Apache RocketMQ 是一个分布式消息和流数据平台,具有低延迟、高性能、高可靠性、万亿级容量和灵活的可扩展性。简单的来说,它由 Broker 服务器和客户端两部分组成,其中客户端一个是消息发布者客户端 (Producer),它负责向 Broker 服务器发送消息;另外一个是消息的消费者客户端 (Consumer),多个消费者可以组成一个消费组,来订阅和拉取消费 Broker 服务器上存储的消息。正由于它具有高性能、高可靠性和高实时性的特点,与其他协议组件在MQTT 等各种消息场景中的结合也越来越多,应用也越来越广泛。为了全方位的监控RocketMQ,Apache RocketMQ开源社区基于Prometheus开发了RocketMQ Exporter。Prometheus具有易于管理,监控服务的内部运行状态,强大的数据模型,强大的查询语言PromQL,高效的数据处理,可扩展,易于集成,可视化,开放性等优点,基于RocketMQ Exporter可以很快速的构建出一个能够监控RocketMQ的监控平台。本次分享将由Apache RocketMQ Committer陈厚道为大家介绍为什么Prometheus是云原生时代首选的监控方案?Prometheus的强大的查询语言PromQL的典型应用场景有哪些?对于Apache RocketMQ分布式消息队列,需要监控和关注哪些指标等内容。
演讲嘉宾简介:陈厚道,Apache RocketMQ Committer
以下内容根据演讲视频以及PPT整理而成。
观看回放 https://developer.aliyun.com/live/43210 本次分享主要围绕以下五个方面:
一、Prometheus 简介
二、几种主流的消息队列的比较
三、RocketMQ-Exporter的实现
四、RocketMQ-Exporter的监控指示和告警指示
五、RocketMQ-Exporter的使用示例
一、Prometheus 简介
CNCF基金会中有几个重点项目,其中一个便是K8S,启发于Brog系统。Prometheus是CNCF的另一个项目,启发于BrogMon系统,为Brog系统做监控。在2017年,Prometheus 发布了2.0版本,提供了全新的时间序列数据库引擎,大大的提高了数据存储、数据读取、数据查询的效率。同时,Prometheus 2.0还提供了远程存储能力,以及对容器的支持。现在,Prometheus已经成为了云原生时代中主流的监控解决方案。
监控系统基本架构
监控系统大概可以分为几个模块,包括数据的采集、数据的存储、数据的处理、数据的展示以及告警。传统的数据采集方案是通过push的模型,在机器上安装agent,让agent搜集数据,再push到服务端。而Prometheus做的是pull的模型,这也是与传统监控系统最大的区别,它会向各个目标pull监控数据。需要注意的是并不是所有的数据都适合Prometheus,如短生命周期的应用不适合直接pull。因此,Prometheus提供了Pushgataway的组件。Prometheus的架构的优点是不需要安装agent,但是需要解决从哪里拉数据的问题,因此需要具备动态发现目标的能力。在云原生下,有很多服务注册,服务发现的解决方案,如K8S、DNS、Kubernates、Consull等,那么如何才能从服务注册中心拿到想要监控的目标。Prometheus与这些组件结合起来,就可以从K8S、DNS、Kubernates等拿到注册的服务。Prometheus支持从服务中心拿到的服务信息定时的写到文件中,还支持从文件中定时的发现监控目标。Prometheus核心的功能是数据的存储,目前Prometheus可以达到每秒百万级的数据采集和存储,还支持远程的读和写。另外,Prometheus还支持数据的处理,即PromCL,一个类SQL的模块,具备很强的类聚合能力,提供丰富的算子。此外,Prometheus还支持数据的展现,其中还提供了API clients,支持定制化展示效果。最后还提供告警的功能,Alertmanager,提供对告警做分组、去重、升级等等能力。
Prometheus优势
Prometheus易于管理,部署非常方便。如果有插件,也可以进行单独部署。其次,Prometheus易于集成,采用pull模型,其中包含监控指标,Prometheus可以自动的拉取数据,可以方便的监控服务的内部状态。Prometheus具备强大的数据模型和查询语言PromQL。Prometheus数据采集和数据存储的效率是非常高的,还可以将数据写到远程的DB中,还提供联邦集群能力,完成更大规模的业务监控数据的采集。
数据模型
下图展示了监控数据调用链统计的例子,前面部分是metric,后面是统计的时间timestamp,以及当前的值value。在metric部分还可以增加统计的维度tag,如status,method,handler等,从而使得描述更具体。最后数据模型中还包括类型counterType。
Metrics类型
Metrics类型包含几种,首先是Counter,只增不减的计数器,如接口调用量,永远都是累加的。还有Gauge类型,可增可减的仪表盘,如接口调用耗时、内存占用、cpu占用等。Prometheus还提供另外两种类型,Histogram和Summary,针对接口耗时这个指标,监控其最大,最小及平均值,即使平均耗时很平稳,但不能表示没有问题。因此,Prometheus可以统计每个区间内的耗时分布情况,如分别统计耗时在0-50ms,100-200ms的请求量,以及在TP50、TP99、TO99.9时的请求量。
PromQL
Prometheus数据存储能力非常强大,原因是有自己的SQL语言,PromQL,相比SQL更加简洁。依然以统计调用量为例子,如下图,括号中是过滤条件,过滤出状态404、500、501的请求,过滤条件还支持正则表达式。整个语句还支持函数,下图中将Counter指标通过rate函数转换为了Gauge指标,代表每分钟的调用情况。PromQL还支持很多其它函数,如irate、increase、predict_linear、histogram_quantile等。
有了各个维度的指标后,进行转换后,还希望通过接口名做统计,此时可以通过sum by的方式算出按照接口名每分钟的调用量。此外,PromQL还支持其它算子,如min、max、avg、bottomk、topk、quantile等,支持更多聚合的功能。
此外,还可以增加聚合的维度,如下图,除了handler之外,还可以聚合status。如果想知道某个接口1分钟之内出错的调用量的比例,则可以通过相除两个值。但是直接将2个维度和1个维度相除会出现问题,因此需要加ignoring(status)group_left。PromQL还提供其它匹配模式,包括一对一、一对多、多对一等匹配模式。
二、主流消息队列比较
基础项对比
下图对比了一些主流的消息队列,包括Kafka、RocketMQ、RabbitMQ等。在成熟度方面,Kafka在日志领域应用更广泛,RocketMQ和RabbitMQ在业务领域比较成熟。Kafka、RocketMQ是Apache的,RabbitMQ是Mozilla的。但他们在完备性、活跃度等方面都类似。
可用性&可靠性比较
三种消息队列部署方式都是集群,集群的管理Kafka用的是Zookeeper,RocketMQ使用轻量级的Name Server。选主方式,Kafka是竞争选主,RocketMQ在4.5版之后基于Raft协议,可以自动切换。因此在可用性方面,RocketMQ是级强的可以做到强一致,任何节点挂掉后,数据不会丢失。总体来说,可靠性上面三者差不多。
功能对比
由于RocketMQ是专注于业务的,因此在功能性上支持延时消息、事务消息、还支持消息的过滤、消息的查询、消息回溯、消息失败重试等功能。因此RocketMQ适合做业务消息的MQ。
三、RocketMQ-Exporter的实现
Prometheus Exporter
Prometheus是pull的模型,提供了两种集成RocketMQ的方式,一种是直接在业务中上报,但对中间件来说并不合适,如MySQL就不适合直接暴露问题,因此需要Exporter暴露问题,Prometheus再从Exporter拉数据,做采集。在Prometheus官方提供了很多Exporter,如Node Exporter就是读服务器指标的监控Exporter,还有容器的cAdvisor,数据库的MySQL Exporter,Redis Exporter,Kafka Exporter等。基于RockerMQ的Exporter与其它Exporter类似,从终端Server里将监控指标拿到,暴露给Prometheus。
RocketMQ Exporter
RocketMQ 提供API的功能,MQAdminExt,从RocketMQ cluster中拿到监控的数据,再通过MetricsService做数据规范化,如按照Metrics数据模型,再暴露给Prometheus,从Exporter中拉监控指标数据。(RocketMQ Exporter具体实现代码可观看视频回放)
四、RocketMQ-Exporter的监控指示和告警指示
监控的黄金指标
如果做一个监控系统,那应该监控哪些指标?下图给出了一些监控的黄金指标。
延迟
第一类是延迟指标。首先是发送消息延迟。其次是消费延迟,具体分为两种,一种是消费者直接拉取消息的延迟,另一个是消费过程中的业务处理,即消费消息延迟。还需要监控消息堆积量的延迟,如消费消息落后生成消息的时间差值。还有主从延迟,发送消息排队时间,消费消息的排队时间等。通过对这些延迟指标的监控,可以对系统健康问题进行排查。
通讯量
在通讯量方面,可以监控每秒发送消息的数量和字节数,每秒消费消息的数量和字节数,从而监控目前broker的运行状态,再进行排查。
此外,还需要对错误的次数做监控,包括消息失败的次数,未读取到消息的次数,触发broker限流的原因等。
饱和度
MQ实际上是一个存储系统,因此需要对内存、磁盘I/O进行监控。若这些指标发现异常,则表示Broker的性能可能出现了问题。
需要注意的是,其中有一些指标无法通过API拿到,如触发broker限流的原因,但可以通过RocketMQ的日志拿到。
RocketMQ-Exporter监控指标
输出的指标可以从以下维度划分,broker维度包含broker上生产消息tps、消费消息tps。在生产者指标维度,包含topic在broker上的生产tps、topic在broker上的单位时间收到的字节数、topic在broker上的生产进度。消费者维度包含在broker上消费者消费某个topic的tps、在broker上消费者消费某个topic的进度、在broker上消费者消费某个topic单位时间内消费字节数、在broker上消费者消费延迟时间,以及消费堆积量。
在消费者客户端维度,包含消费者1小时内消费失败的总条数、消费者消费失败tps、消费者消费成功tps、消费者消费单条消息平均时间、消费者拉取单条消息平均时间、消费者拉取消息tps等。
在broker运行指标维度,最重要的是broker上拉取队列对头等待时间、broker上查询队列对头等待时间、broker上发送队列对头等待时间。如果等待时间很长,则表示broker性能出现问题,因此需要着重监控。其次是broker上消费者拉取失败的tps、broker上消费者拉取成功的tps、broker上消费者拉取的tps以及已处理consumeQueue文件字节数与已生成commilog文件的字节差值。
RocketMQ-Exporter告警策略
下图介绍了RocketMQ-Exporter的告警策略,其中expr是PromQL语言,将集群做一个聚合,看集群每秒生产的消息数量,超过10就告警,告警持续3分钟,具体的告警描述是description那一行。Prometheus将告警消息发给AlertManager,由AlertManager通过微信、邮件、钉钉等方式进行告警的传达。
RocketMQ-Exporter高级PromQL
下图展示的是稍微复杂的消息增量的告警。上半部分是sum的是消息生产者进度指标以及消息消费者进度指标,生产者指标减去消费者指标就是所需的消息增量指标。在生产者指标中通过topic维度做聚合,而消费者指标中是通过group和topic两个维度,属于一对多的匹配模式,因此需要加上group_right来描述这个关系。下半部分语句关注的是生产的消息量,下图中取了5分钟的平均值,再按照topic做聚合,此时就计算的是每5分钟topic的生产值,再乘以5*60=300秒,再检查值是否大于0。上下两部分相减就表示生产消息量只要大于平均每5分钟的生产的消息总量,则进行告警。可以发现中间加了ignoring(group)group_left,表示前后是多对一的匹配模式。
一般情况下,topic需要动态增加的话,可以将告警规则写到自己的存储中,写到数据库配置中,定时的载入到Prometheus中,通过这样的方式进行热更新,从而尽快的发现问
题。
五、RocketMQ-Exporter的使用示例
感兴趣的同学可以clone RocketMQ-Exporter。具体的步骤:
1)首先启动NameServer和Broker,验证RocketMQ和Spring-Boot客户端,确保RocketMQ服务正确的下载并启动,大家可以参考RocketMQ主站的快速开始进行操作。确保启动NameServer和Broker已经正确启动。
2)其次是编译RocketMQ-Exporter,通过git clone仔细下载git源码编译。
3)正确编译后进行配置和运行,RocketMQ-Exporter目前有下图中的几种运行选项,当然这些选项可以自行在配置文件中进行更改。运行后自动搜集所需要监控的指标。
4)之后再到Prometheus官方下载地址中下载Prometheus安装包,Prometheus默认监听端口号为9090,安装完后再通过浏览器访问http://<服务器IP地址>,就可以验证Prometheus是否已成功安装。
5)Prometheus还可以展示数据,当然目前Prometheus自身的指标展示平台没有现在流行的展示平台Grafana好,为了更好的展示RocketMQ的指标,可以使用Grafana来展示Prometheus获取的指标。同样到官网下载Grafana,为了不与其它进行的使用端口冲突,可以修改conf目录下的default.ini文件的监听端口,将当前Grafana的监听端口改为5555,然后使用 “./bin/grafana-server web”命令启动即可。当然Grafana官网可以下载到已为RocketMQ创建好的配置文件,大家也可以到自行下载。