贞炸了!上线之后,消息收不到了!
hello,各位小伙伴们,上午好~
昨晚生产系统机房切换,又度过了一个不眠之夜。趁着这段无聊时间,分享一下前一段时间 RocketMQ 踩坑经历
欢迎关注我的公众号:程序通事,获得日常干货推送。如果您对我的专题内容感兴趣,也可以关注我的博客:studyidea.cn
前言
事情是这样的,前端时间我们有个新业务上线,这个业务需要监听支付成功的 mq 消息,然后向绑定的音箱推送消息。这样用户在支付完成之后,商家端就就可以收到收款播报。
起初我们在测试环境的测试的时候,一切流程非常顺利,没有任何问题。但是等到我们发布上线之后,却出现了问题。
一笔支付成功之后,音箱没有发出收款成功的播报。一切流程排查下来之后,这才发现原来 MQ 消费端没有正常在消费消息。
开始排查问题,第一想到的是消费端是不是发布失败了,但是查看相关日志,并没有任何异常。
登录 MQ 控制台,尝试手动重新发布消息,神奇的事来了,消费端成功收到消息。
总结现在的问题,下文开始排查。
- MQ 消费端应用没有异常,但是无法正常消费
- MQ 控制台发送消息,消费端可以成功消费消息
排查问题
刚开始排查的时候,由于没有任何异常业务日志可以定位问题,所以问题排查起来十分困难。
排查了两天了,想过各种问题。比如当前消费端使用 RocketMQ 客户端版本比较高,是不是版本兼容性导致的问题呢?
于是降低消费端的版本,重新发布之后,问题依然存在。
没办法,只好使用 Google 大法了。
通过搜索发现,原来默认情况下 rockmq 客户端的日志将会单独打印输出,日志文件位置如下:
${user.home}/logs/rocketmqlogs
下图为当时的日志截图:
可以看到消费端尝试连接一个 20878 的端口,但是由于网络问题,一直连接失败。
那这个 20878 是什么端口?
我们并没有主动配置这个端口,但是 rocketmq broker 配置的端口为 20880。
搜索发现,原来 rocketmq broker 默认将会启动三个通讯端口:
第一个是 rocketmq broker 配置文件上配置的端口,默认端口为 10911,这里我们修改成了 20880。
第二个是 rockemq broker vip 通道端口,这个端口将会在第一个端口基础上减 2,即 20878。
第三个是 rockemq broker 用户主从数据同步的端口,这个端口将会在第一个端口基础上加 1,即 20881。
大概知道问题,解决办法就很简单了,要么防火墙打开 29878 网络端口的限制,要么关闭使用 vip 端口。
RocketMQ 客户端提供两种方式关闭使用 vip 端口。
- 代码主动禁止使用 vip 端口,配置如下:
## 消费端
DefaultMQPushConsumer#setVipChannelEnabled(false)
## 生产端
DefaultMQProducer#setVipChannelEnabled(false);
- 设置 JVM 参数,禁用 vip 端口
-Dcom.rocketmq.sendMessageWithVIPChannel=false
源码分析
虽然问题解决了,但是上述问题本质原因还没有找到。所以这次我们就从源码出发,追本溯源。
为什么 vip 端口网络不通将会导致消费者不能正常消费?
从 rocketmq 错误日志,我们可以看到报错代码位于 RebalanceService
类中。
这里主要用来执行 topic Rebalance(重平衡)。
首先我们来了解一下,Rebalance
目的是为什么了。
假设当前 rocketmq broker 端存在一个 topic ,拥有四个队列,关系如下:
此时如果有一个消费者使用集群模式消费消息,那么它将需要负责消费所有队列中的消息。
当我们再增加一个消费者消费消息时,此时消费端将会自动进行重平衡,默认情况下将会使用平均分配原则。
可以看到 Rebalance
机制可以提升的消息的并行处理机制。
rocketmq 消费端启动时竟会触发 Rebalance
机制。接着,我们根据源码主要看下 Rebalance
主流程,代码位于RebalanceImpl#rebalanceByTopic
。
通常我们使用集群消费模式,所以这里主要看集群模式下 Rebalance
过程。
上述代码整体流程如下:
- 首先获取 Rebalance 过程所需元数据,包括 Topic 下的队列信息集合以及消费者组下的消费者实例 id 信息集合
- 两者都存在的情况下,将会按照一定策略将队列信息分配给每个消费者,默认按照
AllocateMessageQueueAveragely
,即平均分配原则 - 将预分配结果尝试更新
ProcessQueue Table
,如果有更新将会把新的队列在加入异步消费流程。
后续消息流程就不看源码,比较复杂,网上找了一张消息消费流程图:
可以看到,由于网络端口问题,无法正常获取所有消费者 ID 集合,这就导致无法正常分配队列信息。
List<String> cidAll = this.mQClientFactory.findConsumerIdList(topic, consumerGroup);
由于未被分配任一队列,消费端程序也就业务无法正常拉取消息。
为什么 mq 控制台重新发送的消息消费者可以收到?
rocketmq 控制台重新发送消息代码如下:
MessageService
将会把消息的元数据封装一个CONSUME_MESSAGE_DIRECTLY
类型的请求,接着调用 rocketmq 提供的 admin API,给 rocketmq broker 发送请求。
broker 端收到请求之后,将会查询消息,然后再向消费端发起 CONSUME_MESSAGE_DIRECTLY
请求。消费端接受到消息请求之后,将会直接消息这条消息。
为什么 broker 将会启动两个端口?
rocketmq broker 虽然启动了两个端口,但是从 rocketmq broker 的源码可以发现这两个端口启动之后起到作用是一样的。
那为什么开启两个监听端口那?我想很多同学应该也有这个疑惑,这里给出一个开发者解释答案。
https://github.com/apache/rocketmq/issues/1510
普通的端口将会承载所有消息网络请求,如果此时请求非常繁忙,broker 端的所有 I/O 线程可能都在执行请求,这就会导致后续网络请求进入队列,从而导致消息请求执行缓慢。
这对于生产者来说,可能是一个致命的问题,因为消息生产者通常消息发送延时要低。
这种情况下,我们就可以将消息发送到 VIP 端口,从而降低消息发送的延时。
默认情况下,rocketmq 客户端的 vipChannel
配置为 true
。
private boolean vipChannelEnabled = Boolean.parseBoolean(System.getProperty(SEND_MESSAGE_WITH_VIP_CHANNEL_PROPERTY, "true"));
生产者的发送消息,消费者获取元数据信息等请求默认将会使用 vip
端口。
不过这里需要注意一点,消费者拉取消息,将不会使用vip
端口。
虽然这个设计很巧妙,但是说实话个人觉得这个配置权限应该交给开发者自己去配置,而不是默认开启。
因为不熟悉的情况下还是很容易踩坑的,默认情况下,大家应该只熟悉 9876 与 10911 这两个端口。
rocketmq 4.5.1 版本之后,vipChannel
配置被修改为 false
,这时是否使用 vip 端口真正交给开发者自己
如果此时想开启,需要主动 API 参数,或者 JVM 参数增加 -Dcom.rocketmq.sendMessageWithVIPChannel=true
总结
今天的问题主要由于 VIP 端口无法连接,从而导致消费端无法正常消费消息。虽然最后的解决办法非常简单,但是这个排查过程真的很难。
我们平常在使用 rocketmq 过程中,通常只要设置 nameserver 的配置即可, broker 等地址信息将会自动从 nameserver 获取。这就间接导致了,我们可能只了解 9876 这个端口。
生产环境由于网络安全问题,一般不会开放全部的端口。所以,我们在使用 rocketmq 的过程,需要了解以下四个端口,分别为(默认配置):
- 9876:nameserver 监听端口
- 10911: broker 监听端口
- 10909:broker vip 监听端口
- 10912:broker HA 端口,用于主从同步
生产使用 rocketmq 过程,如果碰到诡问题,不妨尝试 telnet 看下网关连通性。另外还可以通过查看 rocketmq 自身日志,确定问题,日志位置位于:
${user.home}/logs/rocketmqlogs
好了,今天文章就到这里。我是楼下小黑哥,你知道的越多,你不知道的就越多。
下周见~
欢迎关注我的公众号:程序通事,获得日常干货推送。如果您对我的专题内容感兴趣,也可以关注我的博客:studyidea.cn
贞炸了!上线之后,消息收不到了!相关推荐
- 三大运营商将上线 5G 消息;苹果谷歌联手,追踪 30 亿用户;jQuery 3.5.0 发布 | 极客头条...
整理 | 屠敏 头图 | CSDN 下载自东方 IC 快来收听极客头条音频版吧,智能播报由标贝科技提供技术支持. 「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦 ...
- 苹果官网下架iPhone 8;破解百度网盘的Pandownload开发者被捕;三大运营商年内上线5G消息 | EA周报...
EA周报 2020年4月17日 每个星期7分钟,元宝带你喝一杯IT人的浓缩咖啡,了解天下事.掌握IT核心技术. 热点大事件 谷歌收紧游戏商店规则,要求开发者提供免费试用细节 谷歌宣布了一系列政策调整, ...
- 用CSocket重写OnReceive()之后,出现消息收不到的情况
winsock实验,多人聊天室,遇到消息收不到的情况 原先代码: void CCSocket::OnReceive(int nErrorCode) { // TODO: 在此添加专用代码和/或 ...
- Rabbit-用户上线接收消息
application-dev.yml spring:rabbitmq:username: adminpassword: adminhost: 192.168.0.45port: 5672 消费者实现 ...
- python微信验证码收不到_给微信回复消息收不到(Python)
服务器搭在SAE上 解析XML部分用了lxml 这部分代码: def POST(self): str_xml = web.data() xml = etree.fromstring(str_xml) ...
- 线上线下一体化趋势下,零售品牌如何利用线上营销为营收赋能?
电商网店会分流线下营收?线上营销对线下门店营收毫无正面影响?如果零售企业依旧固守不前,线上线下营运割裂甚至彼此牵制,必然对营收造成负面影响.在线上线下一体化趋势下,品牌实践中却总有各种现实问题导致协同 ...
- qq群发信息显示服务器检测到,关于如何突破QQ群发消息屏蔽或限制经验总结
文章导读:本文主要介绍关于如何突破QQ群发消息屏蔽或限制经验总结 ,包括:WebQQ发送消息很多人反映说消息收不到啊,发布多久就屏蔽了.其实我还是那句老话.当你短时间在同一个IP段之内发送这么多消息, ...
- 阿里巴巴旗下平台口碑推出无人收银技术,改造便利店市场;重庆法院运用 AI 探索“智能判案”...
阿里巴巴旗下平台口碑推出无人收银技术,改造便利店市场 雷锋网消息 阿里巴巴旗下本地生活服务平台口碑今日宣布在上海新兴便利店品牌24鲜上线无人收银技术.消费者只要打开支付宝,扫一扫想要购买的商品的条形码 ...
- 小程序 订阅消息 原来就是如此
前言 只有光头才能变强. 文本已收录至我的GitHub精选文章,欢迎Star:https://github.com/ZhongFuCheng3y/3y 如果近期有看我文章的同学,会知道我最近在公司做的 ...
- 上线两周后 腾讯吃鸡手游和平精英怎么样了
和平精英5月8日正式上市后,引发众媒体和用户热议,新浪财经,华尔街见闻都曾报道,和平精英更是登上了新浪微博的首页.两周过去,和平精英的表现到底如何了?上市之前,开发和平精英的游戏厂商腾讯股价连续四天上 ...
最新文章
- Android NDK开发之旅29 云服务器Ubuntu下搭建NDK环境,并编译FFmpeg
- 资源 | 阿里发布免费深度学习课程:感知机梳理(附链接)
- 平民软件OneProxy的强大
- 小工匠聊架构- 提升性能的大杀器之缓存技术
- C语言试题五十二之学生的记录由学号和成绩组称个,n名大学生得数据已在主函数中放入结构体数组a中,请编写函数fun,它的功能时:按分数的高低排列学生的记录,高分在前。
- 爬出数据标注陷阱,半监督学习模型暗藏多少玄机?
- vue瀑布流demo_面试加分企业级Vue瀑布流
- 【从0到1,搭建Spring Boot+RESTful API+Shiro+Mybatis+SQLServer权限系统】04、统一处理异常...
- 擅长排列的小明(nyoj19)
- bat获取当前文件夹路径
- bzoj 3672 购票 点分治+dp
- 考研数据结构常考的代码题总结 C语言实现
- 你值得拥有的Mac PS滤镜插件和特效处理软件合集,不要错过!
- IPV6的福音---六维空间
- WBS:工作分解结构(Work Breakdown Structure)
- Error: Network Error
- 低碳生活进行时!国产“芯”RK3568创造智慧出行新体验
- 基于JSP+SSH的在线租车汽车租赁系统
- java String工具类/字符串工具类 StringUtil
- 要求实现符号函数sign(x)。
热门文章
- JavaScript表单编程
- syntax error near unexpected token `then'
- HTTP Error 404 - File or Directory not found caused by ISAPI filter of Sharepoint
- Answers To The Questions from GiGabyte
- 孙鑫VC学习笔记:第十五讲 (二) 线程创建方法
- 孙鑫VC学习笔记:第四讲 MFC消息映射机制和CDC类的使用
- mysql node 可视化_使用Prometheus进行Substrate节点可视化监控
- 拓端tecdat|Python风险价值计算投资组合VaR(Value at Risk )、期望损失ES(Expected Shortfall)
- 拓端tecdat|R语言多项式回归拟合非线性关系
- 拓端tecdat|WINBUGS对随机波动率模型进行贝叶斯估计与比较