SpringBoot定时监听RocketMQ的NameServer

news2025/2/27 23:10:59

问题分析

  • 自己在测试环境部署了RocketMQ,发现namesrv很容易挂掉,于是就想着监控,挂了就发邮件通知。
  • 查看了rocketmq-dashboard项目,发现只能监控Broker,遂放弃这一路径。
  • 于是就从报错的日志入手,发现最终可以根据RocketMQTemplate获得可活动的NameServer。

报错日志

  • 报错日志如下:
12月 25 13:59:22 192.168.240.65 java[59571]: 2023-12-25 13:59:22.598  INFO 59571 --- [tWorkerThread_2] RocketmqRemoting                         : NETTY CLIENT PIPELINE: CLOSE 192.168.240.86:9876
12月 25 13:59:22 192.168.240.65 java[59571]: 2023-12-25 13:59:22.598  INFO 59571 --- [tWorkerThread_2] RocketmqRemoting                         : closeChannel: the channel[192.168.240.86:9876] was removed from channel table
12月 25 13:59:22 192.168.240.65 java[59571]: 2023-12-25 13:59:22.598  INFO 59571 --- [tWorkerThread_2] RocketmqRemoting                         : NETTY CLIENT PIPELINE: CLOSE 192.168.240.86:9876
12月 25 13:59:22 192.168.240.65 java[59571]: 2023-12-25 13:59:22.598  INFO 59571 --- [tWorkerThread_2] RocketmqRemoting                         : eventCloseChannel: the channel[null] has been removed from the channel table before
12月 25 13:59:22 192.168.240.65 java[59571]: 2023-12-25 13:59:22.598  INFO 59571 --- [lientSelector_1] RocketmqRemoting                         : closeChannel: close the connection to remote address[192.168.240.86:9876] result: true
12月 25 13:59:25 192.168.240.65 java[59571]: 2023-12-25 13:59:25.597  INFO 59571 --- [ntScan_thread_1] RocketmqRemoting                         : createChannel: begin to connect remote host[192.168.240.86:9876] asynchronously
12月 25 13:59:25 192.168.240.65 java[59571]: 2023-12-25 13:59:25.597  INFO 59571 --- [tWorkerThread_3] RocketmqRemoting                         : NETTY CLIENT PIPELINE: CONNECT  UNKNOWN => 192.168.240.86:9876
12月 25 13:59:25 192.168.240.65 java[59571]: 2023-12-25 13:59:25.598  WARN 59571 --- [ntScan_thread_1] RocketmqRemoting                         : createChannel: connect remote host[192.168.240.86:9876] failed, AbstractBootstrap$PendingRegistrationPromise@f2a3fc5(failure: io.netty.channel.AbstractChannel$AnnotatedConnectException: 拒绝连接: /192.168.240.86:9876)


  • 根据日志可以发现是NettyRemotingClient类在做监控,持续调用,具体核心方法:
org.apache.rocketmq.remoting.netty.NettyRemotingClient#createChannel
  • createChannel的源码:
private Channel createChannel(String addr) throws InterruptedException {
        NettyRemotingClient.ChannelWrapper cw = (NettyRemotingClient.ChannelWrapper)this.channelTables.get(addr);
        if (cw != null && cw.isOK()) {
            return cw.getChannel();
        } else {
            if (this.lockChannelTables.tryLock(3000L, TimeUnit.MILLISECONDS)) {
                try {
                    cw = (NettyRemotingClient.ChannelWrapper)this.channelTables.get(addr);
                    boolean createNewConnection;
                    if (cw != null) {
                        if (cw.isOK()) {
                            Channel var4 = cw.getChannel();
                            return var4;
                        }

                        if (!cw.getChannelFuture().isDone()) {
                            createNewConnection = false;
                        } else {
                            this.channelTables.remove(addr);
                            createNewConnection = true;
                        }
                    } else {
                        createNewConnection = true;
                    }

                    if (createNewConnection) {
                        ChannelFuture channelFuture = this.bootstrap.connect(RemotingHelper.string2SocketAddress(addr));
                        LOGGER.info("createChannel: begin to connect remote host[{}] asynchronously", addr);
                        cw = new NettyRemotingClient.ChannelWrapper(channelFuture);
                        this.channelTables.put(addr, cw);
                    }
                } catch (Exception var8) {
                    LOGGER.error("createChannel: create channel exception", var8);
                } finally {
                    this.lockChannelTables.unlock();
                }
            } else {
                LOGGER.warn("createChannel: try to lock channel table, but timeout, {}ms", 3000L);
            }

            if (cw != null) {
                ChannelFuture channelFuture = cw.getChannelFuture();
                if (channelFuture.awaitUninterruptibly((long)this.nettyClientConfig.getConnectTimeoutMillis())) {
                    if (cw.isOK()) {
                        LOGGER.info("createChannel: connect remote host[{}] success, {}", addr, channelFuture.toString());
                        return cw.getChannel();
                    }

                    LOGGER.warn("createChannel: connect remote host[" + addr + "] failed, " + channelFuture.toString());
                } else {
                    LOGGER.warn("createChannel: connect remote host[{}] timeout {}ms, {}", new Object[]{addr, this.nettyClientConfig.getConnectTimeoutMillis(), channelFuture.toString()});
                }
            }

            return null;
        }
    }
  • 从源码中可以看到报错的日志数据

追溯

  • 以NettyRemotingClient类为起点,使用Debug分析,最终可以看到完整的调用链路:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/332d213235a6439eb748c8422d480a44.png

监控开发

  • 那么监控开发就很容易了,注册RocketMQTemplate,使用定时任务监听即可,示例代码如下:
@Slf4j
@Component
public class MQMonitorTask {


    @Resource
    private RocketMQTemplate rocketMQTemplate;

    @Scheduled(cron = "0/10 * * * * ?")
    public void scanNameServerBroker() {
        org.apache.rocketmq.remoting.RemotingClient remotingClient = rocketMQTemplate.getProducer()
                .getDefaultMQProducerImpl().getMqClientFactory().getMQClientAPIImpl().getRemotingClient();
        // 注册的 NameServer
        List<String> nameServerAddressList = remotingClient.getNameServerAddressList();
        // 当前活跃的 NameServer
        List<String> availableNameSrvList = remotingClient.getAvailableNameSrvList();
        log.info("nameServerAddressList:{}", JSONUtil.toJsonStr(nameServerAddressList));
        log.info("availableNameSrvList:{}", JSONUtil.toJsonStr(availableNameSrvList));
        // 只要 nameServerAddressList 和 availableNameSrvList 大小不一致,即可做邮件通知,具体阈值自己设置!!!
        // TODO:邮件通知
    }

}

  • 另外要在SprongBoot启动类加上注解@EnableScheduling来开启定时任务。

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

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

相关文章

vue整理面试题

1. v-if/v-show的区别? v-if"表达式" 当表达式值true&#xff0c;v-if所作用的元素显示 否则隐藏 v-show"表达式" 当表达式值true&#xff0c;v-if所作用的元素显示 否则隐藏 理解&#xff1a; v-if控制元素显示与隐藏&#xff0c;通过js创建dom元素或删除…

用通俗易懂的方式讲解大模型:ChatGLM3-6B 部署指南

最近智谱 AI 对底层大模型又进行了一次升级&#xff0c;ChatGLM3-6B 正式发布&#xff0c;不仅在性能测试和各种测评的数据上有显著提升&#xff0c;还新增了一些新功能&#xff0c;包括工具调用、代码解释器等&#xff0c;最重要的一点是还是保持 6B 的这种低参数量&#xff0…

阿里员工:本月收入489325元,开心过年

阿里员工&#xff1a;本月收入489325元&#xff0c;开心过年 近日&#xff0c;一名阿里员工在社交媒体上爆料自己的本月收入&#xff0c;竟然高达48.9万&#xff0c;真是让人目瞪口呆。 震惊之余&#xff0c;大家都很好奇这么高收入是怎么来的&#xff0c;再仔细看工资单&…

C++初阶——基础知识(内联函数)

目录 1.内联函数 内联函数的示例代码 1.内联函数 是一种 C 中的函数定义方式&#xff0c;它告诉编译器在每个调用点上插入函数体的副本&#xff0c;而不是像普通函数那样在调用时跳转到函数体所在的地址执行。这样可以减少函数调用的开销&#xff0c;提高程序的执行效率。 …

【算法】数论---欧拉函数

什么是欧拉函数&#xff1f; 对于正整数n&#xff0c;欧拉函数是小于或等于n的正整数中与n互质的数的数目&#xff0c;记作φ(n) φ(1)1 当m,n互质时&#xff0c;φ(mn)φ(m)∗φ(n) 一、求一个正整数的欧拉函数---&#xff08;先对它分解质因数&#xff0c;然后套公式&#xf…

子网划分问题(实战超详解)_主机分配地址

文章目录: 子网划分的核心思想 第一步,考虑借几位作为子网号 第二步,确定子网的网络地址 第三步,明确网络地址,广播地址,可用IP地址范围 一些可能出现的疑问 实战 题目一 子网划分的核心思想 网络号不变,借用主机号来产生新的网络 划分前的网络:网络号主机号 划分后的网络:原网…

SpringBoot 一个注解实现数据脱敏

什么是数据脱敏 数据脱敏是指对某些敏感信息&#xff0c;例如姓名、身份证号码、手机号、固定电话、银行卡号、邮箱等个人信息&#xff0c;通过脱敏算法进行数据变形&#xff0c;以保护敏感隐私数据。 数据脱敏通常涉及以下几种主要方法&#xff1a; 替换&#xff1a; 将原始…

【量化】蜘蛛网策略复现

文章目录 蜘蛛网策略研报概述持仓数据整理三大商品交易所的数据统一筛选共有会员清洗数据计算研报要求数据全部代码 策略结果分析无参数策略有参数策略正做反做 MSD技术指标化 蜘蛛网策略 策略来自《东方证券-股指期货趋势交易之蜘蛛网策略——从成交持仓表中捕捉知情投资者行为…

Blender:从新手到专家的全方位指南

Blender&#xff0c;这款强大的开源3D建模和渲染软件&#xff0c;已经成为了CG行业的标准工具之一。它不仅拥有丰富的教程资源&#xff0c;而且还在不断发展和完善中。尽管Blender的教程主要集中在国外网站和YouTube上&#xff0c;但其全面的功能和易用性使它成为许多人的首选工…

电子邮件地址填写指南:格式与常见问题解答

一个专业的电子邮件地址是一个你只用于工作目的的通信帐户。当你给收件人发送电子邮件时&#xff0c;这是他们最先看到的细节之一。无论你的职位或行业如何&#xff0c;拥有一个专业的电子邮件地址都可以提高你和所在公司的可信度。 在本文中我们解释了专业的电子邮件地址是什么…

python基础-01

文章目录 前言一、python中的注释二、变量的数据类型1.Number&#xff08;数字&#xff09;2.Boolean&#xff08;布尔类型&#xff09;—— True 和 False3.String&#xff08;字符串&#xff09;4.List&#xff08;列表&#xff09;5.Tuple&#xff08;元组&#xff09;6.Dic…

wordpress日主题模版Ripro-v5 6.4开心版

RiPro主题全新V5版本&#xff0c;&#xff08;原RiPro v2旧版已停更&#xff09;是一个优秀且功能强大、速度极快&#xff0c;易于管理、现代化的WordPress虚拟资源商城主题。支持首页模块化布局和WP原生小工具模块化首页可拖拽设置&#xff0c;让您的网站设计体验更加舒适。同…

Mastercam各版本安装指南

Mastercam下载链接 https://pan.baidu.com/s/1OldNR0ERqJFrEN24uu3j0Q?pwd0531 1.鼠标右击【Mastercam2024(64bit)】压缩包&#xff08;win11及以上系统需先点击“显示更多选项”&#xff09;【解压到 Mastercam2024(64bit)】。 2.打开解压后的文件夹&#xff0c;鼠标右击【…

LVS那点事

LVS 原理 IPVS LVS 的 IP 负载均衡技术是通过 IPVS 模块来实现的&#xff0c;IPVS 是 LVS 集群系统的核心软件&#xff0c;它的主要作用是&#xff1a;安装在 Director Server 上&#xff0c;同时在 Director Server 上虚拟出一个 IP 地址&#xff0c;用户必须通过这个虚拟的…

算法基础之滑雪

滑雪 核心思想&#xff1a;记忆化搜索 状态表示&#xff1a; f[i][j] 表示所有从(i,j) 开始滑的路径的最大值 状态计算&#xff1a; 分成四个方向 f[i][j] max(f[i][j] , f[i][j1] 1) 且h[a][b] (下一个点) 必须严格小于 h[i][j] 才能滑过去 #include<iostream>#…

从仿写持久层框架到MyBatis核心源码阅读

接上篇手写持久层框架&#xff1a;https://blog.csdn.net/liwenyang1992/article/details/134884703 MyBatis源码 MyBatis架构原理&主要组件 MyBatis架构设计 MyBatis架构四层作用是什么呢&#xff1f; API接口层&#xff1a;提供API&#xff0c;增加、删除、修改、查询…

20231228在Firefly的AIO-3399J开发板的Android11的挖掘机的DTS配置单前置摄像头ov13850

20231228在Firefly的AIO-3399J开发板的Android11的挖掘机的DTS配置单前置摄像头ov13850 2023/12/28 10:42 【碰到一个很神奇的问题】&#xff1a; 昨天晚上前置摄像头怎么也点不亮&#xff01;改了巨多的地方&#xff01;晚上睡觉之前把开发板彻底断电了&#xff01;今天开电脑…

SLAM学习入门--机器学习

文章目录 机器学习逻辑回归&#xff08;LR&#xff09;基本原理为什么 LR 要使用 sigmoid 函数&#xff1f;LR 可以用核函数么&#xff1f;为什么 LR 用交叉熵损失而不是平方损失&#xff1f;LR 能否解决非线性分类问题&#xff1f;LR为什么要离散特征&#xff1f;逻辑回归是处…

51和32单片机读取FSR薄膜压力传感器压力变化

文章目录 简介线性电压转换模块51单片机读取DO接线方式51代码实验效果 32单片机读取AO接线方式32代码实验效果 总结 简介 FSR薄膜压力传感器是可以将压力变化转换为电阻变化的一种传感器&#xff0c;单片机可以读取然后作为粗略测量压力&#xff08;仅提供压力变化&#xff0c;…

各部门请注意,VELO维乐潮流骑士尼莫出街啦,快来加入吧!

VELO潮流骑士丨车界“小学生”尼莫&#xff0c;下面是来自她的自诉&#xff1a;      大家好&#xff01;我是尼莫&#xff0c;一枚骑车届的“小学生”&#xff0c;我爱上骑车已经有一年的时间啦&#xff01;在这一年的时间里&#xff0c;骑车改变了我很多&#xff1a;爱上…