RocketMQ 的安装及使用

摘要

  • 本文介绍 CentOS9 中 RocketMQ 的安装与使用。

  • RocketMQ官网

  • 本文使用的 RocketMQ 版本为 5.3.2。

Apache RocketMQ 简介

一、RocketMQ 是什么?

RocketMQ 是一个分布式、队列模型的消息中间件。它由阿里巴巴在2012年开源,并于2017年正式成为 Apache 基金会的顶级项目。

你可以把它想象成一个在分布式系统中负责可靠传递消息的“邮局”或“快递系统”。当系统A需要发送数据给系统B,但它们之间不直接通信时,就可以通过 RocketMQ 来中转,确保消息不丢失、不重复,并且能按顺序送达。

RocketMQ 是一个高性能、高可靠、高实时的分布式消息中间件。它就像分布式系统的“中枢神经系统”,负责在各个服务之间可靠、高效地传递数据,是现代互联网架构中不可或缺的基础组件之一。

RocketMQ 5.x 通过引入 Proxy 模式,极大地提升了架构的灵活性、多语言支持能力和云原生亲和力,是其在消息中间件领域持续演进的重要里程碑。

它与 Kafka、RabbitMQ 等都是业界顶级的消息队列,但各有侧重。RocketMQ 在事务消息、顺序消息和对在线业务的稳定性支持方面表现尤为出色。


二、核心特点与优势

RocketMQ 之所以流行,主要归功于以下几个核心特点:

  1. 削峰填谷

    • 场景:电商秒杀活动时,瞬时会有海量下单请求涌来,后端处理系统可能无法承受。
    • 作用:RocketMQ 可以将这些突发的请求消息先缓存起来,然后让后端系统按照自己能处理的速率慢慢消费,避免了系统被冲垮。这就好比用一个大水库先拦住洪水,再平稳地向下游放水。
  2. 异步解耦

    • 场景:用户注册后,需要发送欢迎邮件、发放优惠券、初始化积分等。
    • 作用:主注册流程只需要向 RocketMQ 发送一个“用户已注册”的消息,而不需要等待所有后续操作完成。负责邮件、优惠券的系统会自己去 RocketMQ 取消息并处理。这样,系统之间的依赖关系就变弱了,提高了整体的灵活性和可维护性。
  3. 顺序消息

    • 场景:一个订单的状态必须严格按照 创建 -> 付款 -> 发货 -> 确认收货 的顺序来变更。
    • 作用:RocketMQ 可以保证同一个订单ID的消息被存储在同一个队列中,并按照发送顺序被消费,确保了业务逻辑的正确性。
  4. 持久性与高可靠

    • RocketMQ 会将所有消息持久化到磁盘,即使服务器重启,消息也不会丢失。
    • 它本身采用分布式集群架构,支持主从复制,提供了极高的可用性。
  5. 消息回溯

    • 消费者可以重置消费位点,重新消费过去某个时间点的消息。这在业务逻辑出错、需要重新处理时非常有用。
  6. 海量消息堆积能力

    • 能够支持万亿级别的消息堆积,不会因为大量未消费消息而导致性能急剧下降。

三、核心架构与概念

要理解 RocketMQ,需要知道几个关键角色:

3.1 经典核心组件 (RocketMQ 4.x)

  • Producer(生产者):发送消息的客户端。

  • Consumer(消费者):接收消息的客户端。

  • Broker:消息服务器,负责存储和转发消息。它是 RocketMQ 的核心。

  • Topic(主题):消息的分类,生产者向指定的 Topic 发送消息,消费者订阅指定的 Topic 来消费消息。例如,可以有一个 “Order_Topic” 专门用来处理所有订单相关的消息。

  • Name Server(名字服务):一个轻量级的注册中心,负责管理所有 Broker 的地址信息,帮助生产者和消费者找到对应的 Broker。

3.2 RocketMQ 5 的新核心:Proxy

在 RocketMQ 5.x 版本中,引入了一个新的关键组件——Proxy

  • Proxy(代理):一个无状态的网络代理层,可以独立部署。

引入 Proxy 主要有两种模式:

  1. 集群部署模式 (Cluster Mode)

    • 这是经典的部署方式。生产者和消费者直接与 Broker 通信。
    • 架构Producer/Consumer <--> Broker <--> Name Server
  2. Proxy 部署模式

    • 这是 RocketMQ 5.x 推荐的新模式。所有客户端的请求都先经过 Proxy,由 Proxy 代理与 Broker 和 Name Server 进行交互。
    • 架构Producer/Consumer <--> Proxy <--> Broker <--> Name Server

引入 Proxy 模式的优势:

  • 架构解耦与语言无关:Proxy 作为通用代理,将复杂的 Broker 协议封装成更简单的接口(如 gRPC),使得用不同编程语言(如 Go, Python, C++ 等)开发的客户端更容易接入,而无需实现复杂的原生协议。

  • 简化客户端:客户端不再需要感知 Name Server 和 Broker 的地址变化,只需连接固定的 Proxy 地址即可,大大降低了客户端的复杂度。

  • 增强安全性:可以在 Proxy 层统一实现安全认证、限流、审计等策略,作为Broker集群的安全屏障。

  • 云原生友好:无状态的 Proxy 非常适合在 Kubernetes 等容器化环境中进行部署和弹性伸缩。


四、典型应用场景

  • 电商/金融交易系统:保证交易核心流程的可靠、顺序和最终一致性。

  • 大数据采集:将大量日志、行为数据先写入消息队列,再由后端的大数据处理系统(如 Flink, Spark)消费。

  • 微服务间的异步通信:在微服务架构中,作为服务之间的通信总线。


RocketMQ 的安装

  • RocketMQ 5.x 依赖 JDK 1.8+。

单机安装

1
2
3
4
5
mkdir -p /usr/local/soft/rocketmq/
wget https://dist.apache.org/repos/dist/release/rocketmq/5.3.2/rocketmq-all-5.3.2-bin-release.zip
unzip rocketmq-all-5.3.2-bin-release.zip
ln -s rocketmq-all-5.3.2-bin-release rocketmq5
cd rocketmq5

小贴士
默认脚本中,NameServer需要4G内存,Broker 需要8G内存,如果内存不够,可以进入bin目录,对其中的runserver.shrunbroker.sh两个脚本进行一下修改

1
2
3
4
5
6
7
8
9
# 使用vi runserver.sh指令,编辑这个脚本,找到下面的一行配置,调整Java进程的内存大小。
JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2G -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
修改为:
JAVA_OPT="${JAVA_OPT} -server -Xms1g -Xmx1g -Xmn512m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"

# 接下来,同样调整runbroker.sh中的内存大小。
JAVA_OPT="${JAVA_OPT} -server -Xms8g -Xmx8g"
修改为:
JAVA_OPT="${JAVA_OPT} -server -Xms2g -Xmx2g"
  • 启动 NameServer

安装完RocketMQ包后,我们启动NameServer

1
2
3
4
5
6
7
### 启动namesrv
$ nohup sh bin/mqnamesrv &

### 验证namesrv是否启动成功
$ tail -f ~/logs/rocketmqlogs/namesrv.log
# 我们可以在namesrv.log 中看到 'The Name Server boot success..', 表示NameServer 已成功启动。
The Name Server boot success. serializeType=JSON, address 0.0.0.0:9876
  • 启动 Broker+Proxy

NameServer成功启动后,我们启动Broker和Proxy。这里我们使用 Local 模式部署,即 Broker 和 Proxy 同进程部署。5.x 版本也支持 Broker 和 Proxy 分离部署以实现更灵活的集群能力。

1
2
3
4
5
6
7
### 先启动broker
$ nohup sh bin/mqbroker -n localhost:9876 --enable-proxy &

### 验证broker是否启动成功, 比如, broker的ip是192.168.1.2 然后名字是broker-a
$ tail -f ~/logs/rocketmqlogs/proxy.log
# 我们可以在 proxy.log 中看到“The broker[brokerName,ip:port] boot success..”,这表明 broker 已成功启动。
The broker[broker-a, 10.250.0.175:10911] boot success. serializeType=JSON and name server is localhost:9876

启动 Proxy 遇到的问题

  • 无论是 Broker+Proxy 启动,还是 单独启动 Proxy,都报如下错误:

1
2
3
4
5
Exception in thread "main" java.lang.UnsatisfiedLinkError: failed to load the required native library

Caused by: java.lang.IllegalArgumentException: Failed to load any of the given libraries: [netty_tcnative_linux_x86_64_fedora, netty_tcnative_linux_x86_64, netty_tcnative_x86_64, netty_tcnative]

Suppressed: java.lang.UnsatisfiedLinkError: /tmp/libnetty_tcnative_linux_x86_642308675901892111861.so: libcrypt.so.1: cannot open shared object file: No such file or directory
  • 原因分析

      1. Netty-tcnative 的编译依赖:RocketMQ 使用的 Netty 的 tcnative 模块是在较旧的环境中编译的,而动态链接的版本锁定:编译时链接的是 libcrypt.so.1,运行时必须找到相同主版本号的库
      1. 而我当前使用的系统为 Amazon Linux 2023,基于更新的 glibc,其加密功能已经迁移到 libcrypt.so.2。(Amazon Linux 2:基于较旧的 glibc 版本,libcrypt.so.1 是主要的加密库)
1
2
3
4
5
6
7
8
# 检查 libcrypt 是否存在
$ ldconfig -p | grep libcrypt
## 输出
libcryptsetup.so.12 (libc6,x86-64) => /lib64/libcryptsetup.so.12
libcrypto.so.3 (libc6,x86-64) => /lib64/libcrypto.so.3
libcrypto.so (libc6,x86-64) => /lib64/libcrypto.so
libcrypt.so.2 (libc6,x86-64) => /lib64/libcrypt.so.2
libcrypt.so (libc6,x86-64) => /lib64/libcrypt.so
  • 解决办法

1
2
3
4
5
6
7
8
9
10
11
# 安装兼容性包
sudo yum install libxcrypt-compat
# 检查 libcrypt 是否存在
$ ldconfig -p | grep libcrypt
## 输出
libcryptsetup.so.12 (libc6,x86-64) => /lib64/libcryptsetup.so.12
libcrypto.so.3 (libc6,x86-64) => /lib64/libcrypto.so.3
libcrypto.so (libc6,x86-64) => /lib64/libcrypto.so
libcrypt.so.2 (libc6,x86-64) => /lib64/libcrypt.so.2
libcrypt.so.1 (libc6,x86-64) => /lib64/libcrypt.so.1
libcrypt.so (libc6,x86-64) => /lib64/libcrypt.so