RocketMQ新旧版本比较
RocketMQ 发展过程中,4.x 和 5.x 在概念、客户端 API、消息类型、代理层能力上都有变化。学习时不需要一开始就背所有差异,先抓住一个核心:5.x 更强调“面向云原生和多语言接入”的统一模型,4.x 更常见于传统 Java 项目。
为什么要理解新旧差异
版本差异不是“类名变了”这么简单。它会影响接入地址、客户端生命周期、Topic 类型、订阅关系、延迟消息语义和运维方式。如果只按旧教程复制 4.x 的 DefaultMQProducer,再拿 5.x 的 Proxy 地址去连,就很容易出现连不上、订阅不一致、消息类型不匹配等问题。
flowchart TD
A["旧项目 4.x 写法"] --> B["DefaultMQProducer / PushConsumer"]
C["新项目 5.x 写法"] --> D["ClientServiceProvider / Producer / PushConsumer"]
B --> E["直连 NameServer / Broker 为主"]
D --> F["通过 Proxy 或 Broker 接入"]
E --> G["迁移时检查配置和语义"]
F --> G总体差异
| 对比项 | RocketMQ 4.x | RocketMQ 5.x |
|---|---|---|
| 客户端模型 | Java SDK 使用最广,API 偏传统 | 引入更清晰的新客户端模型,多语言支持更统一 |
| 消息类型 | 普通、顺序、延迟、批量、事务等 | 对消息类型约束更清晰,Topic 可声明消息类型 |
| 接入方式 | Producer/Consumer 直连 NameServer 和 Broker | 支持 Proxy 接入,更适合云原生和统一网关 |
| 延迟消息 | 常见为固定延迟级别 | 支持更灵活的定时/延迟能力 |
| 运维方式 | 传统集群部署较多 | 更强调可观测、云原生部署和统一治理 |
4.x 常见模型
4.x 项目中经常看到 DefaultMQProducer、DefaultMQPushConsumer 这类 API。代码理解成本不高,很多老项目也仍在使用。
flowchart TD
A["DefaultMQProducer"] --> B["NameServer<br/>获取路由"]
A --> C["Broker<br/>发送消息"]
D["DefaultMQPushConsumer"] --> B
C --> D4.x 的优点是资料多、项目存量大、排查经验成熟。缺点是多语言统一性、云原生接入、部分高级能力的表达不如 5.x 清晰。
5.x 新模型
5.x 引入了更清晰的消息类型和客户端抽象,常见对象包括 ClientServiceProvider、Producer、PushConsumer、SimpleConsumer 等。
flowchart TD
A[ClientServiceProvider] --> B[Producer]
A --> C[PushConsumer]
A --> D[SimpleConsumer]
B --> E[Proxy 或 Broker]
C --> E
D --> EPushConsumer
PushConsumer 更接近传统的监听器模型,适合大多数业务消费场景。应用注册消息处理逻辑,客户端负责拉取和回调。
SimpleConsumer
SimpleConsumer 更像手动拉取模型,业务可以自己控制拉取、处理、ACK 的节奏。它适合对消费节奏、批量处理、失败控制要求更高的场景。
Topic 消息类型约束
RocketMQ 5.x 更强调 Topic 的消息类型。例如普通消息、FIFO 消息、延迟消息、事务消息应该使用匹配的 Topic 类型。
这样做的好处是:
- 运维侧更容易知道 Topic 的用途。
- 服务端可以根据类型做更明确的校验。
- 避免同一个 Topic 混用多种消息语义造成排查困难。
迁移时重点关注
1. API 不要混用
老客户端和新客户端的配置、对象模型、异常处理方式不同。迁移时建议按模块逐步替换,不要在同一个业务链路里随意混用。
2. Topic 类型要重新梳理
如果旧项目中一个 Topic 同时承载普通消息、延迟消息、事务消息,迁移时建议拆分。
示例:
ORDER_EVENT_NORMALORDER_EVENT_DELAYORDER_EVENT_TRANSACTION
3. 消费幂等仍然必须保留
不管 4.x 还是 5.x,都不能假设消息只会被消费一次。迁移过程中不要删除原有的去重表、唯一索引、状态机判断。
4. 延迟消息语义要确认
旧版常见固定延迟级别,新版能力更灵活。迁移时要确认业务原本依赖的是“延迟多久”还是“指定什么时间点投递”。
选择建议
flowchart TD
A[新项目还是老项目?] -->|新项目| B[优先考虑 5.x]
A -->|老项目稳定运行| C[继续维护 4.x 也可以]
C --> D{是否需要云原生接入或新能力?}
D -->|需要| E[规划迁移到 5.x]
D -->|不需要| F[保持版本稳定, 加强监控和治理]如果是新项目,建议直接学习和使用 5.x 模型;如果是老系统,先评估收益和风险,不要为了升级而升级。版本迁移最重要的是保证消息不丢、消费不乱、幂等不失效。
更多 API 写法可以继续看 5.x 版本 API 使用。
代码 Demo:4.x 与 5.x 写法对比
4.x 常见写法:
DefaultMQProducer producer = new DefaultMQProducer("ORDER_PRODUCER_GROUP");
producer.setNamesrvAddr("127.0.0.1:9876");
producer.start();
producer.send(new Message("ORDER_EVENT", "ORDER_CREATED", body));
producer.shutdown();5.x 新客户端更强调 Builder 和 Endpoint:
ClientServiceProvider provider = ClientServiceProvider.loadService();
ClientConfiguration configuration = ClientConfiguration.newBuilder()
.setEndpoints("127.0.0.1:8081")
.build();
Producer producer = provider.newProducerBuilder()
.setClientConfiguration(configuration)
.setTopics("ORDER_EVENT")
.build();迁移时不要只替换类名,要同时检查 Topic 类型、接入地址、异常处理、重试策略和消费幂等。
常见风险
| 风险 | 为什么会发生 | 处理方式 |
|---|---|---|
| 4.x 教程和 5.x 客户端混用 | API、端口、接入模型不一致 | 先确认项目使用的客户端版本 |
| endpoints 写成 NameServer 地址 | 5.x 新客户端常通过 Proxy 接入 | 区分 namesrvAddr 和 endpoints |
| Topic 类型不匹配 | 5.x 对 FIFO、事务、延迟等语义更明确 | 创建 Topic 时就声明正确类型 |
| 迁移后重复消费 | 重试和消费进度变化 | 保留业务幂等,不要依赖“只消费一次” |
| 多消费者订阅不一致 | 同一消费组订阅关系不统一 | 同一组同一 Topic 保持过滤条件一致 |
