差异:
存储:我们将所有的 prometheus 的数据额外存储一份到 aliyun sls 中,这样不仅可以做到数据 backup,也可以方便 grafana 统一查询 prometheus 数据。
服务发现:由于流利说拥有大量 aliyun ecs 机器,所以我们在 prometheus 原有的服务发现基础上开发了 ecs scrape 代码,以便监控ecs机器。
告警:使用 pagerduty 以及正在开发的 goalert +流利说自研通知中心用于告警通知,并且支持告警调度以及告警升级。
统一管理 Prometheus Config:由于流利说现有多个 prometheus 同时运行,由于每个 prometheus 所要监控的数据不同,所以需要分别配置相关 Recording rules && Alerting rules,但是如果分别管理每个prometheus config 就使得运维成本非常高。所以 infra 团队就将这些配置文件统一放到一个git仓库下,当某个 prometheus config 发生改变时,就会触发 prometheus reload,使变更立刻生效。这样我们只需管理一个配置“仓库”即可。
自动检测 Prometheus Config :由于 infra 团队会定制一些 metrics 用于告警,如果配置不准确会引起 prometheus 状态异常,所以当我们更新 prometheus config 时也会检测变更的 rule 或 metrics 是否正确,主要依靠 prometheus 自带检测工具 promtool 与流利说自研检测工具 prom-threshold 来检测。相关ci文件如下:
stages:
- test
check_rules:
stage: test
image: debian:jessie
script:
- find ./ -type f -name '*.yml' | grep -E 'alerting|recording' | grep -v 'threshold' | xargs ./bin/promtool-linux check rules
tags:
- docker
check_threshold:
stage: test
image: prom-threshold:v0.1.1
script:
- find ./ -type d -name threshold | egrep '.*' || exit 0
- find ./ -type d -name threshold | xargs /prom_threshold -op check -path
tags:
- docker
自定义告警阈值:因为我们会配置一些通用的告警,但是由于业务差异,对一些告警的要求可能不同,所以我们就会给这些业务在通用告警的基础上,通过 metrics 的方式暴露业务专有指标(业务指定的告警阈值),然后通过 recordingRules 的方式修改其告警值,从而提高了告警的灵活性。
ThresholdMetrics:
metric: http_4xx_ratio_threshold
threshold: 0.05
labels:
host: ****.com
path: /oauth/callback
metric: http_latency_95_seconds_threshold
threshold: 20
labels:
host: ****.com
path: /
AlertingRule:
name: http/latency.customized
rules:
alert: SlowHTTP
expr: service:kong_latency:quantile95_rate1m{type="request"} > on (host,path) group_left() (http_latency_95_seconds_threshold * 1000)
流利说拥有各种各样的云资源,如果分别依靠云平台的监控系统,那么就与我们预期的统一监控不符,所以我们通过拉取云平台监控系统 api,将云资源相关指标暴露在 prometheus 中,对这些指标再针对性的配置 Recording rules && Alerting rules,从而使得云资源监控告警可以统一且灵活的配置。
ExportCode:
switch collectType {
case "EsExporter":
es := exporter.EsExporter(newCmsClient())
prometheus.MustRegister(es)
case "HbaseExporter":
hbase := exporter.HbaseExporter(newCmsClient())
prometheus.MustRegister(hbase)
case "KafkaExporter":
kafka := exporter.KafkaExporter(newCmsClient())
prometheus.MustRegister(kafka)
case "KvstroeExporter":
kvstroe := exporter.KvstoreExporter(newDbClient())
prometheus.MustRegister(kvstroe)
case "NatExporter":
nat := exporter.NatExporter(newCmsClient())
prometheus.MustRegister(nat)
case "OssExporter":
oss := exporter.OssExporter(newCmsClient())
prometheus.MustRegister(oss)
case "RdsExporter":
rds := exporter.RdsExporter(newDbClient())
prometheus.MustRegister(rds)
case "SlbExporter":
slb := exporter.SlbExporter(newCmsClient())
prometheus.MustRegister(slb)
}
AlertingRule:
groups:
name: rds.rules
rules:
alert: RdsConnectionOutOfUsage
expr: avg_over_time(cloudmonitor_rds_connection_usage[5m]) + on (instanceid) group_left(app,team,owner,name) avg_over_time(alicloud_rds_tags[1m]) >80
for: 3m
labels:
severity: critical
prometheus: prometheus
k8s_cluster: k8s
source: rds
annotations:
summary: "{{ $labels.app }} {{ $labels.name }} {{ $labels.instanceid }} rds connection_usage out of 80% for 3 minutes"
details: "{{ $labels.app }} {{ $labels.name }} {{ $labels.instanceid }} rds connection_usage is out of 80% for 3 minutes \n Current value: {{ $value }}%"
0 */1 * * * bash /opt/cloudmonitor/cloudmonitor_cronjob.sh /opt/cloudmonitor/cronjob.log 2>&1
监控告警系统:
服务可用性SLA:prometheus 的 Recording rules 功能非常的强大,所以流利说通过此规则延伸出了服务 SLA 监控,主要是通过 kong mertics 计算 HTTP SLA,通过 istio metrics 计算 GRPC SLA。
展望:
作者简介
赵勇超 技术部 cloud-infra 团队 后端工程师