RocketMQ简介

RocketMQ

文章目录

RocketMQ简介

RocketMQ 作为一款纯java、分布式、队列模型的开源消息中间件,支持事务消息、顺序消息、批量消息、定时消息、消息回溯等

官网 https://rocketmq.apache.org/

核心概念

主要由四大部分组成:

  1. Producer:生产者,可以集群部署。它会先和 NameServer 集群中的随机一台建立长连接,得知当前要发送的 Topic 存在哪台 Broke Master上,然后再与其建立长连接,支持多种负载平衡模式发送消息。举例:发件人。

  2. Consumer:消费者,可以集群部署。它也会先和 NameServer 集群中的随机一台建立长连接,得知当前要消息的 Topic 存在哪台 Broker Master、Slave上,然后它们建立长连接,支持集群消费和广播消费消息。举例:收件人。

  3. Broker:消息队列的中间服务器,主要负责存储消息并将消息传递给消费者。支持主从部署,一个 Master 可以对应多个 Slave,Master 支持读写,Slave 只支持读。Broker 会向集群中的每一台 NameServer 注册自己的路由信息。举例:快递。

  4. NameServer:是一个很简单的 Topic 路由注册中心,支持 Broker 的动态注册和发现,保存 Topic 和 Borker 之间的关系。通常也是集群部署,但是各 NameServer 之间不会互相通信, 各 NameServer 都有完整的路由信息,即无状态。

Topic:消息的逻辑分类,生产者发送消息到指定的Topic,消费者从指定的Topic订阅消息。一个Topic可以有多个Producer和多个Consumer。

ProducerGroup:生产者组。

ConsumerGroup:消费者组,多个消费者组可以同时消费一个主题的消息。

RabbitMQ、Kafka、RocketMQ 三大消息队列对比

特性 RabbitMQ Kafka RocketMQ
开发语言 Erlang Scala/Java Java
协议 AMQP 自定义协议 自定义协议
设计目标 企业级消息路由 高吞吐日志流 金融级消息队列
吞吐量 万级 十万级/百万级 十万级
延迟 微秒级 毫秒级 毫秒级
可靠性 非常高 非常高
顺序性 队列级别 分区级别 队列级别
事务 支持 不支持(0.11+支持) 支持
回溯消费 不支持 支持 支持
消息过滤 简单 不支持 支持(Tag/SQL)
社区生态 非常成熟 非常成熟 逐渐成熟
学习曲线 中高

安装RocketMQ

推荐版本

RocketMQ 版本 JDK 要求 状态 推荐度
RocketMQ 5.x JDK 17+ 最新版 ⭐⭐⭐⭐⭐
RocketMQ 4.9.x JDK 8-17 稳定版 ⭐⭐⭐⭐
RocketMQ 4.8.x JDK 8-11 维护版 ⭐⭐⭐
RocketMQ 4.7.x JDK 8 过时

下载Apache RocketMQ 5.3.2的源码包

设置环境变量

变量名:ROCKETMQ_HOME

变量值:MQ解压路径\MQ文件夹名(bin目录的上一级即可)

启动RocketMQ

启动NameServer
复制代码
start mqnamesrv.cmd
启动Broker
复制代码
start mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable = true

配置可视化页面

修改rocketmq-dashboard-2.0.0-source-release\src\main\resources下边application.yml(可选)

运行Dashboard
复制代码
#1. 进入 Dashboard 源码目录
cd /d D:\RocketMQ\rocketmq-dashboard-2.0.0-source-release

# 2. 编译打包
mvn clean package -Dmaven.test.skip=true

#3. 编译成功后,jar 包在:D:\RocketMQ\rocketmq-dashboard-2.0.0-source-release\target\
#将 application.yml 复制到 target 目录
#注意:application.yml 在 src\main\resources\ 目录下
copy src\main\resources\application.yml target\

#进入 target 目录并启动
cd /d D:\RocketMQ\rocketmq-dashboard-2.0.0-source-release\target

#使用配置文件启动
java -jar rocketmq-dashboard-2.0.0.jar --spring.config.location=application.yml

访问http://localhost:8888

展示了 RocketMQ Broker 和 Topic 的实时运行状态和性能指标。

**Broker TOP 10 ** 显示了消息量排名前10的Broker

Broker 5min trend

  • 过去5分钟内 Broker 的消息流量趋势图
  • Y轴:代表消息的生产/消费速率(TPS - 每秒事务数

主题 TOP 10 显示了消息量排名前10的 Topic

主题 5min trend

  • TOPIC 在最近5分钟内的消息趋势图
  • Y轴:表示该 Topic 的消息生产速率

SpringBoot 集成 RocketMQ

添加依赖

xml 复制代码
<!-- Lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<!-- RocketMQ -->
<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-spring-boot-starter</artifactId>
    <version>2.2.2</version>
</dependency>

配置文件application.yml

yml 复制代码
server:
  port: 8080

spring:
  application:
    name: rocketmq-demo
rocketmq:
  # NameServer地址
  name-server: 127.0.0.1:9876
  producer:
    group: demo-producer-group
    # 发送消息超时时间,单位毫秒
    send-message-timeout: 3000
    # 发送失败重试次数
    retry-times-when-send-failed: 2
    # 异步发送失败重试次数
    retry-times-when-send-async-failed: 2
    # 消息最大长度
    max-message-size: 4096
    # 压缩消息阈值
    compress-message-body-threshold: 4096
    # 是否VIP通道,可避开一些检测逻辑
    vip-channel-enabled: false

配置类

java 复制代码
package com.hz.rocketmqtest.config;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RocketMQConfig {
    // 可以在这里定义一些公共的Topic和Tag常量
    public static final String ORDER_TOPIC = "ORDER_TOPIC";

    // 订单相关的Tag
    public static final String ORDER_CREATE_TAG = "ORDER_CREATE";
    public static final String ORDER_PAY_TAG = "ORDER_PAY";
    public static final String ORDER_CANCEL_TAG = "ORDER_CANCEL";

    // 消费者组
    public static final String ORDER_CONSUMER_GROUP = "ORDER_CONSUMER_GROUP";
}

实体类

java 复制代码
package com.hz.rocketmqtest.pojo;

import lombok.Data;

import java.math.BigDecimal;
import java.util.Date;
@Data
public class Order {
    private static final long serialVersionUID = 1L;

    private String orderId;
    private String userId;
    private BigDecimal amount;
    private Integer status; // 0-待支付,1-已支付,2-已取消
    private Date createTime;
    private String productName;
    private Integer quantity;
}

普通消息生产者

java 复制代码
package com.hz.rocketmqtest.service;

import com.hz.rocketmqtest.config.RocketMQConfig;
import com.hz.rocketmqtest.pojo.Order;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class RocketMQProducer {
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    /**
     * 发送同步消息
     */
    public boolean sendSyncMessage(Order order, String tag) {
        try {
            // 构建消息
            Message<Order> message = MessageBuilder.withPayload(order)
                    .setHeader("KEYS", order.getOrderId())
                    .build();

            // 发送同步消息
            org.apache.rocketmq.client.producer.SendResult sendResult =
                    rocketMQTemplate.syncSendOrderly(
                            RocketMQConfig.ORDER_TOPIC + ":" + tag,
                            message,
                            order.getOrderId()
                    );

            log.info("同步消息发送成功,消息ID: {}, 发送状态: {}",
                    sendResult.getMsgId(),
                    sendResult.getSendStatus());
            return true;
        } catch (Exception e) {
            log.error("同步消息发送失败", e);
            return false;
        }
    }

    /**
     * 发送异步消息
     */
    public void sendAsyncMessage(Order order, String tag) {
        try {
            Message<Order> message = MessageBuilder.withPayload(order)
                    .setHeader("KEYS", order.getOrderId())
                    .build();

            rocketMQTemplate.asyncSend(
                    RocketMQConfig.ORDER_TOPIC + ":" + tag,
                    message,
                    new org.apache.rocketmq.client.producer.SendCallback() {
                        @Override
                        public void onSuccess(org.apache.rocketmq.client.producer.SendResult sendResult) {
                            log.info("异步消息发送成功,消息ID: {}", sendResult.getMsgId());
                        }

                        @Override
                        public void onException(Throwable e) {
                            log.error("异步消息发送失败", e);
                        }
                    }
            );
        } catch (Exception e) {
            log.error("异步消息发送异常", e);
        }
    }

    /**
     * 发送单向消息(不关心结果)
     */
    public void sendOneWayMessage(Order order, String tag) {
        try {
            Message<Order> message = MessageBuilder.withPayload(order)
                    .setHeader("KEYS", order.getOrderId())
                    .build();

            rocketMQTemplate.sendOneWay(
                    RocketMQConfig.ORDER_TOPIC + ":" + tag,
                    message
            );
            log.info("单向消息发送完成");
        } catch (Exception e) {
            log.error("单向消息发送失败", e);
        }
    }

    /**
     * 发送延迟消息
     */
    public boolean sendDelayMessage(Order order, String tag, int delayLevel) {
        try {
            Message<Order> message = MessageBuilder.withPayload(order)
                    .setHeader("KEYS", order.getOrderId())
                    .build();

            // 延迟级别:1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
            org.apache.rocketmq.client.producer.SendResult sendResult =
                    rocketMQTemplate.syncSend(
                            RocketMQConfig.ORDER_TOPIC + ":" + tag,
                            message,
                            rocketMQTemplate.getProducer().getSendMsgTimeout(),
                            delayLevel
                    );

            log.info("延迟消息发送成功,消息ID: {}", sendResult.getMsgId());
            return true;
        } catch (Exception e) {
            log.error("延迟消息发送失败", e);
            return false;
        }
    }
}

普通消息消费者

java 复制代码
package com.hz.rocketmqtest.service;


import com.hz.rocketmqtest.config.RocketMQConfig;
import com.hz.rocketmqtest.pojo.Order;
import org.apache.rocketmq.spring.annotation.MessageModel;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.ConsumeMode;
import org.apache.rocketmq.spring.core.RocketMQListener;
@Service
@Slf4j
public class RocketMQConsumer {
    /**
     * 订单创建消费者
     */
    @Service
    @RocketMQMessageListener(
            topic = RocketMQConfig.ORDER_TOPIC,
            selectorExpression = RocketMQConfig.ORDER_CREATE_TAG,
            consumerGroup = RocketMQConfig.ORDER_CONSUMER_GROUP + "_CREATE",
            consumeMode = ConsumeMode.ORDERLY,  // 顺序消费
            messageModel = MessageModel.CLUSTERING  // 集群模式
    )
    public class OrderCreateConsumer implements RocketMQListener<Order> {
        @Override
        public void onMessage(Order order) {
            log.info("收到订单创建消息,订单ID: {}, 用户ID: {}, 金额: {}",
                    order.getOrderId(), order.getUserId(), order.getAmount());
            // 处理订单创建逻辑
            processOrderCreate(order);
        }

        private void processOrderCreate(Order order) {
            // 实际的业务处理逻辑
            log.info("处理订单创建业务...");
        }
    }

    /**
     * 订单支付消费者
     */
    @Service
    @RocketMQMessageListener(
            topic = RocketMQConfig.ORDER_TOPIC,
            selectorExpression = RocketMQConfig.ORDER_PAY_TAG,
            consumerGroup = RocketMQConfig.ORDER_CONSUMER_GROUP + "_PAY",
            consumeMode = ConsumeMode.CONCURRENTLY,  // 并发消费
            messageModel = MessageModel.CLUSTERING
    )
    public class OrderPayConsumer implements RocketMQListener<Order> {
        @Override
        public void onMessage(Order order) {
            log.info("收到订单支付消息,订单ID: {}", order.getOrderId());
            // 处理订单支付逻辑
            processOrderPay(order);
        }

        private void processOrderPay(Order order) {
            log.info("处理订单支付业务...");
        }
    }

    /**
     * 订单取消消费者
     */
    @Service
    @RocketMQMessageListener(
            topic = RocketMQConfig.ORDER_TOPIC,
            selectorExpression = RocketMQConfig.ORDER_CANCEL_TAG,
            consumerGroup = RocketMQConfig.ORDER_CONSUMER_GROUP + "_CANCEL",
            consumeMode = ConsumeMode.CONCURRENTLY,
            messageModel = MessageModel.CLUSTERING
    )
    public class OrderCancelConsumer implements RocketMQListener<Order> {
        @Override
        public void onMessage(Order order) {
            log.info("收到订单取消消息,订单ID: {}", order.getOrderId());
            // 处理订单取消逻辑
            processOrderCancel(order);
        }

        private void processOrderCancel(Order order) {
            log.info("处理订单取消业务...");
        }
    }
}

Controller层

java 复制代码
package com.hz.rocketmqtest.controller;
import com.hz.rocketmqtest.service.RocketMQProducer;
import com.hz.rocketmqtest.pojo.Order;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Date;
import java.util.UUID;
@RestController
@RequestMapping("/message")
@Slf4j
public class MessageController {

    @Autowired
    private RocketMQProducer rocketMQProducer;

    /**
     * 发送同步消息
     */
    @PostMapping("/sendSync")
    public String sendSyncMessage(@RequestParam String tag) {
        Order order = createOrder();

        boolean success = rocketMQProducer.sendSyncMessage(order, tag);

        return success ? "同步消息发送成功" : "同步消息发送失败";
    }

    /**
     * 发送异步消息
     */
    @PostMapping("/sendAsync")
    public String sendAsyncMessage(@RequestParam String tag){
        Order order = createOrder();

        rocketMQProducer.sendAsyncMessage(order, tag);

        return "异步消息发送中...";
    }

    /**
     * 发送单向消息
     */
    @PostMapping("/sendOneWay")
    public String sendOneWayMessage(@RequestParam String tag) {
        Order order = createOrder();

        rocketMQProducer.sendOneWayMessage(order, tag);

        return "单向消息发送完成";
    }

    /**
     * 发送延迟消息
     */
    @PostMapping("/sendDelay")
    public String sendDelayMessage(@RequestParam String tag,
                                   @RequestParam(defaultValue = "3") int delayLevel) {
        Order order = createOrder();

        boolean success = rocketMQProducer.sendDelayMessage(order, tag, delayLevel);

        return success ? "延迟消息发送成功" : "延迟消息发送失败";
    }
    /**
     * 模拟创建订单
     */
    private Order createOrder() {
        Order order = new Order();
        order.setOrderId(UUID.randomUUID().toString().replace("-", ""));
        order.setUserId("U" + System.currentTimeMillis() % 10000);
        order.setAmount(new BigDecimal("199.99"));
        order.setStatus((int) (Math.random() * 3));
        order.setCreateTime(new Date());
        order.setProductName("测试商品");
        order.setQuantity((int) (Math.random() * 10) + 1);
        return order;
    }
}
相关推荐
折哥的程序人生 · 物流技术专研8 小时前
Java面试85题图解版 · 特别篇:2026后端高频面试题复盘(算法底层逻辑+高并发架构设计全解析,附Java实战代码)
java·网络·数据库·算法·面试
GoGeekBaird8 小时前
从 Prompt Engineering 到 Loop Engineering,我觉得 AI 开发这事儿终于开始变味了
后端·github
一条泥憨鱼9 小时前
【Redis】数据类型和常用命令
java·数据库·redis·后端·缓存
云烟成雨TD9 小时前
Spring AI Alibaba 1.x 系列【78】沙箱(Sandbox)
java·人工智能·spring
程序员二叉9 小时前
【Java】 异常高频面试题精讲 | 易错点+对比总结
java·开发语言·面试
周航宇JoeZhou9 小时前
JB3-9-SpringAI(二)
java·ai·agent·多智能体·调度·智能体·观察
好家伙VCC9 小时前
Web Components主题热切换方案揭秘
java·前端
慕木沐10 小时前
Google ADK Java 1.0版本 核心机制与实战 Demo
java·开发语言·python
Oneslide10 小时前
初始化微信小程序
后端