本文介绍RocketMQ与SpringBoot集成,使用rocketmq-client依赖,使用rocketmq官方原生方式操作mq。而非使用org.apache.rocketmq.spring.core.RocketMQTemplate
RocketMQTemplate只需要配置即可使用,比较简单,原理差不多,可以自行百度~
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<modules>
<module>springboot-rocketmq-demo-common</module>
<module>springboot-rocketmq-demo-config</module>
<module>springboot-rocketmq-demo-web</module>
<module>start</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.7.RELEASE</version>
<relativePath/>
</parent>
<groupId>org.example</groupId>
<artifactId>springboot-rocketmq-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<project.version>1.0-SNAPSHOT</project.version>
<lombok.version>1.18.16</lombok.version>
<junit.version>4.13.1</junit.version>
<commons-lang3.version>3.12.0</commons-lang3.version>
<hutool.version>5.7.20</hutool.version>
<fastjson.version>1.2.79</fastjson.version>
<rocketmq.version>4.9.1</rocketmq.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>${rocketmq.version}</version>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>springboot-rocketmq-demo-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>springboot-rocketmq-demo-config</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>springboot-rocketmq-demo-web</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
生产者核心配置类
/**
* @author yongen
* @description: 生产者配置
* @date 2022/2/9 2:18 PM
*/
@Configuration
@Slf4j
public class DefaultProducerConfig {
@Resource
private RocketMQProducerProperties producerProperties;
@Bean
@Primary
public DefaultMQProducer defaultProducer() throws MQClientException {
DefaultMQProducer producer = new DefaultMQProducer(producerProperties.getGroup());
producer.setNamesrvAddr(producerProperties.getNamesrvAddr());
producer.setVipChannelEnabled(false);
producer.setRetryTimesWhenSendAsyncFailed(producerProperties.getRetryTimesWhenSendAsyncFailed());
producer.setSendMsgTimeout(producerProperties.getSendMsgTimeout());
producer.start();
log.info("RocketMQ Producer 初始化成功: {}", JSONUtil.parse(producerProperties));
return producer;
}
}
消费者要实现对消息的监听,这里使用的枚举类定义topic和tag还有具体处理类的关系实现监听:
ConsumerBeanEnum
/**
* @author yongen
* @description: 维护topicTag和处理类的关系
* @date 2022/2/9 3:04 PM
*/
public enum ConsumerBeanEnum {
ADD_USER("T_DEMO_PROJECT:ADD_USER", "addUserHandler"),
ADD_ORDER("T_DEMO_PROJECT:ADD_ORDER", "addOrderHandler"),
;
/**
* TOPIC:TAG 名称
*/
private String topicTag;
/**
* Handler bean名称
*/
private String beanName;
public String getTopicTag() {
return topicTag;
}
public void setTopicTag(String topicTag) {
this.topicTag = topicTag;
}
public String getBeanName() {
return beanName;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
ConsumerBeanEnum(String topicTag, String beanName) {
this.topicTag = topicTag;
this.beanName = beanName;
}
public static ConsumerBeanEnum getBeanByTopicTag(String topicTag) {
for (ConsumerBeanEnum beanEnum : ConsumerBeanEnum.values()) {
if (beanEnum.getTopicTag().equals(topicTag)) {
return beanEnum;
}
}
return null;
}
}
AbstractConsumerListener
/**
* @author yongen
* @description: 抽象消费消息监听类
* @date 2022/2/9 2:52 PM
*/
@Configuration
@Slf4j
public abstract class AbstractConsumerListener {
@Resource
private RocketMQConsumerProperties rocketMQConsumerProperties;
/**
* 开启消费注册
*
* @param topic
* @param tags 支持多个tag, 如 tag1 || tag2 || tag3
* @throws MQClientException
*/
public void listener(String topic, String tags) throws MQClientException {
log.info("开启【{}】:【{}】 消费者....", topic, tags);
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(rocketMQConsumerProperties.getGroup());
consumer.setNamesrvAddr(rocketMQConsumerProperties.getNamesrvAddr());
consumer.subscribe(topic, tags);
// 开启内部类实现监听
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
return AbstractConsumerListener.this.onMessage(msgs);
}
});
consumer.start();
}
/**
* 处理body的业务
*
* @param msgs
* @return ConsumeConcurrentlyStatus
*/
public abstract ConsumeConcurrentlyStatus onMessage(List<MessageExt> msgs);
DefaultConsumerListener
/**
* @author yongen
* @description: 消费消息监听者实现类
* @date 2022/2/9 2:56 PM
*/
@Configuration
@Slf4j
public class DefaultConsumerListener extends AbstractConsumerListener implements ApplicationContextAware,
ApplicationListener<ContextRefreshedEvent> {
/**
* 上下文
*/
private ApplicationContext applicationContext;
@Override
public ConsumeConcurrentlyStatus onMessage(List<MessageExt> msgs) {
for (MessageExt msg : msgs) {
String topicTag = msg.getTopic() + ":" + msg.getTags();
ConsumerBeanEnum mqConsumerBeanEnum = ConsumerBeanEnum.getBeanByTopicTag(topicTag);
if (mqConsumerBeanEnum == null) {
break;
}
ConsumeConcurrentlyStatus consumerStatus = null;
Object serviceBean = applicationContext.getBean(mqConsumerBeanEnum.getBeanName());
if (null == serviceBean) {
break;
}
if (serviceBean instanceof RocketMQConsumerService) {
String message = new String(msg.getBody(), StandardCharsets.UTF_8);
RocketMQConsumerService consumerService = (RocketMQConsumerService) serviceBean;
// 预处理
consumerService.beforeHandler(message);
// 处理
consumerStatus = consumerService.handle(message);
// 处理之后
consumerService.afterHandler(message, LocalDateTime.now(), consumerStatus);
}
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
try {
// 订阅同一个topic下的多个tag
super.listener("T_DEMO_PROJECT", "ADD_USER || ADD_ORDER");
} catch (MQClientException e) {
log.error("consumer error");
}
}
}
完整代码地址:gitee.com/islibin/spr…
核心配置代码在config子模块下。