细说RocketMQ双网卡问题

文章目录

    • [一、 为什么会出现"双网卡问题"?](#一、 为什么会出现“双网卡问题”?)
      • [关键冲突点:Broker 汇报了错误的"身份证"](#关键冲突点:Broker 汇报了错误的“身份证”)
    • [二、 核心症状(怎么判断自己踩坑了?)](#二、 核心症状(怎么判断自己踩坑了?))
    • [三、 完美解决方案](#三、 完美解决方案)
      • [方案 A:如果是原生安装(修改 `broker.conf`)](#方案 A:如果是原生安装(修改 broker.conf))
      • [方案 B:如果是 Docker / Docker Compose 安装(最推荐)](#方案 B:如果是 Docker / Docker Compose 安装(最推荐))
    • [四、 必须要放行的"云服务器安全组"端口](#四、 必须要放行的“云服务器安全组”端口)

在分布式中间件(如 RocketMQ、Kafka 等)的部署中,"双网卡问题" (或者叫内外网隔离、多网络接口问题)是把中间件部署在远端云服务器,而本地 Spring Boot 去连接时最经典、最容易让人抓狂的坑

它的核心表现通常是:明明 Nacos 能连上,RocketMQ 的 Namesrv 也能连上,但一发送消息或者消费消息就直接报超时(Timeout)或连接拒绝(Connection Refused)。

下面我们用最通俗的语言,彻底拆解这个问题的底层原理和解决方案。


一、 为什么会出现"双网卡问题"?

在阿里云等云服务器(ECS)上,通常存在两块"虚拟网卡":

  1. 内网网卡(Private IP): 比如 172.19.xx.xx。这是云厂商机房内部通信用的,速度极快(内网千兆/万兆),且不花流量费。
  2. 公网网卡(Public IP): 比如 47.98.xx.xx。这是暴露给互联网的,你本地电脑连接服务器、以及用户访问网站都走这个 IP。

关键冲突点:Broker 汇报了错误的"身份证"

RocketMQ 的架构是:NameServer(注册中心) 负责管理路由,Broker(数据节点) 负责真正存取消息。

  1. 默认情况: 当你在云服务器上启动 RocketMQ Broker 时,它默认会去抓取服务器的内网 IP(因为在服务器看来,内网网卡才是它的主网卡)。
  2. 注册阶段: Broker 向 NameServer 报到,说:"我叫 Broker-A,我的地址是 172.19.xx.xx:10911。"
  3. 本地连接: 你本地的 Spring Boot 启动了,配置了 NameServer 的公网 IP47.98.xx.xx)。连接成功!
  4. 死锁发生: Spring Boot 问 NameServer:"我要发消息,请问 Broker 在哪?" NameServer 极为诚实地把刚才 Broker 注册的地址丢给本地:"Broker 在 172.19.xx.xx:10911,你去吧。"
  5. 崩溃: 你的本地电脑在互联网上,怎么可能直接访问到阿里云机房内部的 172.19.xx.xx 呢?于是,本地 Spring Boot 开始疯狂尝试连接这个内网 IP,直到连接超时报错

二、 核心症状(怎么判断自己踩坑了?)

如果你遇到以下现象,99% 就是双网卡/内外网路由问题:

  • 测试连接正常:telnet 47.98.xx.xx 9876(NameServer 端口)是通的。
  • 控制台正常: 部署在同台服务器上的 RocketMQ Dashboard(控制台)能正常看到集群和 Topic。
  • 唯独本地代码报错: 本地 Spring Boot 生产者发送消息时,日志卡住,几秒后抛出 RemotingConnectException: connect to <172.19.xx.xx:10911> failed注意看报错信息里的 IP,如果变成了服务器的内网 IP,就是此问题。

三、 完美解决方案

解决这个问题的核心逻辑非常简单:强行指定 Broker 对外宣布的"身份证"为公网 IP。

针对你使用 Docker原生安装,修改方式略有不同:

方案 A:如果是原生安装(修改 broker.conf

找到你 RocketMQ 的配置文件(通常在 conf/2m-2s-async/ 或自定义路径下的 broker.conf),在文件末尾显式添加一行配置:

properties 复制代码
# 关键配置:强行指定 Broker 对外暴露的 IP 为你的云服务器公网 IP
brokerIP1 = 47.98.xx.xx 

# 如果你要做主从,或者有特殊监听需求,可以把 brokerIP2 也配上,一般配 brokerIP1 即可
# brokerIP2 = 47.98.xx.xx

注意:启动 Broker 的时候,必须带上 -c 参数指定这个配置文件,否则配置不生效:

bash 复制代码
nohup sh mqbroker -n localhost:9876 -c ../conf/broker.conf &

方案 B:如果是 Docker / Docker Compose 安装(最推荐)

如果你是用 Docker 部署的,由于 Docker 容器内部还有一套虚拟网络,更容易触发这个问题(Broker 会把 Docker 的容器内网 IP 如 172.17.0.x 注册过去)。

在 Docker 启动命令中,通过 -c 或者环境变量将 brokerIP1 传进去。

Docker Run 示例:

bash 复制代码
docker run -d \
--name rmqbroker \
-p 10911:10911 -p 10909:10909 \
vincenzopalazzo/rocketmq:v5.1.0 \
sh mqbroker -n 47.98.xx.xx:9876 -c /opt/rocketmq/conf/broker.conf --param "brokerIP1=47.98.xx.xx"

Docker Compose 示例(最直观):

在映射的 broker.conf 挂载文件中写死 brokerIP1=你的公网IP,或者在 command 启动命令中注入:

yaml 复制代码
version: '3.5'
services:
  rmqnamesrv:
    image: apache/rocketmq:5.1.0
    container_name: rmqnamesrv
    ports:
      - 9876:9876
    command: sh mqnamesrv

  rmqbroker:
    image: apache/rocketmq:5.1.0
    container_name: rmqbroker
    ports:
      - 10909:10909
      - 10911:10911
    environment:
      - NAMESRV_ADDR=rmqnamesrv:9876
    # 核心就在最后这一句,强行指定当前 Broker 注册上去的 IP 是公网公网 IP
    command: sh mqbroker -c /home/rocketmq/rocketmq-5.1.0/conf/broker.conf --param "brokerIP1=47.98.xx.xx"
    depends_on:
      - rmqnamesrv

四、 必须要放行的"云服务器安全组"端口

改完配置后,本地要成功通信,还需要在阿里云/腾讯云后台放行以下几个端口。RocketMQ 用的端口比普通中间件多,少放一个都会失败:

  • 9876 NameServer 的端口(本地 Spring Boot 建立初步连接、拉取路由表用)。
  • 10911 Broker 的默认监听端口(本地非 VIP 通道发送/消费消息的核心通道)。
  • 10909 Broker 的 VIP 通道 端口(RocketMQ 默认开启 VIP 通道,如果你的客户端没显式关闭 VIP 通道,消息会往这个端口发。很多人只放行了 10911 没放行 10909,结果依然超时)。
  • 8080 / 8081(针对 RocketMQ 5.x 纯 gRPC 模式): 如果你使用的是最新的 RocketMQ 5.x 并且使用了新的 Proxy 模式,走的是 gRPC 协议,需要开放对应的 Proxy 端口(默认 8081)。

总结口诀

本地连远端,Broker 别偷懒;

莫报内网号,公网 IP 填上面(brokerIP1);

九八七六连名字,一零九一送消息;

还有一零九零九,安全组里别漏失!

相关推荐
北城以北88885 小时前
RocketMQ简介
java·spring boot·后端·rocketmq
IT界的老黄牛15 小时前
RocketMQ 4.x 任意秒数延迟消息工程实战:MQ 粗延迟 + Redis 补精度 + MDC 链路透传
redis·rocketmq·事务消息·延迟消息
至此流年莫相忘1 天前
Windows 环境下 RocketMQ 安装与 NSSM 后台服务化部署指南
windows·rocketmq
折哥的程序人生 · 物流技术专研2 天前
《Java 100 天进阶之路》第95篇:消息队列基础(RocketMQ/Kafka)(2026版)
java·面试·kafka·rocketmq·java-rocketmq·求职招聘
景川呀2 天前
RocketMq知识点
java·rocketmq·java-rocketmq
cfm_29144 天前
RocketMQ源码深度解析(三)消息持久化机制
rocketmq
不惑_7 天前
手摸手教你在腾讯云CVM搭建RocketMQ
云计算·rocketmq·腾讯云
东方巴黎~Sunsiny7 天前
实战:RocketMQ 幂等 + Redis 分布式锁 + 异常重试 保姆级教程
redis·分布式·rocketmq
cfm_29147 天前
RocketMQ源码深度解析(二)Netty通信、Broker心跳注册、消息收发、客户端负载均衡原理
负载均衡·rocketmq