Linux 部署 RocketMQ 实操:从内网到公网,搞定远程消息服务

· 编程技术杂谈

最近做分布式项目时需要用 RocketMQ 实现跨服务消息通信,从本地测试到服务器内网部署再到开放公网供远程调用,我踩了不少坑也总结出一套完整的实操流程,今天就把这份干货分享给大家,全程都是实操内容没有废话,新手跟着一步步做就能搞定,不用在部署上浪费时间。

先跟大家说下本次实操的环境,我用的是 CentOS 7 版本的 Linux 系统、适合大多数项目的 RocketMQ 4.9.4 稳定版,而 RocketMQ 要依赖 Java 环境所以得提前装好用好 JDK 1.8 及以上版本,我们的核心目标就是先完成内网部署保证服务正常运行、消息收发不出问题,再配置公网访问实现不同网络环境下远程客户端的消息交互。

一、前期准备:环境搭建与安装包准备

工欲善其事,必先利其器,部署前我们得先把基础环境弄好,避免后面出现各种兼容性问题。

检查并安装 JDK,因为 RocketMQ 对 JDK 版本有明确要求,必须是 64 位的 JDK 1.8 及以上,大家可以执行 java -version 命令查看当前 JDK 版本,要是没安装或者版本不符合要求,就先卸载旧版本再安装 JDK 1.8,安装完成后记得配置 JAVA_HOME 环境变量确保全局都能使用。

然后获取 RocketMQ 安装包,我推荐大家用二进制包,因为它已经编译完成可以直接运行,不用自己手动编译特别适合新手,大家可以用 wget 命令在 Linux 服务器上直接下载,也能在本地下载好后上传到服务器,下载完成后把安装包解压到 /usr/local/rocketmq 这类指定目录,解压命令是 unzip rocketmq-all-4.9.4-bin-release.zip,解压后进入解压目录,后面所有操作都在这个目录里进行。

补充一点,解压后大家可以修改目录名称让后面输入命令更方便,比如用 mv rocketmq-all-4.9.4-bin-release rocketmq 这个命令,这样后面进入目录只要输入 cd /usr/local/rocketmq 就可以了。

二、内网部署:搞定 NameServer 与 Broker 核心服务

RocketMQ 有两个核心部分分别是 NameServer 和 Broker,其中 NameServer 负责管理 Broker 注册信息和 Topic 路由信息就像一个“导航仪”,而 Broker 负责消息的存储和收发是实际处理消息的核心,内网部署的关键就是启动这两个组件并保证它们能正常通信。

2.1 启动 NameServer

NameServer 启动起来很简单,大家进入 RocketMQ 目录后执行 nohup sh bin/mqnamesrv & 这个后台启动命令,它会把 NameServer 以守护进程的方式启动,日志会默认输出到 ~/logs/rocketmqlogs/namesrv.log 文件里。

启动后大家要验证一下 NameServer 有没有启动成功,执行 tail -f ~/logs/rocketmqlogs/namesrv.log 命令,要是日志里出现“The Name Server boot success...”这句话,就说明 NameServer 已经启动成功了,它的默认端口是 9876,这个端口后面要开放大家先记下来。

2.2 配置并启动 Broker

Broker 启动前要简单配置一下,这样才能确保它能正确注册到 NameServer 并且适应内网环境,大家进入 RocketMQ 的 conf 目录后复制一份 broker.conf 配置文件,命令是 cp broker.conf broker-inner.conf,别直接修改默认文件这样后面出问题好回滚。

编辑这份复制好的配置文件时,核心配置要注意这几点:指定 NameServer 地址时填写内网 IP:9876 比如 namesrvAddr=192.168.1.100:9876,设置 Broker 名称比如 brokerName=broker-a,监听端口默认是 10911 不用修改,要是出现端口冲突自己调整一下就行,其他配置保持默认就可以。

配置好之后就可以启动 Broker 了,执行 nohup sh bin/mqbroker -n 内网IP:9876 -c conf/broker-inner.conf & 这个命令,其中 -n 是指定 NameServer 地址、-c 是指定配置文件路径,启动后同样要验证是否成功,执行 tail -f ~/logs/rocketmqlogs/Broker.log 命令,要是日志里出现“The broker(broker-a, 内网IP:10911) boot success...”,就说明 Broker 启动成功而且已经注册到 NameServer 了。

2.3 内网消息收发测试

服务启动后大家一定要做内网测试,确保消息能正常发送和接收,别等后面公网配置好了才发现内网服务本身就有问题。

设置环境变量指定 NameServer 地址,执行 export NAMESRV_ADDR=内网IP:9876 这个命令,然后发送消息执行 sh bin/tools.sh org.apache.rocketmq.example.quickstart.Producer 命令,要是能看到很多“SendResult (sendStatus=SEND_OK, msgId=...)”的输出内容,就说明消息发送成功了。

接着进行接收消息的测试,大家新开一个终端同样设置好环境变量,然后执行 sh bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer 命令,要是能看到“ConsumeMessageThread_%d Receive New Messages: (MessageExt...”的输出,就说明消息接收成功,到这里内网部署就全部完成了。

三、公网配置:从内网暴露到远程可访问

内网部署完成后只能在同一局域网内访问,要是想让本地电脑、其他服务器这类远程客户端也能访问,就需要配置公网访问,这一步是重点也很容易踩坑,核心就是解决“公网IP映射”和“端口开放”这两个问题。

3.1 配置 Broker 公网IP

首先要修改 Broker 配置让它对外暴露公网 IP,不然远程客户端获取到的会是 Broker 的内网 IP 根本没法建立连接,大家进入 conf 目录后新建一个 broker-public.conf 配置文件,核心配置要注意这几点:namesrvAddr 填写和 NameServer 公网地址一样的公网IP:9876,brokerName 保持和内网 Broker 一样的 broker-a 确保路由信息统一,brokerIP1 填写公网 IP 这是让 Broker 对外暴露公网 IP 的关键配置,listenPort 保持和内网一样的 10911 方便后面开放端口。

配置好之后先停止之前启动的内网 Broker,执行 sh bin/mqshutdown broker 命令,等进程完全停止后再重新启动 Broker,启动时指定新的公网配置文件,命令是 nohup sh bin/mqbroker -n 公网IP:9876 -c conf/broker-public.conf &,启动后查看日志,确认 Broker 已经成功注册到 NameServer 而且日志里显示的 IP 是公网 IP。

3.2 开放服务器端口

RocketMQ 需要开放两个核心端口,分别是 NameServer 的 9876 端口和 Broker 的 10911 端口,要是部署了 Dashboard 还需要开放 8080 端口不过本次实操暂时不部署 Dashboard,端口开放要分两步来做,分别是 Linux 系统防火墙开放端口和云服务器安全组开放端口,要是大家用的是阿里云、腾讯云这类云服务器,安全组开放端口这一步一定要做。

配置 Linux 防火墙,执行 firewall-cmd --permanent --add-port=9876/tcp 和 firewall-cmd --permanent --add-port=10911/tcp 这两个命令开放对应的端口,然后执行 firewall-cmd --reload 命令重新加载防火墙,最后执行 firewall-cmd --list-ports 命令查看端口有没有开放成功。

要是用的是云服务器,大家登录云控制台找到安全组配置,添加入方向规则允许外部访问 9876 和 10911 端口,源地址设置为 0.0.0.0/0 这样能允许所有 IP 访问,生产环境可以根据实际需求限制 IP 范围来提高安全性,协议选择 TCP 配置好后保存生效就可以了。

3.3 重启 NameServer(可选)

要是 NameServer 之前绑定的是内网 IP,建议大家重启一下 NameServer 让它监听公网 IP,执行 sh bin/mqshutdown namesrv 命令停止进程,等进程停止后执行 nohup sh bin/mqnamesrv -n 公网IP:9876 & 命令重新启动,启动后查看日志确保 NameServer 正常运行而且能被公网访问。

四、公网远程测试:验证远程消息服务

公网配置完成后,大家要在本地电脑这类远程客户端进行测试,确保能正常连接 RocketMQ 服务并完成消息的收发操作。

首先在本地电脑安装 JDK 1.8 及以上版本并配置好环境变量,然后下载 RocketMQ 二进制包,不用启动服务只用它提供的工具类进行测试就可以,解压后打开命令行进入 RocketMQ 目录,Windows 系统执行 set NAMESRV_ADDR=公网IP:9876 命令设置环境变量,Mac/Linux 系统则执行 export NAMESRV_ADDR=公网IP:9876 命令。

然后执行发送消息的命令,Mac/Linux 系统执行 sh bin/tools.sh org.apache.rocketmq.example.quickstart.Producer 命令,Windows 系统执行 bin\tools.cmd org.apache.rocketmq.example.quickstart.Producer 命令,要是能正常输出消息发送成功的日志,就说明公网连接是正常的。

接下来再执行接收消息的命令,同样先设置好环境变量后执行对应的接收命令,要是能正常接收消息,就说明远程消息服务已经完全搞定了,到这里从 Linux 内网部署 RocketMQ 到配置公网实现远程访问的整个流程就全部完成了。

五、常见问题排查(避坑指南)

实操过程中大家难免会遇到各种问题,我这里总结了几个最常见的坑,能帮助大家快速排查并解决问题。

  1. 启动 Broker 失败且日志提示“connect to NameServer failed”,遇到这种情况要检查 NameServer 是不是正常运行、Broker 配置文件里的 namesrvAddr 填写得对不对,还要确保 NameServer 和 Broker 网络能连通,大家可以用 ping 命令验证 IP 能不能连通,用 telnet 命令验证 9876 端口有没有开放。
  2. 远程客户端没法连接且提示“connect timeout”,这时候要检查云服务器安全组和 Linux 防火墙有没有开放 9876 和 10911 端口,还要检查 Broker 配置文件里的 brokerIP1 是不是正确填写了公网 IP,修改后重启 Broker 再进行测试。
  3. 消息能发送成功但接收不到,这种情况要检查客户端环境变量 NAMESRV_ADDR 是不是正确配置成了公网 IP:9876,还要检查 Broker 日志确认 Broker 正常运行且已经注册到 NameServer,大家可以用 mqadmin clusterList -n 公网IP:9876 命令查看 Broker 的注册情况。
  4. 启动服务时提示“内存不足”,因为 RocketMQ 默认启动时需要的内存比较大,要是服务器内存不够,大家可以修改 bin 目录下的 runserver.sh 和 runbroker.sh 文件,调整里面的 JVM 内存参数,比如把 -Xms4g -Xmx4g 改成 -Xms512m -Xmx512m,根据服务器的实际内存灵活调整就可以。

六、总结

本次实操从前期环境准备,到内网部署 NameServer 和 Broker、完成内网消息测试,再到配置公网 IP、开放端口、实现远程访问,每一步都是能直接落地的实操步骤,其实 RocketMQ 部署并不复杂,核心就是掌握两个核心组件的启动和配置方法,以及公网访问需要的端口开放和 IP 映射技巧。

对于新手来说,建议先把内网部署做好确保服务正常运行,再一步步推进公网配置,每一步操作后都进行测试,别一次性配置完成后出现问题不好排查,另外生产环境部署时,建议配置多节点的 NameServer 和 Broker 集群来提高服务可用性,本次实操是单节点部署,更适合测试和小型项目使用。