RocketMQ 5.x + Spring Boot 发送消息失败全解析

 更新时间:2026年02月13日 10:06:22   作者:堕落年代  
本文给大家介绍RocketMQ 5.x + Spring Boot 发送消息失败全解析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

从 gRPC 端口到 Topic 配置的完整踩坑实录

关键词:RocketMQ 5.x、Spring Boot、gRPC、Producer FAILED、No topic route info
适用版本:RocketMQ 5.3.x + rocketmq-client-java 5.x

一、问题背景

在使用 RocketMQ 5.3.3 搭配 Spring Boot 开发消息生产者时,服务启动正常、控制台可访问、Topic 也“看似”已经创建,但在真正发送消息时却频繁失败,典型报错如下:

Expected the service ProducerImpl-0 [FAILED] to be RUNNING

或:

No topic route info in name server for the topic: rewre

更让人困惑的是:

  • RocketMQ Console 可以正常访问
  • NameServer 和 Broker 都已启动
  • Topic 在控制台里“存在”
  • Producer 代码没有明显错误

但消息就是发不出去

本文将完整复盘这个问题,并给出 RocketMQ 5.x 下的正确使用姿势

二、RocketMQ 5.x 与 4.x 的本质差异(很多坑从这里开始)

1️⃣ 通信协议发生了根本变化

版本通信方式
RocketMQ 4.x自定义 TCP 协议
RocketMQ 5.xgRPC

👉 RocketMQ 5.x 的 Java Client 完全基于 gRPC

这意味着:

  • NameServer
  • Broker
  • Client(Producer / Consumer)

三者之间必须能通过 gRPC 端口通信

2️⃣ RocketMQ 5.x 新增的关键端口

RocketMQ 5.3.3 为例:

NameServer

端口作用
9876兼容旧协议(Console / Admin)
8081gRPC 端口(5.x Client 必须)

Broker

端口作用
10911旧协议
8080gRPC 端口(Producer / Consumer 真正使用)

⚠️ 如果只暴露 9876 / 10911,而没暴露 8081 / 8080:

  • Console 能用
  • Topic 能看
  • Producer 一发消息就失败

三、问题一:Producer FAILED —— 实际是 gRPC 不通

典型异常

org.apache.rocketmq.shaded.io.grpc.StatusRuntimeException:
UNAVAILABLE: Network closed for unknown reason

本质原因

RocketMQ 5.x Client 通过 gRPC 连接 Broker,但 Broker 的 gRPC 端口未暴露或不可达

解决方式

在 Docker / 容器环境中,必须显式暴露 gRPC 端口

# NameServer
ports:
  - "9876:9876"
  - "8081:8081"
# Broker
ports:
  - "10911:10911"
  - "8080:8080"

四、问题二:No topic route info —— 真正的大坑

在 gRPC 问题解决后,紧接着会遇到第二个错误:

No topic route info in name server for the topic: rewre

表面含义

NameServer 中没有该 Topic 的路由信息

但问题并不只是“没建 topic”这么简单

五、致命配置错误:Producer 默认 Topic + 代码显式 Topic 混用

1️⃣ 错误示例(问题根源)

rocketmq:
  producer:
    endpoints: 127.0.0.1:8081
    group: dromara-producer-group
    topic: rewre   # ❌ Producer 级别默认 topic
demo:
  rocketmq:
    normal-topic: normal-topic
rocketMQClientTemplate.syncSendNormalMessage(normalTopic, message);

日志打印的是:

发送普通消息到主题: normal-topic

但异常却是:

No topic route info for topic: rewre

2️⃣ 为什么会这样?

这是 RocketMQ 5.x Client 的一个“隐式行为”

如果在 rocketmq.producer.topic 中配置了 topic,
Producer 初始化和首次发送时,会优先拉取该 topic 的路由信息

即使你在 send() 时传入了别的 topic:

syncSendNormalMessage("normal-topic", ...)

👉 Client 仍然会先去 NameServer 查询 rewre 的路由

如果 rewre 不存在:

40402 No topic route info

六、正确姿势:两种方案,只能选一种

✅ 方案一(强烈推荐):删除 Producer 默认 topic

正确配置

rocketmq:
  producer:
    endpoints: 127.0.0.1:8081
    group: dromara-producer-group
    timeout: 10000
    max-retry-times: 2
    enable-ssl: false

Topic 全部由代码控制

syncSendNormalMessage(normalTopic, message);
syncSendDelayMessage(delayTopic, message);
syncSendFifoMessage(fifoTopic, message);

手动创建 topic(必须)

mqadmin updatetopic -n rmqnamesrv:9876 -c DefaultCluster -t normal-topic

👉 这是官方示例和生产环境最推荐的方式

⚠️ 方案二(不推荐):只使用一个固定 topic

如果配置了:

rocketmq:
  producer:
    topic: rewre

那么你必须:

  • 代码中 只能发 rewre
  • NameServer 中 必须存在 rewre
syncSendNormalMessage("rewre", message);

❌ 不适合多 topic、延时、事务、顺序消息场景

七、RocketMQ 5.x 的几个重要认知纠正

1️⃣ RocketMQ 5.x不会自动创建 Topic

和 4.x 不同:

Topic 必须提前创建,否则必定 40402

2️⃣ Console 看到 ≠ Client 能用

  • Console / mqadmin:走旧协议
  • Producer / Consumer:走 gRPC

👉 两个世界

3️⃣ 日志不一定可信,异常才是真相

日志打印 topic ≠ Client 实际拉取路由的 topic

八、最终 Checklist(上线前必查)

  • NameServer 暴露 8081
  • Broker 暴露 8080
  • 使用 rocketmq-client-java 5.x
  • 未配置 rocketmq.producer.topic
  • 所有 topic 已通过 mqadmin updatetopic 创建
  • Producer group 唯一

九、总结

RocketMQ 5.x 并不是“不能用”,
而是 思维模型已经完全不同于 4.x

真正的三大坑只有:

  1. gRPC 端口
  2. Topic 不自动创建
  3. Producer 默认 topic 与 send topic 混用

只要理解了这三点,
RocketMQ 5.x + Spring Boot 会非常稳定、清晰、现代化。

你这次踩的坑,非常值得被更多人看到

到此这篇关于RocketMQ 5.x + Spring Boot 发送消息失败全解析的文章就介绍到这了,更多相关RocketMQ 5.x Spring Boot 发送消息失败内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java实现字符串的分割(基于String.split()方法)

    Java实现字符串的分割(基于String.split()方法)

    Java中的我们可以利用split把字符串按照指定的分割符进行分割,然后返回字符串数组,下面这篇文章主要给大家介绍了关于Java实现字符串的分割的相关资料,是基于jDK1.8版本中的String.split()方法,需要的朋友可以参考下
    2022-09-09
  • SpringBoot中使用MongoDB的连接池配置全过程

    SpringBoot中使用MongoDB的连接池配置全过程

    这篇文章主要介绍了SpringBoot中使用MongoDB的连接池配置全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-06-06
  • Springboot2.7+Minio8 实现大文件分片上传

    Springboot2.7+Minio8 实现大文件分片上传

    本文主要介绍了Springboot2.7+Minio8 实现大文件分片上传,通过文件切片上传,我们能够提高文件上传的速度,优化用户体验,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • 使用Spring Boot快速构建一个简单的文件处理工具

    使用Spring Boot快速构建一个简单的文件处理工具

    在现代Web应用中,文件上传与处理是常见的需求,本文将通过一个实际案例,详细介绍如何使用Spring Boot构建一个文件处理工具,感兴趣的小伙伴可以参考一下
    2025-06-06
  • Spring AOP在web应用中的使用方法实例

    Spring AOP在web应用中的使用方法实例

    这篇文章主要给大家介绍了关于Spring AOP在web应用中的使用方法,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring AOP具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-12-12
  • Java实现贪吃蛇游戏

    Java实现贪吃蛇游戏

    这篇文章主要为大家详细介绍了Java实现贪吃蛇游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • 策略模式:告别if else

    策略模式:告别if else

    你是不是还在写着大量的if else语句,if else 不仅难以维护不易扩展,而且使代码臃肿不堪,想不想让你的业务代码更加的健壮,更易扩展,那你一定要学一学今天的主角策略模式
    2021-06-06
  • idea提交文件时如何忽略某些文件的提交

    idea提交文件时如何忽略某些文件的提交

    这篇文章主要介绍了idea提交文件时如何忽略某些文件的提交问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • Java中的@Async异步功能详解

    Java中的@Async异步功能详解

    这篇文章主要介绍了Java中的@Async异步功能详解,@Async注解,可以实现异步处理的功能,它可以有返回值,或者直接在新线程时并行执行一个任务,对于异步来说,它的执行是有条件的,你需要把异步代码块放在单独的类里,需要的朋友可以参考下
    2023-11-11
  • 使用spring oauth2框架获取当前登录用户信息的实现代码

    使用spring oauth2框架获取当前登录用户信息的实现代码

    这篇文章主要介绍了使用spring oauth2框架获取当前登录用户信息的实现代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07

最新评论