SpringBoot + RocketMQ 整合配置与案例详解

161 阅读4分钟

SpringBoot + RocketMQ 整合配置与案例详解

下面将详细介绍SpringBoot整合RocketMQ的配置方法和实际案例,包括依赖配置、环境设置、生产者与消费者的实现等。

一、环境准备

1. 添加Maven依赖

pom.xml文件中添加RocketMQ的SpringBoot启动器依赖:

<!-- RocketMQ Spring Boot Starter -->
<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-spring-boot-starter</artifactId>
    <version>2.2.3</version>
</dependency>

如果需要指定特定版本的RocketMQ客户端,可以采用排除再引入的方式:

<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-spring-boot-starter</artifactId>
    <version>2.3.3</version>
    <exclusions>
        <exclusion>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-client</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-client</artifactId>
    <version>4.9.7</version>
</dependency>

2. 配置文件设置

application.yml中配置RocketMQ连接信息和生产者/消费者属性:

rocketmq:
  name-server: localhost:9876  # NameServer地址,集群模式用分号分隔
  producer:
    group: producer-group  # 生产者组名
    sendMessageTimeout: 5000  # 发送消息超时时间,默认3000ms
    retryTimesWhenSendFailed: 2  # 同步发送失败重试次数
    retryTimesWhenSendAsyncFailed: 2  # 异步发送失败重试次数
  consumer:
    group: consumer-group  # 消费者组名

集群环境配置示例:

rocketmq:
  name-server: 192.168.1.1:9876;192.168.1.2:9876  # 多NameServer集群配置

二、生产者实现

1. 基本生产者服务

创建生产者服务类,使用RocketMQTemplate发送消息:

import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;

@Component
public class RocketMQProducer {
    
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    
    /**
     * 发送同步消息
     */
    public void sendSyncMessage(String topic, String message) {
        rocketMQTemplate.convertAndSend(topic, message);
        System.out.println("同步消息发送成功: " + message);
    }
    
    /**
     * 发送带Tag的消息
     */
    public void sendMessageWithTag(String topic, String tag, String message) {
        rocketMQTemplate.convertAndSend(topic + ":" + tag, message);
    }
    
    /**
     * 发送Spring Message对象
     */
    public void sendSpringMessage(String topic, String message) {
        org.springframework.messaging.Message<String> springMessage = 
            MessageBuilder.withPayload(message).build();
        rocketMQTemplate.send(topic, springMessage);
    }
    
    /**
     * 发送异步消息
     */
    public void sendAsyncMessage(String topic, String message) {
        rocketMQTemplate.asyncSend(topic, message, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                System.out.println("异步消息发送成功: " + sendResult);
            }
            
            @Override
            public void onException(Throwable throwable) {
                System.err.println("异步消息发送失败: " + throwable.getMessage());
            }
        });
    }
    
    /**
     * 发送顺序消息
     */
    public void sendOrderlyMessage(String topic, String message, String hashKey) {
        rocketMQTemplate.syncSendOrderly(topic, message, hashKey);
    }
}

2. 消息实体类

创建自定义消息实体类:

import lombok.Data;
import java.io.Serializable;

@Data
public class MessageDTO<T> implements Serializable {
    private String id;
    private T content;
    private long timestamp;
}

三、消费者实现

1. 基本消费者监听

使用@RocketMQMessageListener注解创建消息监听器:

import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Component;

@Component
@RocketMQMessageListener(
    topic = "test_topic",  // 监听的主题
    consumerGroup = "consumer-group",  // 消费者组
    selectorExpression = "*"  // 消息选择表达式,*表示全部
)
public class RocketMQConsumer implements RocketMQListener<String> {
    
    @Override
    public void onMessage(String message) {
        System.out.println("接收到消息: " + message);
        // 处理消息的业务逻辑
        processMessage(message);
    }
    
    private void processMessage(String message) {
        // 消息处理逻辑
        System.out.println("处理消息中...");
    }
}

2. 监听自定义对象消息

import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Component;

@Component
@RocketMQMessageListener(
    topic = "object_topic",
    consumerGroup = "consumer-group"
)
public class ObjectMessageConsumer implements RocketMQListener<MessageDTO<String>> {
    
    @Override
    public void onMessage(MessageDTO<String> messageDTO) {
        System.out.println("接收到对象消息,ID: " + messageDTO.getId());
        System.out.println("消息内容: " + messageDTO.getContent());
    }
}

四、Controller层实现

创建REST接口用于测试消息发送:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/message")
public class MessageController {
    
    @Autowired
    private RocketMQProducer producer;
    
    @PostMapping("/send")
    public String sendMessage(@RequestParam String topic, @RequestParam String message) {
        producer.sendSyncMessage(topic, message);
        return "消息发送成功";
    }
    
    @PostMapping("/sendWithTag")
    public String sendMessageWithTag(@RequestParam String topic, @RequestParam String tag, @RequestParam String message) {
        producer.sendMessageWithTag(topic, tag, message);
        return "带标签消息发送成功";
    }
    
    @PostMapping("/sendAsync")
    public String sendAsyncMessage(@RequestParam String topic, @RequestParam String message) {
        producer.sendAsyncMessage(topic, message);
        return "异步消息发送请求已提交";
    }
    
    @PostMapping("/sendOrderly")
    public String sendOrderlyMessage(@RequestParam String topic, @RequestParam String message, @RequestParam String hashKey) {
        producer.sendOrderlyMessage(topic, message, hashKey);
        return "顺序消息发送成功";
    }
}

五、SpringBoot主程序

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class RocketMQDemoApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(RocketMQDemoApplication.class, args);
    }
}

六、高级特性

1. 事务消息

生产者端:

import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;

@Component
@RocketMQTransactionListener(txProducerGroup = "transaction-producer-group")
public class TransactionListenerImpl implements RocketMQLocalTransactionListener {
    
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        // 执行本地事务
        try {
            // 执行业务逻辑
            return RocketMQLocalTransactionState.COMMIT;
        } catch (Exception e) {
            return RocketMQLocalTransactionState.ROLLBACK;
        }
    }
    
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
        // 检查本地事务状态
        // 根据业务查询结果返回相应状态
        return RocketMQLocalTransactionState.COMMIT;
    }
}

发送事务消息:

// 在RocketMQProducer中添加方法
public void sendTransactionMessage(String topic, String message) {
    rocketMQTemplate.sendMessageInTransaction(
        "transaction-producer-group", 
        topic, 
        MessageBuilder.withPayload(message).build(), 
        null
    );
}

2. 消息过滤

消费者可以通过Tag或SQL表达式过滤消息:

@Component
@RocketMQMessageListener(
    topic = "test_topic",
    consumerGroup = "consumer-group",
    selectorExpression = "TagA || TagB"  // 只消费TagA或TagB的消息
)
public class TagFilterConsumer implements RocketMQListener<String> {
    // 实现代码...
}

3. 消息重试

配置重试策略:

rocketmq:
  consumer:
    group: consumer-group
    maxReconsumeTimes: 3  # 最大重试次数

七、测试与验证

  1. 确保RocketMQ服务已启动(NameServer和Broker)
  2. 启动SpringBoot应用
  3. 通过API接口发送消息进行测试:
    • 同步消息:POST /api/message/send?topic=test_topic&message=Hello
    • 带标签消息:POST /api/message/sendWithTag?topic=test_topic&tag=TagA&message=HelloTagA
    • 异步消息:POST /api/message/sendAsync?topic=test_topic&message=HelloAsync
    • 顺序消息:POST /api/message/sendOrderly?topic=order_topic&message=Order1&hashKey=orderId

八、常见问题与解决方案

  1. 连接问题:确保NameServer地址正确且可访问
  2. 权限问题:如果开启ACL认证,需要在配置中添加accessKey和secretKey
  3. 消息发送失败:检查生产者组名是否唯一,重试机制是否配置合理
  4. 消息接收不到:确认消费者组名、topic和tag配置是否与生产者匹配
  5. 序列化问题:自定义对象消息需要确保可序列化,RocketMQ默认使用JSON序列化

以上就是SpringBoot整合RocketMQ的完整配置和案例实现。通过这些配置和代码示例,您可以快速搭建RocketMQ的消息发送和接收系统。