- 引入maven
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
</dependency>
- 配置yml
# rocketmq 配置项,对应 RocketMQProperties 配置类
rocketmq:
name-server: 127.0.0.1:9876 # RocketMQ Namesrv
# Producer 配置项
producer:
group: demo-producer-group # 生产者分组
send-message-timeout: 3000 # 发送消息超时时间,单位:毫秒。默认为 3000 。
compress-message-body-threshold: 4096 # 消息压缩阀值,当消息体的大小超过该阀值后,进行消息压缩。默认为 4 * 1024B
max-message-size: 4194304 # 消息体的最大允许大小。。默认为 4 * 1024 * 1024B
retry-times-when-send-failed: 2 # 同步发送消息时,失败重试次数。默认为 2 次。
retry-times-when-send-async-failed: 2 # 异步发送消息时,失败重试次数。默认为 2 次。
retry-next-server: false # 发送消息给 Broker 时,如果发送失败,是否重试另外一台 Broker 。默认为 false
access-key: # Access Key ,可阅读 https://github.com/apache/rocketmq/blob/master/docs/cn/acl/user_guide.md 文档
secret-key: # Secret Key
enable-msg-trace: true # 是否开启消息轨迹功能。默认为 true 开启。可阅读 https://github.com/apache/rocketmq/blob/master/docs/cn/msg_trace/user_guide.md 文档
customized-trace-topic: RMQ_SYS_TRACE_TOPIC # 自定义消息轨迹的 Topic 。默认为 RMQ_SYS_TRACE_TOPIC 。
# Consumer 配置项
consumer:
listeners: # 配置某个消费分组,是否监听指定 Topic 。结构为 Map<消费者分组, <Topic, Boolean>> 。默认情况下,不配置表示监听。
test-consumer-group:
topic1: false # 关闭 test-consumer-group 对 topic1 的监听消费
- 配置变量
public class MqTopicConstant {
public static final String DEMO_TOPIC = "test-top-1";
public static final String DEMO_TAG_REGISTERED = "registered";
public static final String DEMO_TAG_MODIFY = "modify";
}
- 创建Service
import com.alibaba.fastjson.JSON;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
@Component
public class RocketMQService {
private static final Logger log = LoggerFactory.getLogger(RocketMQService.class);
@Resource
private RocketMQTemplate template;
public void sendMessage(String topic, Object message) {
this.template.convertAndSend(topic, message);
log.info("普通消息发送完成:message = {}", message);
}
public void syncSendMessage(String topic, Object message) {
SendResult sendResult = this.template.syncSend(topic, message);
log.info("同步发送消息完成:message = {}, sendResult = {}", message, sendResult);
}
public SendResult syncSendMessageR(String topic, Object message) {
SendResult sendResult = this.template.syncSend(topic, message);
log.info("同步发送消息完成:message = {}, sendResult = {}", message, sendResult);
SendStatus sendStatus = sendResult.getSendStatus();
log.info("状态打印 : {}" , sendStatus);
return sendResult;
}
public void asyncSendMessage(String topic, final Object message) {
this.template.asyncSend(topic, message, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
log.info("异步消息发送成功, SendStatus = {}", sendResult.getSendStatus());
}
@Override
public void onException(Throwable e) {
log.info("异步消息发送异常,exception = {}", e.getMessage());
}
});
}
public void sendOneWayMessage(String topic, Object message) {
this.template.sendOneWay(topic, message);
log.info("单向发送消息完成:message = {}", message);
}
public void syncSendMessages(String topic, List<Message<?>> messageList, long timeout) {
this.template.syncSend(topic, messageList, timeout);
log.info("同步发送批量消息完成:message = {}", JSON.toJSONString(messageList));
}
public void syncSendMessageWithTag(String topic, Object message) {
this.template.syncSend(topic, message);
log.info("发送带 tag 的消息完成:message = {}", message);
}
public void syncSendDelay(String topic, Object message, long timeout, int delayLevel) {
this.template.syncSend(topic, MessageBuilder.withPayload(message).build(), timeout, delayLevel);
log.info("已同步发送延时消息 message = {}", message);
}
public void asyncSendDelay(String topic, final Object message, long timeout, int delayLevel) {
this.template.asyncSend(topic, MessageBuilder.withPayload(message).build(), new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
log.info("异步发送延时消息成功,message = {}", message);
}
@Override
public void onException(Throwable throwable) {
log.error("异步发送延时消息发生异常,exception = {}", throwable.getMessage());
}
}, timeout, delayLevel);
log.info("已异步发送延时消息 message = {}", message);
}
public void sendMessageInTransaction(String topic, final Object message ,final Object arg) {
TransactionSendResult res = this.template.sendMessageInTransaction(topic, MessageBuilder.withPayload(message).build(), arg);
if (res.getLocalTransactionState().equals(LocalTransactionState.COMMIT_MESSAGE) && res.getSendStatus().equals(SendStatus.SEND_OK)) {
log.info("【生产者】事物消息发送成功;成功结果:{}", res);
} else {
log.info("【生产者】事务发送失败:失败原因:{}", res);
}
}
}
- 事务监听器
import lombok.extern.slf4j.Slf4j;
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;
@Slf4j
@Component
@RocketMQTransactionListener
public class TranscationRocketListener implements RocketMQLocalTransactionListener {
@Override
public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object arg) {
// 获取第三个参数(用户自定义参数)
Integer customArg = (Integer) arg;
log.info("执行本地事务,自定义参数: {}", customArg);
String tag = String.valueOf(message.getHeaders().get("rocketmq_TAGS"));
log.info("这里是校验TAG: {}" , tag );
//RocketMQLocalTransactionState.COMMIT
//RocketMQLocalTransactionState.ROLLBACK
//RocketMQLocalTransactionState.UNKNOWN
return RocketMQLocalTransactionState.UNKNOWN;
}
@Override
public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
log.info("检查本地交易: {}", message);
return RocketMQLocalTransactionState.COMMIT;
}
}
状态解释
- RocketMQLocalTransactionState.COMMIT:
含义: 表示本地事务已成功执行,允许提交消息。这意味着消息将对消费者可见,可以被正常消费。
使用场景: 当您的业务逻辑成功执行且希望该消息能够被下游系统处理时,应返回此状态。
- RocketMQLocalTransactionState.ROLLBACK:
含义: 表示本地事务执行失败,要求回滚消息。即该消息不会被发送给任何消费者。
使用场景: 如果您的业务逻辑执行过程中遇到错误或异常情况,不希望该消息影响下游系统,则应回滚事务,返回此状态。
- RocketMQLocalTransactionState.UNKNOWN:
含义: 表示当前无法确定事务的状态,可能是因为网络问题或其他原因导致暂时无法判断。RocketMQ 会定期调用 checkLocalTransaction 方法来检查事务的状态。
使用场景: 当您不确定事务是否成功完成时(例如,远程服务调用超时),可以返回此状态。RocketMQ 将通过 checkLocalTransaction 方法尝试再次确认事务状态。
- 测试发送消息
@Autowired
private RocketMQService rocketMQService;
## 发送事务消息
rocketMQService.sendMessageInTransaction(GpsConstants.DEDUCTION_MESSP_TOPIC, "这是测试消息");
## 消费事务消息
@Service
@RocketMQMessageListener(topic = GpsConstants.DEDUCTION_MESSP_TOPIC
, consumerGroup = GpsConstants.DEDUCTION_MESSP_GROUP)
public class deductionTopic implements RocketMQListener<String> {
@Override
public void onMessage(String msg) {
System.out.println("msg : " + msg);
}
}
提示 : 同一个topic,不同的consumerGroup都会消费,根据自己的业务指定不同的 consumerGroup 处理不同的业务,如果不需要,则一个topic只能用一次