前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《Prometheus监控实战》第13章 监控Tornado

《Prometheus监控实战》第13章 监控Tornado

作者头像
yeedomliu
发布2019-12-20 16:57:02
2K0
发布2019-12-20 16:57:02
举报
文章被收录于专栏:yeedomliuyeedomliu

第13章 监控Tornado

  • 我们将在Kubernetes集群上部署一个名为Tornado的应用程序并对其进行监控。Tornado是一个简单的REST-ful HTTP API,用Clojure语言编写的,可在JVM上运行,具有 Redis数据存储和Mysql
  • 监控如下内容
  1. Mysql
  2. Redis
  3. Tornado API应用程序

13.1 边车模式

  • 边车为应用程序提供支持功能——例如,基础设施边车可能会收集日志或进行监控。边车还与父应用程序共享相同的生命周期,与父应用程序一起创建和删除

提示:边车有时也被称为sidekicks


13.2 Mysql

  • 使用Prometheus监控Mysql是通过exporter完成的:Mysqld exporter。exporter使用提供的凭证连接到Mysql服务器并查询服务器状态。使用边车模式在部署到Kubernetes的Docker容器中运行exporter
  • 代码清单:exporter容器
  • 使用带有latest标签的prom/mysqld-exporter镜像,并将容器命名为tornado-db-exp。我们使用DATA_SOURCE_NAME环境变量指定了数据库连接的详细信息,此连接使用DSN格式配置Mysql服务器的连接和凭据的详细信息
  • 代码清单:连接到Mysql容器
代码语言:javascript
复制
kubectl exec -ti <pod> -- /usr/bin/mysql -p
  • 代码清单:创建Mysql用户
  • 代码清单:额外的Mysql exporter收集器
  • 从Mysql的performance_schema数据库中收集数据,跟踪特定查询和操作的性能
  • 代码清单:tornado-db服务
  • 使用了两个注解:prometheus.io/scrape告诉Prometheus抓取这个服务:prometheus.io/port告诉要抓取的端口。我们指定这一点是希望Prometheus在端口9104上访问Mysql Exporter,而不是直接访问Mysql服务器
  • 代码清单:Kubernetes端点作业的重新标记
代码语言:javascript
复制
relabel_configs:
  - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
    action: keep
    regex: true
  - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
    action: replace
    target_label: __address__
    regex: ([^:]+)(?::\d+)?;(\d+)
    replacement: $1:$2
……

prometheus.io/port注解将被注入__address__标签中,以便被作业抓取。接下来的服务发现将开始收集这些Mysql指标

Mysql监控配置
  • 我们将创建一个可能的规则样本,大致与Google的四个黄金指标一致,让你了解如何使用Mysql指标。将专注于
  1. 延迟
  2. 流量
  3. 错误
  4. 饱和度

警告:测量Mysql性能很难,尤其是在跟踪延迟等信号时,情况会因应用程序和服务器配置的不同而有很大差异。这些规则为你提供了起点,而不是明确的答案

  • 代码清单:Mysql慢查询警报
代码语言:javascript
复制
- alert: MySQLHighSlowQuerysHigh
  expr: rate(mysql_global_status_slow_queries[2m]) > 5
  labels:
    severity: warning
  annotations:
    summary: MySQL Slow query rate is exceeded on {{ $labels.instance }} for {{ $labels.kubernetes_name }}
  • 如果两分钟内慢查询超过5个,则会生成一个警报
  • 代码清单:Mysql请求速率记录mysql_rules.yml
代码语言:javascript
复制
groups:
  - name: mysql_rules
    rules:
      - record: mysql:write_requests:rate2m
        expr: sum(rate(mysql_global_status_commands_total{command=~"insert|update|delete"}[2m])) without (command)
      - record: mysql:select_requests:rate2m
        expr: sum(rate(mysql_global_status_commands_total{command="select"}[2m]))
      - record: mysql:total_requests:rate2m
        expr: rate(mysql_global_status_commands_total[2m])
  • 我们使用mysql_global_status_commands_total指标并获取特定命令的所有写请求:insert、update和delete。然后,为这些请求计算两分钟的速率。我们对使用select命令的读取请求和总请求执行相同的操作。然后使用topk聚合运算符来获取最近五分钟内根据模式和速率分组的最常用语句,这有助于我们理解服务器正在做什么
  • 代码清单:连接和中止的连接
代码语言:javascript
复制
- alert: MySQLAbortedConnectionsHigh
  expr: rate(mysql_global_status_aborted_connects[2m]) > 5
  labels:
    severity: warning
  annotations:
    summary: MySQL Aborted connection rate is exceeded on {{ $labels.instance }} for {{ $labels.kubernetes_name }}
  • 我们将警告中止连接的速率是否超过阀值,并创建一个记录规则以跟踪整体连接速率
  • 最后,我们想知道Mysql服务何时不可用。这些警报使用服务状态和特定于exporter的up指标的组合:mysql_up。mysql_up指标在Mysql服务器上执行SELECT 1,如果查询成功,则将其设置为1。第一个警报检查mysql_up指标的值 是否为0,0表示查询失败。第二个警报在服务消失且指标过期时检查此指标的存在
  • 代码清单:Mysql警报
代码语言:javascript
复制
- alert: TornadoDBServerDown
  expr: mysql_up{kubernetes_name="tornado-db"} == 0
  for: 10m
  labels:
    severity: critical
  annotations:
    summary: MySQL Server {{ $labels.instance }} is down!

13.3 Redis

  • 像Mysql一样,Promethseus也有对应Redis的exporter。Redis Exporter将从INFO命令导出大部分条目,其中包含服务器、客户端、内存和CPU使用情况的详细信息。在每个数据库中,还有用于键总数、过期键和键的平均TTL的指标,你可以导出这些键的值
  • 代码清单:Redis服务和边车
代码语言:javascript
复制
apiVersion: apps/v1beta2
kind: Deployment
  - name: redis-exporter
    image: oliver006/redis_exporter:latest
    env:
      - name: REDIS_ADDR
        value: redis//tornado-redis:6379
      - name: REDIS_PASSWORD
        value: tornadoapi
    ports:
      - containerPort: 9121
  • 我们正在运行一个名为redis-exporter的容器,该容器通过Docker镜像构建。指定了两个环境变量和端口
  • 代码清单:通过Kubernetes暴露Redis服务端口
  • 可以看到我们暴露了端口9121,并指定了两个注解:一个用于告诉Prometheus服务端点作业要抓取这个服务,另一个用于指示要抓取的端口。下一次Prometheus进行服务发现时,它将检测更新后的服务并开始收集redis指标
Redis监控配置
  • 代码清单:Redis警报
代码语言:javascript
复制
- alert: TornadoRedisCacheMissesHigh
  expr: redis_keyspace_hits_total / (redis_keyspace_hits_total + redis_keyspace_misses_total) > 0.8
  for: 10m
  labels:
    severity: warning
  annotations:
    summary: Redis Server {{ $labels.instance }} Cache Misses are high.
  • 我们想知道Redis服务何时不可用。这些警报使用服务状态和特定于exporter的up指标的组合:redis_up。如果Redis服务器的抓取成功,则redis_up指标设置为1.第一个警报检查redis_up指标的值是否为0,0表示查询失败。第二个警报在服务消失且指标过期时检查此指标的存在
  • 代码清单:Redis可用性警报
代码语言:javascript
复制
- alert: TornadoRedisServerDown
  expr: redis_up{kubernetes_name="tornado-redis"} == 0
  for: 10m
  labels:
    severity: critical
  annotations:
    summary: Redis Server {{ $labels.instance }} is down!

13.4 Tornado

  • Tornado API是一个Clojure应用程序,它使用Ring并在JVM上运行。应用程序提供了一个API端点,可以购买和销售商品(https://github.com/ring-clojure/ring)

13.4.1 添加Clojure包装器

  • 为了检测应用程序,我们使用了iapetos Clojure包装器(https://github.com/clj-commons/iapetos)。要启用iapetos包装器,需要将它添加到project.clj文件项目的依赖项中
  • 代码清单:project.clj
代码语言:javascript
复制
(defproject tornado-api "0.1.0-SNAPSHOT"
      :description "Example Clojure REST service for AoM"
      :url "http://artofmonitoring.com"
      :dependencies [[org.clojure/clojure "1.8.0"]
                     [compojure "1.1.1"]
                     [ring/ring-json "0.1.2"]
                     [ring/ring-jetty-adapter "1.3.1"]
                     [ring-logger-timbre "0.7.5"]
                     [com.taoensso/timbre "4.2.1"]
                     [c3p0/c3p0 "0.9.1.2"]
                     [org.clojure/java.jdbc "0.4.2"]
                     [mysql/mysql-connector-java "5.1.38"]
                     [com.taoensso/carmine "2.12.2"]
                     [cheshire "4.0.3"]
                     [clj-statsd "0.3.11"]]
      :plugins [[lein-ring "0.7.3"]]
      :main tornado-api.handler
      :ring {:handler tornado-api.handler/app}
      :profiles {
                 :dev {:dependencies [[ring-mock "0.1.3"]]}
                 :uberjar {:aot :all}})

13.4.2 添加注册表

  • 我们需要定义一个注册表来保存所有指标
  • 代码清单:定义注册表
  • 我们创建了一个名为registry的注册表,并且已经初始化了Ring和JVM指标,这些指标将被自动收集或导出。然后我们定义了五个特定的指标,包括四个计数型指标和一个测量型指标
  • 代码清单:添加标签
  • 我们为item-bought计数器添加了description标签

13.4.3 添加指标

  • 我们现在可以在应用程序上为每个API方法添加函数调用以递增计数器
  • 代码清单:添加指标调用
代码语言:javascript
复制
    (defn buy-item [item]
      (let [id (uuid)]
        (sql/db-do-commands db-config
          (let [item (assoc item "id" id)]
            (sql/insert! db-config :items item)
            (statsd/gauge (str statsd-prefix "item.bought.total") (item "price"))))
            (wcar* (car/ping)
              (car/set id (item "title")))
        (get-item id)))
  • 我们调用inc函数,以便在购买商品时增加item-bought计数器
  • 我们还添加了一个名为tornado_up的测量型指标,它将作为应用程序的up指标。当应用程序启动时,它会自动将值 设置为1
  • 代码清单:测量型指标tornado_up
代码语言:javascript
复制
(prometheus/set (registry :tornado/up) 1)

13.4.4 导出指标

  • 我们希望启用/metrics页面本身,在示例中是使用内置的Ring支持
  • 代码清单:开始导出
代码语言:javascript
复制
(def app
      (-> (handler/api app-routes)
        (middleware/wrap-json-body)
        (middleware/wrap-json-response)
        (ring/wrap-metrics registry {:path "/metrics")))
  • 代码清单:Tornado指标

13.4.5 Tornado监控配置

  • 使用一个Ring HTTP指标创建的延迟记录规则
  • 代码清单:Ring延时规则
代码语言:javascript
复制
- record: tornado:request_latency_seconds:avg
  expr: http_request_latency_seconds_sum{status="200"} / http_request_latency_seconds_count{status="200"}
  • 我们创建了一个新指标tornado:request_latency_seconds:avg,表示响应为200 HTTP代码的请求的平均请求延迟(秒)
  • 还可以利用一个与Ring相关的历史记录来触发高延迟警报
  • 代码清单:Ring高延时警报
代码语言:javascript
复制
- alert: TornadoRequestLatencyHigh
  expr: histogram_quantile(0.9, rate(http_request_latency_seconds_bucket{kubernetes_name="tornado-api"}[5m])) > 0.05
  for: 10m
  labels:
    severity: warning
  annotations:
    summary: API Server {{ $labels.instance }} latency is over 0.05.
  • 这里,我们使用histogram_quantile函数(https://prometheus.io/docs/prometheus/latest/querying/functions/#histogram_quantile)在5分钟内生成请求延迟的第90百分位数。如果持续10分钟超过0.05,那么警报将被触发
  • 还可以利用创建的up风格指标tornado_up来监控API服务的可用性
  • 代码清单:监控Tornado API可用性
代码语言:javascript
复制
- alert: TornadoAPIServerDown
  expr: tornado_up{kubernetes_name="tornado-api"} != 1
  for: 10m
  labels:
    severity: critical
  annotations:
    summary: API Server {{ $labels.instance }} is down!
- alert: TornadoAPIServerGone
  expr:  absent(tornado_up{kubernetes_name="tornado-api"})
  for: 10m
  labels:
    severity: critical
  annotations:
    summary: No Tornado API servers are reporting!
    description: Werner Heisenberg says - there is no uncertainty about the Tornado API server being gone.
  • 在这里,我们将检测tornado_up指标的值是否大于0,或者它是否从我们的指标中消失
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 yeedomliu 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第13章 监控Tornado
    • 13.1 边车模式
      • 13.2 Mysql
        • 13.3 Redis
          • 13.4 Tornado
            • 13.4.1 添加Clojure包装器
            • 13.4.2 添加注册表
            • 13.4.3 添加指标
            • 13.4.4 导出指标
            • 13.4.5 Tornado监控配置
        相关产品与服务
        云数据库 SQL Server
        腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档