前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >RocketMQ生产问题一般如何排查?

RocketMQ生产问题一般如何排查?

原创
作者头像
小伟
修改2023-03-03 17:45:29
1.6K0
修改2023-03-03 17:45:29
举报
文章被收录于专栏:魔都程序缘魔都程序缘

RocketMQ架构来看,用户在使用客户端生产时时不时会遇到一些问题,这里做了一些总结,大家参考

初始化生产者实例报错

在使用rocketmq spring boot starter或者rocketmq client时,很容易创建多个相同实例或者同一个实例启动多次,导致出现以下报错:

第一个可能出现的问题: The producer service state not OK, maybe started once, RUNNING

代码语言:txt
复制
Exception in thread "main" org.apache.rocketmq.client.exception.MQClientException: The producer service state not OK, maybe started once, RUNNING
See https://rocketmq.apache.org/docs/bestPractice/06FAQ for further details.
	at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.start(DefaultMQProducerImpl.java:251)
	at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.start(DefaultMQProducerImpl.java:212)
	at org.apache.rocketmq.client.producer.DefaultMQProducer.start(DefaultMQProducer.java:299)
	at org.apache.rocketmq.example.simple.Producer.main(Producer.java:38)

排查分析:一般这种是同一个实例调用了多次start方法导致的。在spring中,需要排查在初始化bean时是否主动调用了多次start方法、是否spring和自己的代码都调用了start。spring可以显示调用,也可以注册bean的初始化方法。

具体逻辑可以参看Producer启动代码:

第二个可能出现的问题:The producer service state not OK, maybe started once, SHUTDOWN_ALREADY

代码语言:txt
复制
Exception in thread "main" org.apache.rocketmq.client.exception.MQClientException: The producer service state not OK, maybe started once, SHUTDOWN_ALREADY
See https://rocketmq.apache.org/docs/bestPractice/06FAQ for further details.
	at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.start(DefaultMQProducerImpl.java:251)
	at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.start(DefaultMQProducerImpl.java:212)
	at org.apache.rocketmq.client.producer.DefaultMQProducer.start(DefaultMQProducer.java:299)
	at org.apache.rocketmq.example.simple.Producer.main(Producer.java:41)
Disconnected from the target VM, address: '127.0.0.1:51268', transport: 'socket'

排查分析:一般这种原因是调用了shutdown方法后,又调用了start。

一般我们惯性思维觉得是没问题的,其实rocketmq中producer和consumer的初始化过程是:初始化+ start、shutdown。所以shutdown后需要初始化+start,初始化过程只有在新建实例的时候才做。

一般可以复用相同producer实例,或者shutdown后再使用时new新实例。在一些流计算的算子中,可能会使用new新实例的方式。

代码参看

对于上面的代码我们简要解释下: 每个RocketMQ客户端进程会拥有一个MQClientInstance实例并且是单例,每个单例里面保存了这个客户端的全部生产者,也就是第二个图中的producerTable,如果有重复的生产者注册进来会注册失败。

topic路由信息获取不到: No topic route info in name server for the topic: XXXX

客户端发送获取路由,发送消息的流程图如下:

RocketMQ通信架构图
RocketMQ通信架构图

生产者发送消息的步骤可以简单分为:

  • 启动生产者,启动路由定时更新检查线程, 检查缓存topicPublishInfoTable中的topic的路由信息是否变化
  • 用户第一次调用生产者send方法,send方法内部查询topicPublishInfoTable缓存,发现没有路由,立即调用tryToFindTopicPublishInfo方法获取topic的路由,保存到topicPublishInfoTable,发送消息。
  • 用户第二次调用生产者send方法,send方法内部查询topicPublishInfoTable缓存,发现存在路由,立即发送消息。

注意:topicPublishInfoTable可以认为是最新的路由信息。topicPublishInfoTable中的路由信息由路由定时更新检查线程定时检查维护, 如果namesrv有最新的路由,它会更新topicPublishInfoTable。

有了以上知识,我们看可能遇到的问题。

topic不存在或者路由信息获取不到

获取到的路由信息为空, 客户端会报错,可能topic没有创建,导致没有获取到topic信息。可能topic创建的时候通知Namesrv失败了, Namesrv没有保存这个topic的路由信息,查询也就返回空。

这种情况新建topic或者删除新建, 实在不行重启namesrv后,再删除新建。

这个逻辑可以追溯到Namesrv的查询路由信息的代码说起:

Namesrv查询路由的代码如下:

image.png
image.png

Namesrv内存中的路由信息从架构图可以看出时Broker定期上报的,如果没有上报或者压根儿没有这个topic,topic路由不存在就是预期内的。

发送消息失败,如上图中03到02。

原因很多, 这里例举常见的问题:

  • 客户端访问Broker网络不通 这种情况客户端处理不了,最好找服务维护人员
  • 发送到Broker报错 可能的问题和分析处理:在确定可以ping通Broker后,一般Broker报错会有错误信息,比如超时、broker磁盘满、broker同步slave失败等,需要根据返回的错误信息排查Broker代码。 这时把本地~/logs/rocketmqlogs/rocketmq_client.log和返回报错信息准备好,丢给运维rocketmq的同学吧。

以上是生产报错, 下一篇我们分享消费失败的问题排查方式。

生产耗时比较大怎么定位?

https://cloud.tencent.com/developer/article/2192667

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 初始化生产者实例报错
    • 第一个可能出现的问题: The producer service state not OK, maybe started once, RUNNING
      • 第二个可能出现的问题:The producer service state not OK, maybe started once, SHUTDOWN_ALREADY
      • topic路由信息获取不到: No topic route info in name server for the topic: XXXX
        • topic不存在或者路由信息获取不到
          • 发送消息失败,如上图中03到02。
          • 生产耗时比较大怎么定位?
          相关产品与服务
          消息队列 RocketMQ 版
          消息队列 RocketMQ 版(TDMQ for RocketMQ,简称TDMQ RocketMQ 版) 是一款分布式高可用的消息队列服务,基于 Apache RocketMQ 的 4.x 和 5.x 架构提供不同的产品形态,支持开源客户端零改造接入,同时具备计算存储分离,灵活扩缩容的优势。TDMQ RocketMQ 版可以支持百万级 TPS 的吞吐量,适用于各类大规模、低延时、对可靠性要求高的在线消息业务场景。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档