pom.xml文件导入关键依赖:
<dependencies>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.1.1</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</exclusion> <exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
</dependencies>
然后以SpringBoot的方式,快速创建一个简单的Demo
SpringBoot启动类:
@SpringBootApplication
public class RocketMQScApplication {
public static void main(String[] args) {
SpringApplication.run(RocketMQScApplication.class,args);
}
}
配置文件 application.properties
#NameServer地址
rocketmq.name-server=192.168.232.128:9876
#默认的消息生产者组
rocketmq.producer.group=springBootGroup
消息生产者
package com.roy.rocket.basic;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
/**
* @author :
* @date :Created in 2020/10/22
* @description:
**/
@Component
public class SpringProducer {
@Resource
private RocketMQTemplate rocketMQTemplate;
//发送普通消息的示例
public void sendMessage(String topic,String msg){
this.rocketMQTemplate.convertAndSend(topic,msg);
}
//发送事务消息的示例
public void sendMessageInTransaction(String topic,String msg) throws InterruptedException {
String[] tags = new String[] {"TagA", "TagB", "TagC", "TagD", "TagE"};
for (int i = 0; i < 10; i++) {
Message<String> message = MessageBuilder.withPayload(msg).build();
String destination =topic+":"+tags[i % tags.length];
SendResult sendResult = rocketMQTemplate.sendMessageInTransaction(destination,message,destination);
System.out.printf("%s%n", sendResult);
Thread.sleep(10);
}
}
}
消息消费者
package com.roy.rocket.basic;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Component;
/**
* @author :
* @date :Created in 2020/10/22
* @description:
**/
@Component
@RocketMQMessageListener(consumerGroup = "MyConsumerGroup", topic = "TestTopic")
public class SpringConsumer implements RocketMQListener<String> {
@Override
public void onMessage(String message) {
System.out.println("Received message : "+ message);
}
}
消费者的核心在@RocketMQMessageListener注解上,所有的消费者核心会集成到这个注解中。
注解里面有几个属性比较重要:
1. 消息过滤可以由里面的selectorType属性和selectorExpression来定制
2. 消息有序消费还是并发消费则由consumeMode属性定制。
3. 消费者是集群部署还是广播部署由messageModel属性定制。
另一个比较重要的是事务消息,事务消息需要指定一个事务消息监听器。
package com.roy.rocket.config;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.apache.rocketmq.spring.support.RocketMQUtil;
import org.springframework.messaging.Message;
import org.springframework.messaging.converter.StringMessageConverter;
import java.util.concurrent.ConcurrentHashMap;
@RocketMQTransactionListener(rocketMQTemplateBeanName = "rocketMQTemplate")
public class MyTransactionImpl implements RocketMQLocalTransactionListener {
private ConcurrentHashMap<Object, String> localTrans = new ConcurrentHashMap<>();
@Override
public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
Object id = msg.getHeaders().get("id");
String destination = arg.toString();
localTrans.put(id,destination);
org.apache.rocketmq.common.message.Message message =
RocketMQUtil.convertToRocketMessage(new StringMessageConverter(),"UTF- 8",destination, msg);
String tags = message.getTags();
if(StringUtils.contains(tags,"TagA")){
return RocketMQLocalTransactionState.COMMIT;
}else if(StringUtils.contains(tags,"TagB")){
return RocketMQLocalTransactionState.ROLLBACK;
}else{
return RocketMQLocalTransactionState.UNKNOWN;
}
}
@Override
public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
//SpringBoot的消息对象中,并没有transactionId这个属性。跟原生API不一样。
// String destination = localTrans.get(msg.getTransactionId());
return RocketMQLocalTransactionState.COMMIT;
}
}
至此SpringBoot整合RocketMQ的过程完成,把程序跑起来之后就能通过访问
http://localhost:8080/MQTest/sendMessage?message=123接口发送一条简单的消息,并且能在SpringConsumer 中消费此条消息。
也可以通过http://localhost:8080/MQTest/sendTransactionMessage?message=123来发送一条事务消息。