当前位置: 首页 > news >正文

SpringBoot定时监听RocketMQ的NameServer

问题分析

  • 自己在测试环境部署了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 {@Resourceprivate RocketMQTemplate rocketMQTemplate;@Scheduled(cron = "0/10 * * * * ?")public void scanNameServerBroker() {org.apache.rocketmq.remoting.RemotingClient remotingClient = rocketMQTemplate.getProducer().getDefaultMQProducerImpl().getMqClientFactory().getMQClientAPIImpl().getRemotingClient();// 注册的 NameServerList<String> nameServerAddressList = remotingClient.getNameServerAddressList();// 当前活跃的 NameServerList<String> availableNameSrvList = remotingClient.getAvailableNameSrvList();log.info("nameServerAddressList:{}", JSONUtil.toJsonStr(nameServerAddressList));log.info("availableNameSrvList:{}", JSONUtil.toJsonStr(availableNameSrvList));// 只要 nameServerAddressList 和 availableNameSrvList 大小不一致,即可做邮件通知,具体阈值自己设置!!!// TODO:邮件通知}}
  • 另外要在SprongBoot启动类加上注解@EnableScheduling来开启定时任务。

相关文章:

SpringBoot定时监听RocketMQ的NameServer

问题分析 自己在测试环境部署了RocketMQ&#xff0c;发现namesrv很容易挂掉&#xff0c;于是就想着监控&#xff0c;挂了就发邮件通知。查看了rocketmq-dashboard项目&#xff0c;发现只能监控Broker&#xff0c;遂放弃这一路径。于是就从报错的日志入手&#xff0c;发现最终可…...

电子招标采购系统源码之从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理

在数字化时代&#xff0c;采购管理也正经历着前所未有的变革。全过程数字化采购管理成为了企业追求高效、透明和规范的关键。该系统通过Spring Cloud、Spring Boot2、Mybatis等先进技术&#xff0c;打造了从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通过…...

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

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

Flutter配置Android和IOS允许http访问

默认情况下&#xff0c;Android和IOS只支持对https的访问&#xff0c;如果需要访问不安全的连接&#xff0c;也就是http&#xff0c;需要做以下配置。 Android 在res目录下的xml目录中(如果不存在&#xff0c;先创建xml目录)&#xff0c;创建一个xml文件network_security_con…...

[设计模式 Go实现] 创建型~抽象工厂模式

抽象工厂模式用于生成产品族的工厂&#xff0c;所生成的对象是有关联的。 如果抽象工厂退化成生成的对象无关联则成为工厂函数模式。 比如本例子中使用RDB和XML存储订单信息&#xff0c;抽象工厂分别能生成相关的主订单信息和订单详情信息。 如果业务逻辑中需要替换使用的时候…...

移动端开发框架mui代码在安卓模拟器上运行(HbuilderX连接到模拟器)

开发工具 HBuilder X 3.8.12.20230817 注意&#xff1a;开发工具尽量用最新的或较新的。太旧的版本在开发调试过程中可能会出现莫名其妙的问题。 1、电脑下载安装安卓模拟器 我这里使用的是 夜神模拟器 &#xff0c;也可以选择其他安卓模拟器 夜神模拟器官网&#xff1a;夜神安…...

upload-labs Pass-03(黑名单验证,特殊后缀)问题纠正

php任何后缀名解析 背景&#xff1a;为了验证php解析不依靠后缀名&#xff0c;可以是任何后缀名&#xff0c;纠正upload-labs Pass-03&#xff08;黑名单验证&#xff0c;特殊后缀&#xff09;里所说的几个固定的后缀名理论是错误的。1 部署1.1 环境准备1.1.1 系统、内核&#…...

微信小程序-父子页面传值

父子页面传值 父页面向子页面传值 方法一&#xff1a; 父页面&#xff1a; 1. /page/xxx/xxx?id1子页面&#xff1a; onLoad:function(option){ }方法二 <bindtap“func” data-xxx””> 子页面向父页面传值 定义父子页面 父页面&#xff1a;hotspot 子页面&a…...

【JavaScript】浮点数精度问题

✨ 专栏介绍 在现代Web开发中&#xff0c;JavaScript已经成为了不可或缺的一部分。它不仅可以为网页增加交互性和动态性&#xff0c;还可以在后端开发中使用Node.js构建高效的服务器端应用程序。作为一种灵活且易学的脚本语言&#xff0c;JavaScript具有广泛的应用场景&#x…...

使用axios发送get和post请求

使用axios发送get和post请求的方法如下&#xff1a; 1.发送GET请求&#xff1a; axios.get(url).then(response > {// 请求成功的处理逻辑console.log(response.data);}).catch(error > {// 请求失败的处理逻辑console.error(error);});2.发送POST请求&#xff1a; ax…...

【基于VirtualBox及openEuler20.03 TLS SP1编译openGauss2.1.0源码】

【openEuler 20.03 TLS编译openGauss2.1.0源码】 一、安装环境二、安装步骤 一、安装环境 项目Value虚拟机virtualbox操作系统openEuler 20.03 TLSopenGauss2.1.0openGauss-third_party2.1.0 二、安装步骤 以下操作需要在root用户下执行 编辑/etc/selinux/config vim /etc/s…...

hibernate 使用注解+拦截器实现自动开启、关闭session,提交、回滚事务

hibernate 使用注解+注解拦截器实现自动开启、关闭session,开启、提交、回滚事务 项目为springboot项目 ,springboot版本为:2.5.11, hiernate-core5.4.3 版本。spring-xxx 等为5.3.17版本 注意:在spring-xxx4.x版本+ hiernate-core5.x.x版本中,hibernate的配置 true是有效的…...

Solidworks学习笔记

本内容为solidworks的学习笔记&#xff0c;根据自己的理解进行记录&#xff0c;部分可能不正确&#xff0c;请自行判断。 学习视频参考&#xff1a;【SolidWorks2018视频教程 SW2018中文版软件基础教学知识 SolidWorks自学教程软件操作教程 sw视频教程 零基础教程 视频教程】 h…...

Redis经典五大类型源码及底层实现(一)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理、数据库技术&#x1f525;如果感觉博主的文章还不错的…...

数据库闭包求法 附相关习题及解析

闭包就是由一个属性直接或间接推导出的所有属性的集合 以下是写的比较科学规范的闭包求解方法&#xff0c;设X和Y均为关系R的属性集的子集&#xff0c;F是R上的函数依赖集&#xff0c;若对R的任一属性集B&#xff0c;一旦X→B&#xff0c;必有B⊆Y&#xff0c;且对R的任一满足…...

idea利用JRebel插件,无需重启,实现Spring Boot项目热重载,节省开发时间和精力!

插件介绍 官方介绍 翻译过来的意思是&#xff1a; JRebel 是一款提高开发效率的工具&#xff0c;允许开发者立即重新加载代码更改。它跳过了在Java开发中常见的重新构建、重启和重新部署循环。JRebel 能够让开发者在相同的时间内完成更多工作&#xff0c;并且在编码时能够保持…...

学习体系结构 - AArch64内存管理

学习体系结构 - AArch64内存管理 Learn the architecture - AArch64 memory management Version 1.2 个人的英语很一般&#xff0c;对拿不准的翻译校准在后面添加了英文原文。 1、 概述 本指南介绍了AArch64中的内存转换&#xff0c;这是内存管理的关键。它解释了如何将虚拟地…...

Vue3 精通指南:如何在 setup 函数中巧妙利用 Vuex

在 Vue 3 中&#xff0c;如果你使用了组合式 API&#xff08;Composition API&#xff09;&#xff0c;你可以通过 setup 函数来设置组件的响应式状态和逻辑。要在 setup 函数中访问 Vuex 的 $store&#xff0c;你可以使用 useStore 钩子&#xff0c;它是 Vuex 4 为 Vue 3 提供…...

Linux 服务器安全策略技巧:启用账户锁定策略

Linux 服务器安全策略技巧:启用账户锁定策略 在Linux服务器上,启用账户锁定策略是一种重要的安全措施。通过锁定账户,可以防止未经授权的访问和恶意活动。本文将介绍如何在Linux服务器上启用账户锁定策略。 什么是账户锁定策略? 账户锁定策略是一种安全措施,用于限制对…...

野火霸道-V2+3.2寸屏+FreeRTOS+LVGL移植

摘要 基于野火霸道-V23.2寸屏的开发板&#xff0c;下载器为STLINK分为两个版本&#xff0c;FreeRTOS和裸机版本 裸机 裸机准备 lvgl v8.2版本的源码野火的《触摸画板-3.2寸》与《基本定时器》的代码例程 移植 将基本定时器代码移植到触摸画板-3.2寸的例程中&#xff0c;…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…...

Unity中的transform.up

2025年6月8日&#xff0c;周日下午 在Unity中&#xff0c;transform.up是Transform组件的一个属性&#xff0c;表示游戏对象在世界空间中的“上”方向&#xff08;Y轴正方向&#xff09;&#xff0c;且会随对象旋转动态变化。以下是关键点解析&#xff1a; 基本定义 transfor…...