文章目录
  1. 1. 一、需求概括
  2. 2. 二、业务架构
    1. 2.1. 2.1 数据源
    2. 2.2. 2.2 数据采集
    3. 2.3. 2.3 数据转换
    4. 2.4. 2.4 数据存储
    5. 2.5. 2.5 数据分析
    6. 2.6. 2.6 数据展现
    7. 2.7. 2.7 预警
    8. 2.8. 2.8 CMDB
  3. 3. 三、系统架构
    1. 3.1. 3.1 技术组件
    2. 3.2. 3.2 架构说明
      1. 3.2.1. 3.2.1 日志采集优化
      2. 3.2.2. 3.2.2 数据采集
      3. 3.2.3. 3.2.3 数据转换
      4. 3.2.4. 3.2.4 数据存储
      5. 3.2.5. 3.2.5 数据分析
      6. 3.2.6. 3.2.6 数据展现
      7. 3.2.7. 3.2.7 预警
  4. 4. 四、具体实现
    1. 4.1. 4.1 标签体系
    2. 4.2. 4.2 数据展现
      1. 4.2.1. 4.2.1 虚拟机相关指标
      2. 4.2.2. 4.2.2 JVM相关指标
      3. 4.2.3. 4.2.3 RabbitMQ相关指标
      4. 4.2.4. 4.2.4 Gateway相关指标
    3. 4.3. 4.3. 告警分级体系
    4. 4.4. 4.4 自研的告警适配模块(Alert Adapter)
      1. 4.4.1. 4.4.1 告警存储
      2. 4.4.2. 4.4.2 告警展示
        1. 4.4.2.1. 告警信息列表
        2. 4.4.2.2. 告警详情
      3. 4.4.3. 4.4.3 告警路由
      4. 4.4.4. 4.4.4 告警分发
      5. 4.4.5. 4.4.5 告警内容格式化
  5. 5. 五、应用案例
    1. 5.1. 5.1 日志数据实时分析
  6. 6. 六、迭代规划
    1. 6.1. 6.1 DevOps自动化提升
      1. 6.1.1. 6.1.1 CMDB 关联
      2. 6.1.2. 6.1.2 自动服务发现
    2. 6.2. 6.2 可伸缩性提升
    3. 6.3. 6.3 健壮性提升
    4. 6.4. 6.4 存储优化
    5. 6.5. 6.5 消息服务替换
    6. 6.6. 6.6 其他

If You Can’t Measure It, You Can’t Manage It
—— Peter Drucker

如何利用工具对系统建立全面的度量和监控体系,帮助我们有效的管理我们的系统,以下是基础架构部中间件组基于Prometheus构建监控系统的一些实践经验与思考。

Prometheus系列文章分为三部分呈现,这是其中的第三篇

第一章:方案选型和部署应用

第二章:Prometheus使用详解以及项目接入

第三章:落地方案与实践案例

这一篇分享,将介绍基础架构部中间件组与运维组的小伙伴,如何结合公司目前的基础设施和技术架构,利用Prometheus设计并搭建指标监控平台的实践心得。

一、需求概括

在第一篇分享中,我们讲到,监控系统从业务层面,基本可以分为以下3大类:

  • 日志监控(已部署:Filebeat 或 Logstash + Kafka + LogStash + ElasticSearch + Kibana)
  • 指标监控
  • 调用链监控(已部署SkyWalking

那么在利用Prometheus来构建一个与我们的业务现状和技术栈相匹配的指标监控平台时,应该考虑满足哪些需求和特性呢?

总的来说,一个好的指标监控平台,应当具备如下的一些能力:

  1. 高度抽象模型,扩展监控指标:

    业务的高复杂度决定了数据源、指标的多样化,这要求我们必须要进行监控模型的高度抽象,并且针对于指标可以动态扩展,这样才能保证监控平台的健壮性和可扩展性。

  2. 多种数据源采集能力:

    数据源的不同决定了采集的方式也是有区别的,系统应该能适配广泛的数据源。

  3. 强大的数据处理能力:

    海量的数据必须要有足够强大的数据加工、分析处理能力才能得到直观的结果。

  4. 多种数据视图:

    监控数据不能只是简单的表格展现,还需要支持各种饼图、柱状图、折线图、仪表盘等丰富的可视化图表,监控的数据需要结合实际情况选择最佳的可视化展现方式。

  5. 多种报警机制:

    要能支持短信、邮件、企业微信等等不同的信息传播方式,结合不同场景灵活选择不同的报警机制。

基于这几方面的考虑,我们开始对监控平台的架构进行规划和设计。

二、业务架构

首先从业务层面对整个系统的各种业务、流程与功能进行抽象,其业务架构如下图所示:

业务架构

各业务模块的主要职责和功能包括:

2.1 数据源

需要接入监控平台的监控源多种多样,从业务层次上来划分的话,大致可以分为4层:
| 序号 | 业务层次 | 监控源 | 说明 | 相关指标 |
|—|—|—|—|—|
| 1 | 业务层 | 系统内部业务流程 | | 业务相关的自定义指标,如大额流水、流水区域、流水明细、请求笔数、响应时间、响应笔数等 |
| 2 | 应用层 | Java、PHP、Golang等各类应用程序 | 主要是JVM、PHP-FPM等层面的指标 | CPU使用率、内存使用率、IOPS、GC次数等 |
| 3 | 中间件层 | 各类中间件软件RabbitMQ、Kong、MySQL、ElasticSearch、Spark、HDFS等 | | 可用性、异常、吞吐量、响应时间、当前等待笔数、资源占用率、请求量、日志大小、性能、队列深度、线程数、服务调用次数、访问量、服务可用性等 |
| 4 | 基础设施层 | 物理服务器、虚拟机、云PaaS服务、K8S容器平台、网络设备、存储设备等 | CPU负载、内存负载、磁盘负载、网络IO、磁盘IO、tcp连接数、进程数等 |

2.2 数据采集

监控数据源的多样性,决定了数据采集的任务自然轻松不了,从协议上就有Http、SNMP、MQTT等多种。

从采集方式来说通常可以分为:

  • 被动接收数据源Push
  • Pull主动抓取
  • 客户端Agent主动收集

2.3 数据转换

采集到的各种数据,在进入系统后,还需要进行缓存、格式转换、去重、校验等多道处理流程,然后才会进入后续的存储、分析、预警等业务环节;

2.4 数据存储

采集到的数据一般都需要存储到文件系统(如HDFS)、搜索引擎(如ElasticSearch)、时间序列数据库(如influxDB)、消息队列(如kafka,做消息临时存储或者缓冲)、关系数据库(如mysql)、等

2.5 数据分析

针对采集到的数据,根据监控的需要,再进行进一步的计算分析。

按技术实现方式,一般分为以下几类:

  • 流式计算:如Spark Streaming、Flink、Storm等计算平台;
  • 批处理。技术包括Map/Reduce计算等
  • 全文检索
  • 指标计算

重点是根据不同的场景需求选择不同的分析方式。

2.6 数据展现

将处理的结果进行展现,在多屏时代,跨设备的支持、丰富的可视化图表与即时交互是必不可少的。

2.7 预警

如果在数据分析、处理过程中发现了问题,则需要进行异常的分析、风险的预估以及事件的触发或告警。

2.8 CMDB

CMDB 在监控平台中是很重要的一环,监控源虽然种类繁多,但是他们大都有着内在的关系,如应用运行在运行环境中,应用的正常运行又依赖网络和存储设备,一个应用也会依赖于其他的应用(业务依赖),一旦其中任何一个环节出了问题,都会导致应用的不可用。

CMDB除了存储软硬件资产信息外,还要存储资产间的关联关系,一个资产发生了故障,要能根据这个关系迅速得知哪些其他的资产会被影响,然后逐一解决问题。

三、系统架构

基于选定的技术组件,整个监控平台的系统架构,如下图所示:

系统架构

3.1 技术组件

根据业务架构,在对主流的相关技术进行调研,并结合公司目前已有的技术积累,最后的技术选型如下:

  1. 日志监控优化:

    采集模块调整为Fluent-bit

  2. 指标数据采集 + 数据转换:

    1. 各种Exporter
    2. PushGateway
  3. 数据存储

    1. Prometheus Server
    2. ElasticSearch
  4. 数据分析

    Flink流式处理平台

  5. 预警处理

    1. AlertManager
    2. 自研告警适配处理模块(Alert Adapter)
  6. 数据可视化

    1. Grafana
    2. Kibana
    3. 自研告警管理模块(Alert Admin)

3.2 架构说明

3.2.1 日志采集优化

原来的日志分析方案采用Filebeat 或 LogStash作为采集模块,存在以下缺点:

  1. 内存占用高:LogStash内存占用可达上百MB,即使轻量化的Filebeat内存占用也需要几十MB,后期如果要演进到Kubernetes等云原生基础架构,资源的浪费非常高;
  2. CPU占用高:Filebeat不具备日志内容解析和格式化能力,所有日志解析的计算压力都集中到后端LogStash或ElasticSearch上;

调整为采用Fluent-bit作为采集模块,其具备以下优点:

  1. 内存占用少:内存消耗不到10MB;
  2. 日志解析能力:本地解析日志,直接输出JSON,缓解后端计算压力;
  3. 日志缓存能力:可缓存部分日志信息;
  4. CNCF原生项目,目前已毕业;

3.2.2 数据采集

目前Prometheus官方和社区,已开发了大量的数据采集Agent,只要针对监控的数据源,选择合适的Agent即可实现相关数据的收集,同时应用内部也可以通过第三方库或自己实现相应的接口,实现数据的直接采集。

根据数据源的分类,目前可用的Agent包括:

序号 业务层次 数据源 采集方式 Agent/库名称
业务层 业务指标 自定义 自定义
应用层 Golang应用 程序库 go-client
PHP应用 Agent php-fpm-exporter
Java应用 Agent jmx-exporter
第三方程序库 SpringBoot Auactor
中间件 RabbitMQ Agent rabbitmq-exporter
ElasticSearch Agent elasticsearch-exporter
Kafka Agent kafka-exporter
Kong 接口 Prometheus插件
基础设施 虚拟机 Agent node-exporter

3.2.3 数据转换

各Exporter和PushGateway对采集到的指标数据进行缓存、去重、过滤,Prometheus Server定期从各Exporter和PushGateway等组件,Pull指标数据;

3.2.4 数据存储

指标数据直接存储于Prometheus Server自带的时间序列数据库中。

同时通过Prometheus Server的远程存储接口,也可写入ElasticSearch存储,长期保存和作为数据备份。

3.2.5 数据分析

利用Flink作为实时数据分析平台,对日志和各种指标数据进行实时的分析与处理,并将结果转化为Prometheus格式的指标,输出到Prometheus的PushGateway,或直接输出到告警管理模块(AlertManager)

3.2.6 数据展现

采用Grafana作为数据展现平台,并在Grafana上配置与各种数据源匹配的Dashboard,对指标数据进行展示。

3.2.7 预警

在Prometheus Server定义各种告警规则(Alert Rules),触发告警后上报到AlertManager模块,AlertManager对告警进行过滤、去重、抑制等处理后,转发到自研的AlertAdapter模块,然后根据各种告警分发规则,将告警信息,发送到对应的接收人。

四、具体实现

Prometheus作为一款优秀的指标监控系统,在提供强大的基础功能同时,在可扩展性方面也提供了很高的自由度。如何以原生Prometheus为骨架,为其添加肌肉,使其更加“强壮”,让Prometheus更优雅的与我们的业务进行融合。

在设计整个监控体系时,基于开放封闭原则,我们尽量保证在不修改Prometheus代码的前提下,通过其开放的各种接口进行功能的扩充。

基于 Prometheus 的扩展包括:

4.1 标签体系

Prometheus的一大优点就是支持标签(Label),相同的Metric指标名称可以通过标签对其进行区分,并支持对数据添加自定义标签的功能。

因此我们制定了一套使用标签对Metric指标数据进行分类的规则,包括了数据源的:运行环境、所属业务团队、项目、应用名称等。

数据采集到Prometheus Server模块后根据规则,自动为每条Metric加上对应的标签,然后再进行存储。

例如以下的一条原始metric数据:

1
jvm_memory_bytes_used{app="jobscenter-jmx",area="heap",instance="10.105.12.10:10254",job="jvm"}

添加上标签后变为:

1
jvm_memory_bytes_used{app="jobscenter-jmx",area="heap",env="prod",instance="10.105.12.10:10254",job="jvm",project="jobscenter",sla="s1",team="middleware",tier="jobs_center"}

后续进行数据分析和查询时,只需要指定team、project等标签值,就能快速找到匹配的数据。

4.2 数据展现

为了更好的展现各种指标数据,我们在Grafana上定义了多个展示相关指标数据的公共Dashboard,通过这些Dashboard可以迅速直观的了解在某一时间OS、JVM、RabbitMQ等的真实状态。同时也可以根据自己的需要,在Grafana上建立自定义的各种Dashboard。

例如:

4.2.1 虚拟机相关指标

虚拟机指标

4.2.2 JVM相关指标

JVM

4.2.3 RabbitMQ相关指标

RabbitMQ

4.2.4 Gateway相关指标

Gateway

4.3. 告警分级体系

建立标准的告警分级体系,将告警分为Info、Warning、Error、Fatal等不同等级。

建立告警规则时,可以根据阈值的差别,给不同的告警,指定相应的告警级别,便于后续对告警信息做出针对性的处理

4.4 自研的告警适配模块(Alert Adapter)

为适应公司的业务场景,自研了告警适配模块(Alert Adapter),接入到AlertManager的WebHook接口,对告警信息进行定制化处理:

4.4.1 告警存储

Prometheus原生的告警管理模块(AlertManager),并不提供告警存储功能。

AlertAdapter模块可将所有告警信息存储到MySQL,便于分析定位问题,或对历史告警进行回溯;

4.4.2 告警展示

原始的告警信息是JSON格式,内容不易阅读,各业务用户可在AlertAdapter的UI界面上,以直观的方式查看告警信息。

界面如下所示:

告警信息列表

告警详情

4.4.3 告警路由

各业务线可通过UI界面自定义本业务下各项目或系统,各级告警的告警通知方式,如短信、语音、邮件等。

例如下图所示:

4.4.4 告警分发

根据各业务线配置的告警路由规则,在收到告警后,通过基础服务MsgSvr,将告警及时通知到对应人员。

4.4.5 告警内容格式化

短信、语音、企业微信、电子邮件等等,这些不同的告警分发途径,有着不同的信息承载与信息表达限制,为了更高效的传播告警信息,针对不同的发送方式,我们对告警内容做了针对性的格式化,例如:

  1. 短信

    一条传统短信只支持160个西文字符或70个汉字,即使利用长短信将多条短信内容合并处理,能传达的信息量也非常有限。

    经格式化处理后,通过短信展示的告警内容如下:

  2. 企业微信

  3. 邮件

  1. 语音

五、应用案例

5.1 日志数据实时分析

这里以中间件组利用Fluent-bit + Flink + Prometheus对网关Gateway的Error日志进行实时分析,实现快速感知后端业务服务异常的案例,说明整个告警平台的业务处理流程。

整个分析告警的实现流程如下图所示:

  1. 网关Gateway访问某后端业务服务时出现异常,记录Error日志信息到文件。日志内容如下:

    1
    2
    3
    2019/05/09 02:41:35 [error] 12493#0: *2883354568 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 10.154.48.174, server: kong, request: "POST /qbus/topic/messages/publish HTTP/1.1", upstream: "http://10.105.10.135:8080/qbus-server/topic/messages/publish", host: "gateway.api.kuainiujinke.com"
    2019/05/09 02:41:35 [error] 12493#0: *2883355044 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 10.154.8.136, server: kong, request: "POST /qbus/topic/messages/publish HTTP/1.1", upstream: "http://10.105.10.135:8080/qbus-server/topic/messages/publish", host: "gateway.api.kuainiujinke.com"
    2019/05/09 02:43:05 [error] 12494#0: *2883425488 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 10.154.205.26, server: kong, request: "POST /qbus/topic/messages/publish HTTP/1.1", upstream: "http://10.105.10.135:8080/qbus-server/topic/messages/publish", host: "gateway.api.kuainiujinke.com"
  2. 日志采集模块Fluent-Bit采集并解析Error日志文件;

  1. 日志采集模块Fluent-Bit将日志信息提交到Kafka;

  2. 实时分析模块从Kafka获取Error日志信息,同时LogStash也从Kafka获取Error日志信息,并存储到ElasticSearch;

  3. 实时分析模块对Error日志进行分析,并输出指标到PushGateway;

  4. Prometheus Server从PushGateway采集指标数据并存储

从Prometheus Server通过PromQL可以查询到类似如下指标数据:

1
gateway_internal_error_total{app="pushgateway-gateway-internal",env="prod",exported_job="GatewayInterErrorMonitor",gateway="gateway-qbus1",instance="10.105.198.255:9091",job="pushgateway",message="用户[admin]的API[config-meta-prod]发生异常:connect() failed (110: Connection timed out) while connecting to upstream,upstream: http://10.105.55.63:8080/eureka/apps/APOLLO-CONFIGSERVICE/10.105.13.1:apollo-configservice:8080?status=UP&lastDirtyTimestamp=1559109082100, gateway: gateway-inter2",project="gateway-target",service="qbus",sla="s1",target="10.105.209.226:8080",team="middleware",tier="gateway-internal",uri="--qbus-server--queue--messages--pull",username="admin"}	4
  1. 指标阈值触发告警,Prometheus Server输出告警到AlertManager
  1. AlertManager对告警进行过滤、抑制等处理并发送告警到AlertAdapter

  2. AlertAdapter模块将接收到的告警信息进行存储,并根据通知路由规则,将通知信息提交到MsgSvr服务。

  3. MsgSvr通知服务将告警信息下发到指定的接收者。

从业务异常产生到业务开发人员或运维人员接收到告警通知,在系统中流经多个模块与节点,只需短短几十秒钟时间就能完成(具体延时取决于数据采集的频率,以及分析模型的设计)。

六、迭代规划

目前整个监控平台已实现了最基本的功能,具备了初步的监控能力。在后续的迭代演进中,将考虑逐渐增加以下的一些功能和特性:

6.1 DevOps自动化提升

6.1.1 CMDB 关联

目前监控源信息采用手工配置的方式,未与CMDB建立关联,两边信息无法保持一致或同步。一旦CMDB中信息有变更,必须手工修改Prometheus中相关配置,效率低也容易出错。

后续将考虑与运维组一起将CMDB中基础设施信息建立自动化关联机制。提高DevOps自动化水平。

6.1.2 自动服务发现

目前所有的监控源接入均采用的是配置文件手工配置,并重启服务生效的方式。后续将考虑利用etcdConsul等系统实现服务自动发现,配置变更的热更新。

6.2 可伸缩性提升

目前接入的监控源规模还很小,后续各业务线大规模接入后,为保证系统的整体性能,将根据监控源层次或业务差异,对Prometheus Server模块进行Sharding,并利用Federation等机制,实现集群化部署。

6.3 健壮性提升

在当前的实践中已发现了Prometheus系统的一些性能问题。一些时间跨度较大或比较复杂的Metric查询操作,可能会导致PrometheusCPU、内存、磁盘IO等非常高。为保障系统的健壮性,后续将利用Prometheus Federation等特性实现读写分离,将指标采集、数据分析、指标查询等不同操作进行隔离,提高系统整体的健壮性。

6.4 存储优化

数据存储在Prometheus Server 本地文件中,存在单点风险,考虑将指标数据存储到InfluxDB、ElasticSearch等其他存储系统。

6.5 消息服务替换

作为控制平面(Control Plane)的基础设施,原则上监控平台不应依赖业务平面(Business Plane)的服务。但目前为实现告警信息的发送,告警适配模块(Alert Adapter),反向依赖了基础服务层的MsgSvr消息推送服务。后续将考虑剥离对MsgSrv服务的依赖,提高系统的可靠性。

6.6 其他

平台使用过程中暴露的其他问题。

文章目录
  1. 1. 一、需求概括
  2. 2. 二、业务架构
    1. 2.1. 2.1 数据源
    2. 2.2. 2.2 数据采集
    3. 2.3. 2.3 数据转换
    4. 2.4. 2.4 数据存储
    5. 2.5. 2.5 数据分析
    6. 2.6. 2.6 数据展现
    7. 2.7. 2.7 预警
    8. 2.8. 2.8 CMDB
  3. 3. 三、系统架构
    1. 3.1. 3.1 技术组件
    2. 3.2. 3.2 架构说明
      1. 3.2.1. 3.2.1 日志采集优化
      2. 3.2.2. 3.2.2 数据采集
      3. 3.2.3. 3.2.3 数据转换
      4. 3.2.4. 3.2.4 数据存储
      5. 3.2.5. 3.2.5 数据分析
      6. 3.2.6. 3.2.6 数据展现
      7. 3.2.7. 3.2.7 预警
  4. 4. 四、具体实现
    1. 4.1. 4.1 标签体系
    2. 4.2. 4.2 数据展现
      1. 4.2.1. 4.2.1 虚拟机相关指标
      2. 4.2.2. 4.2.2 JVM相关指标
      3. 4.2.3. 4.2.3 RabbitMQ相关指标
      4. 4.2.4. 4.2.4 Gateway相关指标
    3. 4.3. 4.3. 告警分级体系
    4. 4.4. 4.4 自研的告警适配模块(Alert Adapter)
      1. 4.4.1. 4.4.1 告警存储
      2. 4.4.2. 4.4.2 告警展示
        1. 4.4.2.1. 告警信息列表
        2. 4.4.2.2. 告警详情
      3. 4.4.3. 4.4.3 告警路由
      4. 4.4.4. 4.4.4 告警分发
      5. 4.4.5. 4.4.5 告警内容格式化
  5. 5. 五、应用案例
    1. 5.1. 5.1 日志数据实时分析
  6. 6. 六、迭代规划
    1. 6.1. 6.1 DevOps自动化提升
      1. 6.1.1. 6.1.1 CMDB 关联
      2. 6.1.2. 6.1.2 自动服务发现
    2. 6.2. 6.2 可伸缩性提升
    3. 6.3. 6.3 健壮性提升
    4. 6.4. 6.4 存储优化
    5. 6.5. 6.5 消息服务替换
    6. 6.6. 6.6 其他