一次 RocketMQ 进程自动退出排查经验分享(实战篇)
1、背景
公司一个 RocketMQ 集群由4主4从组成,突然其中3台服务器“竟然”在同一时间下线,其监控显示如下:
依次查看三台机器的监控图形,时间戳几乎完美“吻合”,不可思议吧。
2、故障分析
出现问题,先二话不说,马上重启各服务器,尽快恢复集群,降低对业务的影响,接下来开始对日志进行分析。
Java 进程自动退出(rocketmq 本身就是一个java进程),一种最常见的问题是由于内存溢出或由于内存泄漏导致进程发送Crash等。由于我们的启动参数中未配置-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/opt/jvmdump 这两个参数,不能直接根据 是否生成 dump 文件,那退而求其次去查看其GC日志,将GC日志下载到本地,然后可以使用一个在线gc日志分析工具:https://gceasy.io/ ,将 gc 日志上传后会给出图形化的展示,其图如下:
发现垃圾回收很正常。
既然 Java 进程不是由于内存溢出等问题导致的退出,那又会是什么原因呢?那我们来看一下那个点的broker的日志,其关键日志截图如下:
发现 broker 日志中有打印出 shutdownHook,表示在进程退出之前执行了启动时注册时的退出钩子函数,说明 broker 是正常停止的,并且也不可能是 kill -9 命令,肯定是显示的执行了 shutodown 或 kill 命令,于是立马使用 history 命令 查看历史命令,都未在指定时间执行过该命令,并且切换到 root 命令后,同样使用 history 命令,并未发现端倪。
但我始终相信,肯定是执行了手动执行了 kill 命令导致进程退出的,经过网上查找查,得知可以通过查阅系统日志/var/log/messages 来查看系统命令的调用,于是乎把日志文件下载到本地,开始搜索 kill 关键字,发现如下日志:
发现最近一次 kill 命令是在25号的凌晨1点多,停止 rocketmq 集群,并使用 bin/mqbroker -c conf/broker-b.conf & 进行了重新启动。
这个命令是有问题的,没有使用 nohup ,如果会话失效,该进程就会被退出,为了验证,我们再查一下进程退出时的日志:
发现在故障发生点确实有 Removed 相关的日志。
故障原因基本分析到位了,运维在启动的时候没有使用 nohup 来启动,故马上排查刚启动的集群的方式,重新重启刚启动的 Broker。
RocketMQ优雅重启小建议:
-
首先将 broker 的写权限关闭,命令如下:
bin/mqadmin updateBrokerConfig -b 192.168.x.x:10911 -n 192.168.x.x:9876 -k brokerPermission -v 4
- 通过 rocketmq-console 查看该broker的写入TPS,当写入TPS降为0后,再使用 kill pid 关闭 rocketmq 进程。温馨提示:将broker的写权限关闭后,非顺序消息不会立马拒绝,而是需要等客户端路由信息更新后,不会在往该broker上发送消息,故这个过程需要等待。
-
启动 rocketmq
nohup bin/mqbroker -c conf/broker-a.conf /dev/null 2>&1 &
注意:nohup。
-
恢复该节点的写权限
bin/mqadmin updateBrokerConfig -b 192.168.x.x:10911 -n 192.168.x.x:9876 -k brokerPermission -v 6
本文的故障分析与处理就介绍到这里,本文重点讲解了故障的分析过程以及 RocketMQ Broker 优雅停机的方案。
如果本文对您有所帮助的话,麻烦帮忙点个赞,谢谢。
作者介绍:
丁威,《RocketMQ技术内幕》作者,RocketMQ 社区布道师,公众号:中间件兴趣圈 维护者,目前已陆续发表源码分析Java集合、Java 并发包(JUC)、Netty、Mycat、Dubbo、RocketMQ、Mybatis等源码专栏。
原文发布时间为:2019-10-27
本文作者:丁威,《RocketMQ技术内幕》作者。
本文来自中间件兴趣圈,了解相关信息可以关注中间件兴趣圈。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Bug集锦-Spring Cloud Feign调用其它接口报错
问题描述 Spring Cloud Feign调用其它服务报错,错误提示如下:Failed to instantiate [java.util.List]: Specified class is an interface。 解决方案 通过查询一些资料,得到的结论,是定义接口传递的参数时,没有用@RequestBody修饰,查看定义接口有用@RequestBogy修饰,Feign的接口实现里没有用@RequestBody修饰,添加后问题就解决了,以后还是要仔细看待每个问题。
- 下一篇
Java虚拟机线上问题排查的2个基本操作,你知不知道?
前言 对于后端程序员,特别是 Java 程序员来讲,排查线上问题是不可避免的。各种 CPU 飚高,内存溢出,频繁 GC 等等,这些都是令人头疼的问题。楼主同样也遇到过这些问题,那么,遇到这些问题该如何解决呢?首先,出现问题,肯定要先定位问题所在,然后分析问题原因,再然后解决问题,最后进行总结,防止下次再次出现。今天的文章,就如我们的题目一样,讲的是基本操作,也就是一些排查线上问题的基本方法。为什么这么说呢?因为线上问题千奇百怪,就算是身经百战的专家也会遇到棘手的问题,因此不可能在一篇文章里说完,还有一个最重要的原因,当然就是楼主的水平不到位。但不到位归不到位,任何经验都是值得记录的,因此,楼主有必要将这些问题记录一下。还有,本文的排查环境是 Linux. CPU 飚高 线上 CPU 飚高问题大家应该都遇到过,那么如何定位问题呢?思路:首先找到 CPU 飚高的那个 Java 进程,因为你的服务器会有多个 JVM 进程。然后找到那个进程中的 “问题线程”,最后根据线程堆栈信息找到问题代码。最后对代码进行排查。如何操作呢?通过 top 命令找到 CPU 消耗最高的进程,并记住进程 ID。再次...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- MySQL8.0.19开启GTID主从同步CentOS8
- Mario游戏-低调大师作品
- CentOS关闭SELinux安全模块
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Red5直播服务器,属于Java语言的直播服务器
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池