从 Pulsar Client 的原理到它的监控面板

背景
前段时间业务团队偶尔会碰到一些 Pulsar 使用的问题,比如消息阻塞不消费了、生产者消息发送缓慢等各种问题。
虽然我们有个监控页面可以根据 topic 维度查看他的发送状态,比如速率、流量、消费状态等信息。

但也有几个问题:
- 无法在应用维度查看他所依赖的所有 topic 的各种状态。
- 监控的信息还不够,比如发送/消费延迟、发送/消费失败等数据。
总之就是缺少一个全局的监控视角,通过这些指标可以很方便的分析出当时的运行情况。
基于这个需求经过一段时间的折腾,现在已经上线使用几个月,目前比较稳定,效果图如下:



现在就可以在每个应用的监控面板里看到自己使用了哪些 topic,分别的生产消费情况如何。
核心流程
要实现这些功能就得在应用的 metrics 中加入相关的监控信息,但官方的 Java client 是没有暴露出这些指标的。

但 pulsar-client-go 是自带了这些指标的
由于 SDK 不支持所以只能自己想办法实现了,为此其实有两种实现方案:
- 魔改
Java client,在需要监控的地方手动埋点指标。 - 由于我们使用了
SkyWalking,所以可以编写插件,以agent的方式获取数据、埋点指标。
不过第一种方案有以下一些问题:
- 需要自己维护一个代码分支,还需要定期和官方保持一致,难免会出现代码冲突。
- 需要推动业务方进行依赖升级,线上有着几百个应用,推动起来时间太慢。
第二种方案的好处就不言而喻了:
- 升级无感知,只需要在我们的基础镜像中加上插件即可。
- Java client 的版本也更容易统一。
Client 原理
但其实不管是哪种方案我们都得熟悉 Java Client 的实现原理,才能知道哪些数据是我们需要重点关注的,可以帮助我们更好的定位问题。



本文重点不在于此,具体代码就不仔细分析了。
从上图可以看出,如果我们想要监控消费是否存在阻塞的情况,这几个内部队列是需要重点监控的,一旦他们出现堆积,那就会出现消费阻塞。
其实这些数据都可以通过
org.apache.pulsar.client.api.ProducerStats
org.apache.pulsar.client.api.ConsumerStats
这两个接口获取到生产者和消费者的大部分指标,只是这里还有一个小插曲。
那就是在获取消费者队列大小的时候,获取到的数据一直为空。
最终经过源码排查,原来是我们大量使用的 messageListener 在获取队列大小时有 bug,导致获取到的数据一直都为 0.
相关的 issue 和 PR 可以在这两个链接查看,问题原因和修复过程都有具体描述:
https://github.com/apache/pulsar/issues/20076
https://github.com/apache/pulsar/pull/20245
但这个修复得在新版本才能使用,就导致我们现在的监控页面一直显示为空。
开发 SkyWalking 插件
然后就是开发一个 SkyWalking 的插件了,其实直接使用 SW 开发插件是上手 Java-Agent 比较快的方式。
SW 的 SDK 封装了许多 agent 原生接口,使得开发起来非常容易;当然缺点也有,就是得集成整个 SW 的 agent。
这里我简单介绍下这个插件的运行流程:

- 在创建和删除 consumer 的时候维护 consumerPool
- 启动一个定时任务,定期从这些 consumer 中获取指标数据。


当消费多分区 topic 时,为了能唯一标志一个 consumer,所以给每个消费者都加了一个 hashcode 的 label。
因为我们所有的 Java 技术栈都是使用的 Prometheus 的包来生成 metrics ,所以该插件也是使用该包生成的数据。
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient</artifactId>
<version>0.12.0</version>
<scope>provided</scope>
</dependency>
为了兼容一些特殊 Java 应用没有该包时会启动报错,所以在初始化插件的时候需要检测当前 classpath 下是否存在该依赖。

这些功能 SW 已经封装好了,对我们来说也是开箱即用。
其实 SW 插件自己也是支持 metrics 的,由于我们只是使用了它的 trace 功能,所以这里就没有使用它的 API。
关于开发一个 SW 插件的流程也比较简单,可以参考官方文档或者是一些现成的插件源码。
https://skywalking.apache.org/docs/skywalking-java/next/en/setup/service-agent/java-agent/java-plugin-development-guide/
总结
有了这个监控面板后,对于 Pulsar 客户端内部的一些运行情况就不再是黑盒了,还可以基于此做一些报警,比如消费堆积、发送延迟过大等。
当然仅仅只有这个面板依然是不够的,后续我们又开发了可以通过 messageId 查询它的整个生命周期,包括:
- 生产者、消费者信息
- 消息生产时间
- 推送时间
- ack 时间等

同时借助与 Pulsar-SQL 的能力,还能以列表的形式展示当前 topic 的消息列表。

当然在实现这两个功能的同时也踩了不少坑,提了几个 PR ,后面在抽时间做具体的分享。
从 Pulsar Client 的原理到它的监控面板的更多相关文章
- 源码解读:webdriver client的原理
前言 又到年底了,群里很多朋友说要开始备战2020金三银四,其实,我建议是,如果你不是技术大牛,就不要去凑热闹. 其实,现在(11,12月份)就是最佳换工作的时候,因为很多人想等着拿了年终再走,虽然招 ...
- Pulsar负载均衡原理及优化
前言 前段时间我们在升级 Pulsar 版本的时候发现升级后最后一个节点始终没有流量. 虽然对业务使用没有任何影响,但负载不均会导致资源的浪费. 和同事沟通后得知之前的升级也会出现这样的情况,最终还是 ...
- Spark Client启动原理探索
经过几天闲暇时间的学习,终于又理解的深入了一些,关于Spark Client如何提交作业也更清晰了点. 在整体的流程图上是这样的: 大体的思路就是应用程序通过SparkSubmit提交程序后,自动在当 ...
- 深入Pulsar Consumer的使用方式&源码分析
原文链接 1.使用前准备 引入依赖: <dependency> <groupId>org.apache.pulsar</groupId> <artifactI ...
- Pulsar云原生分布式消息和流平台v2.8.0
Pulsar云原生分布式消息和流平台 **本人博客网站 **IT小神 www.itxiaoshen.com Pulsar官方网站 Apache Pulsar是一个云原生的分布式消息和流媒体平台,最初创 ...
- Pulsar Consumer实现介绍
Pulsar-Consumer “Pulsar is a distributed pub-sub messaging platform with a very flexible messaging m ...
- 【Apache Pulsar】Apache Pulsar单机环境及Go语言开发环境搭建
0x01 简介 Apache Pulsar是一个开源的分布式发布-订阅消息系统,与Kafka类似,但比后者更加强大.Pulsar最初由Yahoo开发并维护,目前已经成为Apache软件组织的一个孵化子 ...
- webdriver原理、协议
1.webdriver client的原理是什么? 当测试脚本启动firefox的时候,selenium-webdriver 会首先在新线程中启动firefox浏览器.如果测试脚本指定了firefox ...
- 记录一次Elasticsearch线上部署后出现:org.elasticsearch.client.transport.NoNodeAvailableException: None of the configured nodes are available: []的问题解决
说明:ES部署了3个节点,而一般情况只要这三个节点的IP其中一个都可以连接,Web端口使用的是9500,Client连接使用的是9600,调用程序使用了ES原生Client进行连接. 解决方法: 1. ...
- [Pulsar系列] 10分钟学会Pulsar消息系统概念
Apache Pulsar Pulsar是一个支持多租户的.高性能的服务与服务之间消息通讯的解决方案,最初由雅虎开发,现在由Apache软件基金会管理. Pulsar的主要特性如下: Pulsar实例 ...
随机推荐
- MD5简述及常见解密网址推荐
什么是md5 MD5(Message-Digest Algorithm 5)(信息-摘要算法5), 一种被广泛使用的[密码散列函数](https://baike.baidu.com/item/密码散列 ...
- 2022-09-20:以下go语言代码输出什么?A:8 8;B:8 16;C:16 16;D:16 8。 package main import ( “unsafe“ “fmt“ )
2022-09-20:以下go语言代码输出什么?A:8 8:B:8 16:C:16 16:D:16 8. package main import ( "unsafe" " ...
- 2020-11-15:手写代码:行有序、列也有序的二维数组中,找num,找到返回true,否则false?
福哥答案2020-11-15: 此题来源于leetcode240和剑指 Offer(第 2 版)面试题4.1.线性查找.从二维数组的坐下角开始查找.如果当前元素等于目标值,则返回 true.如果当前元 ...
- 2022-06-27:给出一个长度为n的01串,现在请你找到两个区间, 使得这两个区间中,1的个数相等,0的个数也相等, 这两个区间可以相交,但是不可以完全重叠,即两个区间的左右端点不可以完全一样。
2022-06-27:给出一个长度为n的01串,现在请你找到两个区间, 使得这两个区间中,1的个数相等,0的个数也相等, 这两个区间可以相交,但是不可以完全重叠,即两个区间的左右端点不可以完全一样. ...
- 2021-04-04:给定一个非负数组arr,和一个正数m。 返回arr的所有子序列中累加和%m之后的最大值。
2021-04-04:给定一个非负数组arr,和一个正数m. 返回arr的所有子序列中累加和%m之后的最大值. 福大大 答案2021-04-04: 自然智慧即可. 1.递归,累加和. 2.动态规划,累 ...
- vue全家桶进阶之路15:自定义指令
Vue 2.x 中的自定义指令是一种可以用于扩展 Vue.js 核心功能的特性.指令可以用于操作 DOM 元素的属性.监听 DOM 事件.控制 DOM 行为等等,可以将常见的交互行为封装成指令,从而让 ...
- pages.json 文件:自定义导航栏
自定义导航栏使用注意 当navigationStyle设为custom或titleNView设为false时,原生导航栏不显示,此时要注意几个问题: 非H5端,手机顶部状态栏区域会被页面内容覆盖.这是 ...
- 《最新出炉》系列初窥篇-Python+Playwright自动化测试-1-环境准备与搭建
1.简介 有很多人私信留言宏哥问能不能介绍一下Playwright这款自动化神器的相关知识,现在网上的资料太少了.其实在各大博客和公众号也看到过其相关的介绍和讲解.要不就是不全面.不系统,要不就是系统 ...
- [ARM 汇编]进阶篇—异常处理与中断—2.4.1 异常处理概念
异常处理简介 在ARM汇编开发中,异常处理和中断是常见的概念,它们是对系统运行过程中出现的特殊情况进行处理的一种机制.异常处理和中断包括硬件异常.软件异常和外部中断等.当处理器遇到这些特殊情况时,它会 ...
- Flutter状态管理新的实践
1 背景介绍 1.1 声明式ui 声明式UI其实并不是近几年的新技术,但是近几年声明式UI框架非常的火热.单说移动端,跨平台方案有:RN.Flutter.iOS原生有:SwiftUI.android原 ...