RocketMQ源码分析之监控指标分析

news2024/11/24 19:31:29

这里是weihubeats,觉得文章不错可以关注公众号小奏技术,文章首发。拒绝营销号,拒绝标题党

Rocketmq版本

  • version: 5.1.0

背景

继续上次的高可用topic二开已经有了一段时间,现在我们需要对我们的限流数据进行监控,所以现在我们来研究研究RocketMQ的监控源码

入口

这里我们源码的切入点还是以client为切入点

首先我们来看看比如我们要统计topic发送消息的数量是如何统计的。
入口代码我这里直接看的是rocketmq-exporter的源代码,我这里给出部分核心代码


    @Resource
    private MQAdminExt mqAdminExt;

    BrokerStatsData bsd = mqAdminExt.viewBrokerStatsData(masterAddr, BrokerStatsManager.TOPIC_PUT_NUMS, topic);


    BrokerStatsData viewBrokerStatsData(final String brokerAddr, final String statsName, final String statsKey)
        throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQClientException,
        InterruptedException;


可以看到核心方法就是通过viewBrokerStatsData方法
知道了入口后我们就去RocketMQ源码里面具体分析

客户端的监控指标获取

老规矩我们这里直接进去看看netty的通信code

这里可以看到的通信code就是RequestCode.VIEW_BROKER_STATS_DATA

所以我们直接去找到broker对应的业务handler

很快我们就锁定了方法ViewBrokerStatsData(ctx, request)
这里这个方法命名有点奇怪,竟然是大写开头,不过我们不用在意这些小问题

可以考虑给社区提一个pr,不过merge不merge就不知道了,毕竟现在社区的pr已经高达200多个没处理了

进入到ViewBrokerStatsData方法后,我们可以看到有有一个比较核心的方法

这里还记得requestHeader.getStatsName()requestHeader.getStatsKey()的值吗

没错就是我们开始传进来的这两个值

  • requestHeader.getStatsName():BrokerStatsManager.TOPIC_PUT_NUMS
  • requestHeader.getStatsKey(): topic

监控核心数据结构

在上面的分析我们就已经看到了RocketMQ的核心数据结构,没错就是
BrokerStatsManager

这里我们重点关注的属性就是

private final HashMap<String, StatsItemSet> statsTable = new HashMap<>();

这里我简单理了一下他们的关系图

这里我可以简单给大家看看debug实际里面的数据结构

其中statsTable的可以全在Stats类中,大致有如下一些,我这里简单截个图

之前我们使用的BrokerStatsManager.TOPIC_PUT_NUMS实际是不推荐使用了,推荐使用Stats

所以如果我们想要自定义一些监控指标就可以在这里面加一些我们自己的key

StatsItem中的统计维度主要有三个:

  • 分钟:csListMinute
  • 小时:csListHour
  • 天:csListDay

我们在AdminBrokerProcessor中处理客户端的请求的时候拼装返回数据也可以看到

StatsItemSet的初始化

StatsItemSet的初始化主要是在BrokerStatsManagerinit方法

数据是如何写入

通过上面的从clientbroker我们大致知道了数据查询以及存储的数据结构,接下来我们就来看看数据是如何写入的

通过上面的分析我们知道数据是存储在BrokerStatsManagerstatsTable

所以我们看看statsTable中的调用关系

我们很快就定位到了写入TOPIC_PUT_NUMS的方法

    public void incTopicPutNums(final String topic) {
        this.statsTable.get(Stats.TOPIC_PUT_NUMS).addValue(topic, 1, 1);
    }

    public void incTopicPutNums(final String topic, int num, int times) {
        this.statsTable.get(Stats.TOPIC_PUT_NUMS).addValue(topic, num, times);
    }

再通过这两个方法的调用关系,我们发现业务处理器即发消息的处理器SendMessageProcessor有调用

我们可以看到发送消息成功后就会更新改值的内存值

    this.brokerController.getBrokerStatsManager().incTopicPutNums(msg.getTopic(), putMessageResult.getAppendMessageResult().getMsgNum(), 1);

    public void incTopicPutNums(final String topic, int num, int times) {
        this.statsTable.get(Stats.TOPIC_PUT_NUMS).addValue(topic, num, times);
    }

最终将数据写入到了StatsItem中,那么我们的csListMinutecsListHourcsListDay是如何统计的呢?这里我们有一个多个定时任务,每隔10s会去统计一次

统计逻辑就是在samplingInSeconds();方法中,可以看到这里启动的定时任务是10s统计一次

    public void samplingInSeconds() {
        synchronized (this.csListMinute) {
            if (this.csListMinute.size() == 0) {
                this.csListMinute.add(new CallSnapshot(System.currentTimeMillis() - 10 * 1000, 0, 0));
            }
            this.csListMinute.add(new CallSnapshot(System.currentTimeMillis(), this.times.sum(), this.value
                .sum()));
            if (this.csListMinute.size() > 7) {
                this.csListMinute.removeFirst();
            }
        }
    }

这里是总共统计7个值,超过就将之前的移除掉


第一次会添加一个初始化,可以看到我们到第60s刚好会将初始值0移除掉

计算我们的统计指标sumtps则是在computeStatsData这个方法

    private static StatsSnapshot computeStatsData(final LinkedList<CallSnapshot> csList) {
        StatsSnapshot statsSnapshot = new StatsSnapshot();
        synchronized (csList) {
            double tps = 0;
            double avgpt = 0;
            long sum = 0;
            long timesDiff = 0;
            if (!csList.isEmpty()) {
                CallSnapshot first = csList.getFirst();
                CallSnapshot last = csList.getLast();
                sum = last.getValue() - first.getValue();
                tps = (sum * 1000.0d) / (last.getTimestamp() - first.getTimestamp());

                timesDiff = last.getTimes() - first.getTimes();
                if (timesDiff > 0) {
                    avgpt = (sum * 1.0d) / timesDiff;
                }
            }

            statsSnapshot.setSum(sum);
            statsSnapshot.setTps(tps);
            statsSnapshot.setAvgpt(avgpt);
            statsSnapshot.setTimes(timesDiff);
        }

        return statsSnapshot;
    }

总结

至此RocketMQ的一些监控指标的处理就分析完成了,我们从指标的获取->写入->统计都分析到了。
包括如何添加我们自己的监控指标,当然一些小细节就限于篇幅就没具体分析比如,统计计数使用的LongAdder而不是AtomicLong

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/425222.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt中英文切换(涉及多种场景)

qt中英文切换涉及到一个软件两个文件&#xff0c;分别是QtLinguist、.ts文件和.qm文件。 1、在Pro中添加 TRANSLATIONS en.ts \ch.ts添加这个文件后qmake&#xff0c;然后如下操作点击更新&#xff1a; 这个时候会生成2两个文件en.ts和ch.ts。 2、将这两个文件添加到项目中…

C++ : 构造函数 析构函数

&#x1f535;前提引入 &#xff1a; 1如果一个类中什么成员都没有&#xff0c;称为空类&#xff0c;但空类并非什么都没有&#xff0c;在我们没有写任何东西时&#xff0c;编译器会自动生成6个默认成员函数。 2.默认成员函数 &#xff1a; 用户没有显式实现&#xff0c;编译器…

Redis快速上手

Redis快速上手 OVERVIEWRedis快速上手1.redis数据类型2.redis常用命令StringListSetSortedSetHashKey相关3.redis配置文件4.redis数据持久化5.hiredis使用连接数据库执行redis命令函数释放资源程序实例1.redis数据类型 key: 必须是字符串 - “hello” value: 可选的 String类型…

核心业务5:充值业务实现

核心业务5:我要充值 1.充值业务流程图 2.充值业务流程逻辑 3.数据库表 4.前端逻辑代码 5.汇付宝代码逻辑 6.尚融宝代码逻辑 7.幂等性判断原理和解决方案 8.代码规范和原理了解 核心业务5:我要充值 1.充值业务流程图

基于springboot的在线考试系统源码数据库论文

目 录 目 录 第一章 概述 1.1研究背景 1.2 开发意义 1.3 研究现状 1.4 研究内容 1.5论文结构 第二章 开发技术介绍 2.1 系统开发平台 2.2 平台开发相关技术 2.2.1 Java技术 2.2.2 mysql数据库介绍 2.2.3 MySQL环境配置 2.2.4 B/S架构 2.2.5 Spr…

如何在Linux系统中使用 envsubst 命令替换环境变量?

在Linux系统中&#xff0c;环境变量是非常常见的一种机制&#xff0c;它们被用于存储重要的系统信息&#xff0c;比如用户的登录名、路径等等。当在脚本中需要使用这些变量时&#xff0c;可以使用envsubst命令&#xff0c;该命令可以将环境变量的值替换到文本文件中。 本文将介…

低静态电流-汽车电池反向保护系统的方法

低静态电流-汽车电池反向保护系统的方法 背景 车辆中电子电路数量不断增加&#xff0c;使得需要消耗的电池电量也随之大幅增长。为了支持遥控免钥进入和安全等功能&#xff0c;即使在汽车停车或熄火时&#xff0c;电池也要持续供电。 由于所有车辆都使用有限的电池供电&…

三轴XYZ平台生成gcode文件

1. 生成gcode坐标文件 gcode文件中保存的是需要绘制图形的路径信息&#xff0c;这里我们采用开源矢量图形编辑软件 Inkscape并通过Unicorn G-Code插件来生成 gcode坐标文件。 将软件资料包\Inkscape.rar 压缩文件解压到电脑上任意磁盘&#xff0c;软件内已安装 Unicorn G-Code插…

【花雕学AI】深度挖掘ChatGPT角色扮演的一个案例—CHARACTER play : 莎士比亚

CHARACTER play : 莎士比亚 : 52岁&#xff0c;男性&#xff0c;剧作家&#xff0c;诗人&#xff0c;喜欢文学&#xff0c;戏剧&#xff0c;爱情 : 1、问他为什么写《罗密欧与朱丽叶》 AI: 你好&#xff0c;我是莎士比亚&#xff0c;一位英国的剧作家和诗人。我很高兴你对我的…

【论文速览】图像分割领域的通用大模型SegGPT - Segmenting Everything in Context

文章目录研究背景解决思路PainterSegGPT实验效果&#xff08;部分&#xff09;思考参考资料代码地址&#xff1a;https://github.com/baaivision/Painter Demo地址&#xff1a;https://huggingface.co/spaces/BAAI/SegGPT 研究背景 图像分割一直是计算机视觉领域的一项基础研究…

Free container identify , CIMCAI container detect cloud service

集装箱箱号识别API免费&#xff0c;中国上海人工智能企业CIMCAI飞瞳引擎™集装箱人工智能平台全球近4千企业用户&#xff0c;全球领先的飞瞳引擎™AI集装箱识别云服务&#xff0c;集装箱残损识别箱况检测缺陷检验&#xff0c;小程序拍照检测或支持API接口二次开发&#xff0c;应…

数据结构初阶(算法的复杂度 + 包装类 + 泛型)

文章目录一、算法复杂度1. 算法效率2. 时间复杂度&#xff08;1&#xff09; O的渐进表示法3. 空间复杂度二、包装2.1 为什么会出现包装2.2 分类2.3 装箱和拆箱&#xff08;1&#xff09;装箱/装包&#xff08;2&#xff09;拆箱/拆箱三、泛型3.1 泛型的基本概念3.2 泛型的使用…

2023 年 3 月 GameFi 月度报告

作者&#xff1a;danielfootprint.network 数据来源&#xff1a;Monthly GameFi Report 三月的 GameFi 世界相对沉寂&#xff0c;没有重大的消息公开&#xff0c;没有亮眼的游戏出现&#xff0c;也没有死亡螺旋的发生。 GameFi 领域的重要名字 Splinterlands 和 Hive 开始面…

Redis一主二从搭建

Redis一主二从环境搭建 一主二从 准备工作 安装VMWare 下载镜像 创建下面的目录 Redis-Cluster master mastervmdk slave00 slave00vmdk slave01 slave00vmdk VMWare中安装CentOS7 自定义(高级) 默认 安装程序光盘映像文件 命名虚拟机&#xff0c;选择我们刚才创建的…

ASEMI代理ADAU1961WBCPZ-R7原装ADI车规级ADAU1961WBCPZ-R7

编辑&#xff1a;ll ASEMI代理ADAU1961WBCPZ-R7原装ADI车规级ADAU1961WBCPZ-R7 型号&#xff1a;ADAU1961WBCPZ-R7 品牌&#xff1a;ADI/亚德诺 封装&#xff1a;LFCSP-32 批号&#xff1a;2023 引脚数量&#xff1a;32 安装类型&#xff1a;表面贴装型 ADAU1961WBCPZ-…

通过简单demo让你秒懂Python的编译和执行全过程

基本说明 python 是一种解释型的编程语言&#xff0c;所以不像编译型语言那样需要显式的编译过程。然而&#xff0c;在 Python 代码执行之前&#xff0c;它需要被解释器转换成字节码&#xff0c;这个过程就是 Python 的编译过程。 DEMO演示讲解 假设我们有以下 Python 代码&…

常见安全设备

文章目录前言安全厂商安全设备种类拓扑图防火墙IDSIPSwaf上网行为管理器数据库审计系统全流量设备蜜罐态势感知前言 最近在了解安全设备的基本原理&#xff0c;简单做一下笔记。 安全厂商 深信服、浪潮、奇安信、绿盟、山石网科、启明星辰、安恒、360、新华3 安全设备种类 …

【CSS】元素显示与隐藏 ( display 隐藏对象 | visibility 隐藏对象 | overflow 隐藏对象 )

文章目录一、元素的显示与隐藏二、display 隐藏对象1、display 隐藏对象语法说明2、display 显示元素代码示例3、display 隐藏元素代码示例三、visibility 隐藏对象1、visibility 隐藏对象语法说明2、visibility 显示对象代码示例3、visibility 隐藏对象代码示例四、overflow 隐…

大数据项目实战之数据仓库:电商数据仓库系统——第5章 数据仓库设计

第5章 数据仓库设计 5.1 数据仓库分层规划 优秀可靠的数仓体系&#xff0c;需要良好的数据分层结构。合理的分层&#xff0c;能够使数据体系更加清晰&#xff0c;使复杂问题得以简化。以下是该项目的分层规划。 5.2 数据仓库构建流程 以下是构建数据仓库的完整流程。 5.2.1 …

在unreal中的基于波叠加的波浪水面材质原理和制作

关于水的渲染模型 如何渲染出真实的水体和模拟&#xff0c;是图形学&#xff0c;游戏开发乃至仿真领域很有意思的一件事 记得小时候玩《Command & Conquer: Red Alert 3》&#xff0c;被当时的水面效果深深震撼&#xff0c;作为一款2008年出的游戏&#xff0c;现在想起它…