本文作者:郭宇杰,阿里云智能技术专家。在Prometheus集成的50多个云产品中,RocketMQ在可观察性方面实现了非常完善的功能,是一个特别具有代表性的云产品。01RocketMQ如何接入PrometheusRocketMQ诞生于阿里巴巴内部核心电商系统,是业务消息的首选MQ平台。上图为RocketMQ5.0的整体体系,在接入层、核心组件、底层运维等方面都做了很大的改进。具有功能多样、高性能、高可靠性、可观察性、易操作维护等优点。指标、跟踪和日志记录是可观察性的三大支柱。Metrics:RocketMQ为用户提供开箱即用的Dashboard,采用开源领域广泛使用的产品组合Prometheus+Grafana。指标包括每个阶段的消息量、累积量和耗时。该市场结合了RocketMQ团队在消息领域多年的研发和运维经验打磨出的最佳实践模板,并提供持续迭代更新能力。Tracing:RocketMQ首次引入了OpenTelemetrytracing开源标准,按照消息维度重新组织抽象span拓扑。Logging:Logging主要是对一些客户端的日志进行了规范,这样可以更简单方便的利用日志来定位问题。RocketMQ所有的可观察性数据都围绕一条消息在生产、服务端处理、消费等阶段展开。从消息的生命周期图中可以看出一条消息从Producer发送到MQ服务器所花费的时间;如果是定时消息,可以根据Ready时间知道定时时间;从Consumer的角度,可以知道消息从开始抓取到到达客户端的网络耗时;等待处理资源从到达客户端到开始消息处理的时间消耗;从消息处理开始到最终返回ACK的处理时间消耗。消息在生命周期的任何阶段都可以被明确定义和观察,这是RocketMQ可观察性的核心概念。RocketMQ团队贡献的RocketMQexporter已经被Prometheus官方开源Exporter生态收录,提供丰富的Broker、Producer、Consumer各个阶段的监控指标。Exporter的基本逻辑是通过内部启动多个定时任务,周期性的从MQ集群中拉取数据,然后将数据归一化,通过端点暴露给Prometheus。MQAdminExt类封装了MQAdmin公开的各种接口逻辑。从结构上看,RocketMQ的Exporter是第三方视角的观察者,所有指标都来自MQ集群内部。Prometheus在应用中暴露监控指标的过程需要注意以下两点:①Exporter部署方式的选择分为将Prometheus客户端嵌入到应用程序中的直接观察方式和应用外的独立Exporter方式程序。直接观察模式具有主流语言支持、性能更优、免运维等优点。缺点是代码耦合。Exporter模式具有解耦、开源生态丰富等优点。最大的缺点是需要一个单独的运维Exporter组件。在云原生微服务的应用架构模式下,需要部署多个Exporter,给运维带来很大的负担。部署模式的好坏没有区别。一般建议在对应用代码有控制权的情况下选择直接观察模式,在对应用代码没有控制权的情况下建议选择Exporter模式。②尽量避免索引维度发散导致的高基数问题。因为在Prometheus的索引模型中添加标签非常方便,很多用户在索引中添加多少维度就添加多少,这必然会引入一些不可枚举的维度,比如常见的userid、url、email、ip、Prometheus的时间线总数是根据指标和维度的组合乘积关系计算出来的。因此,高基数问题不仅会带来巨大的存储成本,同时由于瞬时返回的数据过多,也会给查询端带来不小的性能挑战,严重的维度背离使得指标本身失去了统计意义。因此,在使用过程中,应尽量避免指标尺寸的背离。我们在使用PrometheusClient的时候也遇到了高基数的问题,尤其是RocketMQ的指标,提供了account、instance、topic、consumerGroupID等多个维度的组合,使得时间线的整体数量处于非常高的量级。在实践中,我们针对Prometheus原生Client做了两次针对性的优化,以有效控制Exporter高基数带来的内存隐患。在RocketMQ的生产环境中,需要对销售租户进行客户级监控。每个客户的RocketMQ资源都是租户严格隔离的。如果为每个租户部署一套Exporter,将会给产品架构、运维等方面带来极大的挑战。因此,在生产环境中,RocketMQ选择了另一种方式接入Prometheus。RocketMQ5.0的架构有了很大的改进。多语言瘦客户端底层使用gRPC协议向服务端发送数据。同时,MQ服务器也被拆分成两个角色:CBroker(代理)和SBroker,可以分开也可以合并。在架构变化的同时,RocketMQ5.0在客户端和服务端都引入了OpenTelemetry追踪标准埋点规范。全链路Tracing客户端嵌入OpenTelemetryExporter,将Tracing数据批量发送给proxy。作为采集器,proxy本身将client和自己上报的tracing数据进行整合。追踪存储支持自定义采集器、商业托管存储、开源版本存储向自有平台上报。针对消息的生命周期,重新设计了span的拓扑模型。准确多样的Metrics在服务端对接收到的tracing数据进行二次聚合计算,计算出的指标符合OpenMetrics规范。可以无缝集成到Prometheus存储和Grafana的大规模展示中。RocketMQ跨度拓扑模型。拓扑模型对Prod、Recv、Await、Proc、ACK/Nack阶段的埋点处理重新归一化,同时OpenTelemetrytracing模型的attributes部分已经提交给OpenTelemetry规范标准组织和包括。以上改进大大增强了消息轨道的功能。不仅可以根据消息的基本信息查询到相关轨迹,还可以一目了然地看到消息生命周期的各个阶段。点击traceID,还可以看到详细的tracking信息,可以关联查看生产者、消费者以及相关资源,比如机器信息的展示。为什么RocketMQ的指标数据要接入Prometheus?因为Prometheus天生契合云原生架构,Prometheus在开源领域处于metrics的事实标准中。Prometheus为云原生架构而生,与Kubernetes自然融合。具有自动发现、多级采集能力、强大的生态、通用的多模式索引模型、强大的PromQL查询语法等特点。RocketMQ通过以trace数据为metric进行二次计算的方式连接Prometheus。前面提到,RocketMQ5.0引入了OpenTelemetry追踪埋点。我们将客户端和服务端上报的tracing数据统一存储在阿里云日志系统中,并根据tracing数据进行多维度二次聚合,得到符合Prometheus规范的指标。时间序列数据。在ARMS团队内部,使用实时ETL工具将日志数据转化为指标,并由租户存储在Prometheus系统中。RocketMQ控制台深度集成了Grafana的大磁盘和Alarm报警模块。用户只需在RocketMQ实例监控页面开启Prometheus,即可一键获取自己名下的大盘和告警信息。ARMSPrometheus集成了众多的云产品监控指标,针对云产品的多租户需求提供了完整的解决方案。阿里云的云产品不仅需要监控产品本身的指标,还需要监控销售产品的租户的指标。根据租户资源的划分,云产品主要分为租户独享资源模式和租户共享资源模式。租户独占资源模式具有租户单独占用部署资源、隔离性好等特点。标识索引的租户信息只需标注租户索引即可;租户共享资源模式是指部署资源将在租户之间共享,标识索引的租户信息需要产品自行添加租户信息。与开源的Prometheus监控相比,ARMSPrometheus采用了独立的采集存储架构。采集端具备多租户识别和分发能力,存储端内置多租户能力。租户之间的资源完全隔离。ARMSPrometheus会为每个阿里云用户创建一个Prometheus云服务实例,用于存储用户对应的阿里云云产品指标。提供深度定制、开箱即用的仪表板和警报功能。上图是默认集成RocketMQ的Grafana仪表盘示例。大盘提供Overview概览、Topic消息发送、GroupID消息消费等细粒度监控数据支持。与开源实现相比,市场提供了更多更准确的指标数据,并结合了RocketMQ团队在消息领域多年运维经验打磨出的最佳实践模板,并提供了持续迭代更新的能力。02RocketMQObservableBestPractice单纯关注消息系统提供的可观察数据,只能发现部分问题。在真实的微服务系统中,用户需要关注接入层、业务应用、中间组件、容器、底层IaaS的可观察数据,才能准确定位问题。上图是一个非常典型的消息系统上下游的应用结构。上游订单系统发送消息,下游库存系统和营销系统订阅消息,实现上下游解耦。如何在如此复杂的业务系统中发现和解决问题,需要对整个系统的可观察性进行全面的审视。首先,需要收集系统中各个组件的可观察数据,Metric、Trace、Log这三大支柱必不可少。Metric衡量应用状态,通过指标告警快速发现问题;Trace数据可以实现请求层面的全周期跟踪路径,通过排查调用链路可以快速定位问题;日志数据详细记录了系统产生的事件,通过日志分析可以快速排查故障。上图是ARMSKubernetes监控沉淀的诊断体验。通过应用技术栈端到端、自上而下的全栈关联方式,为我们提供横向和纵向诊断和定位可观察问题的实用思路。对于业务相关的组件,要多关注影响用户体验的RED指标,多关注资源层资源饱和度相关的指标。同时,需要注意日志、事件、调用链的横向关联。只有多方位、全视角的可观察性,才能更清晰地排查和定位问题。上图是一个消息堆积场景的例子。首先需要了解消息累积指标含义。Producer发送消息后,消息队列中的处理和Consumer消费的三个阶段分别处于Ready、inFlight、Acked状态。需要关注两个指标。就绪消息量(Readymessage)表示就绪消息的数量。消息量的大小反映了尚未被消费的消息的大小。在消费者异常的情况下,就绪消息的数据量会增加;消息排队时间(Queuetime)表示最早就绪消息的就绪时间与当前时间的时间差,反映了消息未被处理的时间延迟,对于时间敏感的业务非常重要指标。消息堆积的主要原因有两个。是消费端故障或消费能力不足,或上游生产端消息量过大,下游消费能力不足造成的。对于生产端,更需要关注发送消息的健康状况,可以对发送成功率进行告警。发生告警时,需要关注负载、发送时间、消息量等指标,判断消息量是否有突变;对于消费者要注意消费是否及时的消费健康,可以对就绪消息的排队时间进行告警。发生告警时,需要关注消息处理时间、消费成功率、消息量、负载等相关指标,判断消息量、消费处理耗时变化,检查是否存在ERROR日志和痕迹以及其他相关信息。用户可以使用阿里云ARMS产品更方便快捷地处理上述故障处理过程。收到告警信息后,通过查询业务拓扑、异常标签、业务指标变化,一键查看关联的调用链信息。在调用链上,可以获取到业务处理各个阶段的处理时间、是否有异常等相关信息。调用链的每个span节点都可以下钻,实时查询调用栈和耗时比,定位到业务代码层面的问题。如果用户访问的日志按照ARMS规范关联了调用链的traceID,还可以一键查看对应的日志详情,最终定位问题根源。当出现问题时,除了方便快捷的问题定位流程外,还需要针对告警提供较为完备的告警处理和应急响应机制。ARMS报警为用户提供报警配置、报警调度、报警处理的全流程功能,方便客户建立应急处理、事后回顾、机制优化。同时,ARMS智能报警平台支持10+监控数据源整合,多路数据推送。基于钉钉的CHARTOPS让告警协同化、可追溯、可统计,可提供异常检测、智能降噪等算法能力,有效减少无效告警,并可根据告警中的应用上下文获取告警根因分析.阿里云ARMS监控自上而下涵盖用户终端、应用、云服务/三方组件、容器、基础设施全方位、立体化、统一监控和统一告警能力。最佳实践平台。
