RocketMQ 5.x + Spring Boot 發(fā)送消息失敗全解析
從 gRPC 端口到 Topic 配置的完整踩坑實(shí)錄
關(guān)鍵詞:RocketMQ 5.x、Spring Boot、gRPC、Producer FAILED、No topic route info
適用版本:RocketMQ 5.3.x + rocketmq-client-java 5.x
一、問(wèn)題背景
在使用 RocketMQ 5.3.3 搭配 Spring Boot 開(kāi)發(fā)消息生產(chǎn)者時(shí),服務(wù)啟動(dòng)正常、控制臺(tái)可訪問(wèn)、Topic 也“看似”已經(jīng)創(chuàng)建,但在真正發(fā)送消息時(shí)卻頻繁失敗,典型報(bào)錯(cuò)如下:
Expected the service ProducerImpl-0 [FAILED] to be RUNNING
或:
No topic route info in name server for the topic: rewre
更讓人困惑的是:
- RocketMQ Console 可以正常訪問(wèn)
- NameServer 和 Broker 都已啟動(dòng)
- Topic 在控制臺(tái)里“存在”
- Producer 代碼沒(méi)有明顯錯(cuò)誤
但消息就是發(fā)不出去。
本文將完整復(fù)盤這個(gè)問(wèn)題,并給出 RocketMQ 5.x 下的正確使用姿勢(shì)。
二、RocketMQ 5.x 與 4.x 的本質(zhì)差異(很多坑從這里開(kāi)始)
1?? 通信協(xié)議發(fā)生了根本變化
| 版本 | 通信方式 |
|---|---|
| RocketMQ 4.x | 自定義 TCP 協(xié)議 |
| RocketMQ 5.x | gRPC |
?? RocketMQ 5.x 的 Java Client 完全基于 gRPC
這意味著:
- NameServer
- Broker
- Client(Producer / Consumer)
三者之間必須能通過(guò) gRPC 端口通信
2?? RocketMQ 5.x 新增的關(guān)鍵端口
以 RocketMQ 5.3.3 為例:
NameServer
| 端口 | 作用 |
|---|---|
| 9876 | 兼容舊協(xié)議(Console / Admin) |
| 8081 | ? gRPC 端口(5.x Client 必須) |
Broker
| 端口 | 作用 |
|---|---|
| 10911 | 舊協(xié)議 |
| 8080 | ? gRPC 端口(Producer / Consumer 真正使用) |
?? 如果只暴露 9876 / 10911,而沒(méi)暴露 8081 / 8080:
- Console 能用
- Topic 能看
- Producer 一發(fā)消息就失敗
三、問(wèn)題一:Producer FAILED —— 實(shí)際是 gRPC 不通
典型異常
org.apache.rocketmq.shaded.io.grpc.StatusRuntimeException: UNAVAILABLE: Network closed for unknown reason
本質(zhì)原因
RocketMQ 5.x Client 通過(guò) gRPC 連接 Broker,但 Broker 的 gRPC 端口未暴露或不可達(dá)
解決方式
在 Docker / 容器環(huán)境中,必須顯式暴露 gRPC 端口:
# NameServer ports: - "9876:9876" - "8081:8081" # Broker ports: - "10911:10911" - "8080:8080"
四、問(wèn)題二:No topic route info —— 真正的大坑
在 gRPC 問(wèn)題解決后,緊接著會(huì)遇到第二個(gè)錯(cuò)誤:
No topic route info in name server for the topic: rewre
表面含義
NameServer 中沒(méi)有該 Topic 的路由信息
但問(wèn)題并不只是“沒(méi)建 topic”這么簡(jiǎn)單。
五、致命配置錯(cuò)誤:Producer 默認(rèn) Topic + 代碼顯式 Topic 混用
1?? 錯(cuò)誤示例(問(wèn)題根源)
rocketmq:
producer:
endpoints: 127.0.0.1:8081
group: dromara-producer-group
topic: rewre # ? Producer 級(jí)別默認(rèn) topicdemo:
rocketmq:
normal-topic: normal-topicrocketMQClientTemplate.syncSendNormalMessage(normalTopic, message);
日志打印的是:
發(fā)送普通消息到主題: normal-topic
但異常卻是:
No topic route info for topic: rewre
2?? 為什么會(huì)這樣?
這是 RocketMQ 5.x Client 的一個(gè)“隱式行為”:
如果在
rocketmq.producer.topic中配置了 topic,
Producer 初始化和首次發(fā)送時(shí),會(huì)優(yōu)先拉取該 topic 的路由信息
即使你在 send() 時(shí)傳入了別的 topic:
syncSendNormalMessage("normal-topic", ...)
?? Client 仍然會(huì)先去 NameServer 查詢 rewre 的路由
如果 rewre 不存在:
40402 No topic route info
六、正確姿勢(shì):兩種方案,只能選一種
? 方案一(強(qiáng)烈推薦):刪除 Producer 默認(rèn) topic
正確配置
rocketmq:
producer:
endpoints: 127.0.0.1:8081
group: dromara-producer-group
timeout: 10000
max-retry-times: 2
enable-ssl: falseTopic 全部由代碼控制
syncSendNormalMessage(normalTopic, message); syncSendDelayMessage(delayTopic, message); syncSendFifoMessage(fifoTopic, message);
手動(dòng)創(chuàng)建 topic(必須)
mqadmin updatetopic -n rmqnamesrv:9876 -c DefaultCluster -t normal-topic
?? 這是官方示例和生產(chǎn)環(huán)境最推薦的方式
?? 方案二(不推薦):只使用一個(gè)固定 topic
如果配置了:
rocketmq:
producer:
topic: rewre那么你必須:
- 代碼中 只能發(fā)
rewre - NameServer 中 必須存在
rewre
syncSendNormalMessage("rewre", message);? 不適合多 topic、延時(shí)、事務(wù)、順序消息場(chǎng)景
七、RocketMQ 5.x 的幾個(gè)重要認(rèn)知糾正
1?? RocketMQ 5.x不會(huì)自動(dòng)創(chuàng)建 Topic
和 4.x 不同:
Topic 必須提前創(chuàng)建,否則必定 40402
2?? Console 看到 ≠ Client 能用
- Console / mqadmin:走舊協(xié)議
- Producer / Consumer:走 gRPC
?? 兩個(gè)世界
3?? 日志不一定可信,異常才是真相
日志打印 topic ≠ Client 實(shí)際拉取路由的 topic
八、最終 Checklist(上線前必查)
- NameServer 暴露 8081
- Broker 暴露 8080
- 使用 rocketmq-client-java 5.x
- 未配置
rocketmq.producer.topic - 所有 topic 已通過(guò)
mqadmin updatetopic創(chuàng)建 - Producer group 唯一
九、總結(jié)
RocketMQ 5.x 并不是“不能用”,
而是 思維模型已經(jīng)完全不同于 4.x。
真正的三大坑只有:
- gRPC 端口
- Topic 不自動(dòng)創(chuàng)建
- Producer 默認(rèn) topic 與 send topic 混用
只要理解了這三點(diǎn),
RocketMQ 5.x + Spring Boot 會(huì)非常穩(wěn)定、清晰、現(xiàn)代化。
你這次踩的坑,非常值得被更多人看到。
到此這篇關(guān)于RocketMQ 5.x + Spring Boot 發(fā)送消息失敗全解析的文章就介紹到這了,更多相關(guān)RocketMQ 5.x Spring Boot 發(fā)送消息失敗內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MyBatis模糊查詢報(bào)錯(cuò):ParserException: not supported.pos&n
本文主要介紹了MyBatis模糊查詢報(bào)錯(cuò):ParserException: not supported.pos 問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-04-04
Mybatis基于MapperScan注解的動(dòng)態(tài)代理加載機(jī)制詳解
這篇文章主要介紹了Mybatis基于MapperScan注解的動(dòng)態(tài)代理加載機(jī)制,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-01-01
Java讀取json數(shù)據(jù)并存入數(shù)據(jù)庫(kù)的操作代碼
很多朋友問(wèn)大佬們JAVA怎么把json存入數(shù)據(jù)庫(kù)啊,這一問(wèn)題就把我難倒了,糾結(jié)如何操作呢,下面小編把我的經(jīng)驗(yàn)分享給大家,感興趣的朋友一起看看吧2021-08-08
IDEA如何導(dǎo)入多個(gè)Maven項(xiàng)目到同個(gè)目錄
在IDEA中使用微服務(wù)架構(gòu)時(shí),可以通過(guò)以下步驟在一個(gè)窗口中打開(kāi)和運(yùn)行多個(gè)服務(wù):打開(kāi)父級(jí)目錄,點(diǎn)擊右側(cè)的Maven菜單,點(diǎn)擊+按鈕,逐一選中并添加每個(gè)服務(wù)的pom.xml文件,完成后,可以在同一個(gè)窗口中看到并運(yùn)行所有添加的服務(wù)2026-02-02
SpringBoot啟動(dòng)后執(zhí)行方法的五種實(shí)現(xiàn)方式
本文介紹了SpringBoot中五種在項(xiàng)目啟動(dòng)后執(zhí)行方法的方式,包括實(shí)現(xiàn)CommandLineRunner和ApplicationRunner接口、實(shí)現(xiàn)ApplicationListener接口、使用@PostConstruct注解以及實(shí)現(xiàn)InitializingBean接口,每種方式都有其特點(diǎn)和適用場(chǎng)景2025-02-02
springboot項(xiàng)目配置swagger2示例詳解
Swagger是一款RESTful接口的文檔在線自動(dòng)生成、功能測(cè)試功能框架。本文重點(diǎn)給大家介紹springboot項(xiàng)目配置swagger2示例代碼詳解,需要的朋友參考下吧2021-09-09
Java timezone設(shè)置和mybatis連接數(shù)據(jù)庫(kù)時(shí)區(qū)設(shè)置方式
這篇文章主要介紹了Java timezone設(shè)置和mybatis連接數(shù)據(jù)庫(kù)時(shí)區(qū)設(shè)置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
如何在Maven項(xiàng)目配置pom.xml指定JDK版本和編碼
maven是個(gè)項(xiàng)目管理工具,如果我們不告訴它要使用什么樣的jdk版本編譯,它就會(huì)用maven-compiler-plugin默認(rèn)的jdk版本來(lái)處理,這樣就容易出現(xiàn)版本不匹配的問(wèn)題,這篇文章主要給大家介紹了關(guān)于如何在Maven項(xiàng)目配置pom.xml指定JDK版本和編碼的相關(guān)資料,需要的朋友可以參考下2024-01-01

