消息发送方:
@RestController
@RequestMapping("/test")
public class ProducerTest {
@Autowired
private RocketMQTemplate rocketMQTemplate;
@PostMapping("/sendSyncMessage")
public void sendSyncMessage(@RequestBody Map<String, Object> msgMap) throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
//构建消息
Message message = new Message("TopicName", "Tag", "yinjs", JSON.toJSONBytes(msgMap));
//发送同步消息
SendResult sendResult = rocketMQTemplate.syncSend("TopicName:Tag", "同步消息");
//发送异步消息
rocketMQTemplate.asyncSend("TopicName:Tag", "异步消息", new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
System.out.println("异步消息发送成功");
}
@Override
public void onException(Throwable throwable) {
System.out.println("异步消息发送失败");
}
});
//发送单向消息
rocketMQTemplate.sendOneWay("TopicName:Tag", "单向消息");
//发送延时消息
//延时等级1到16分别表示 1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h,3表示延迟10s发送
//timeout:消息发送超时时间(如:timeout=3000,就表示如果3秒消息还没发出那么就会抛异常)
rocketMQTemplate.syncSend("TopicName", MessageBuilder.withPayload("延时消息").build(), 5000, 3);
//发送批量消息
List<org.springframework.messaging.Message> msgs = new ArrayList<>();
for (int i = 100; i < 110; i++) {
msgs.add(MessageBuilder.withPayload("批量消息:" + i).build());
}
rocketMQTemplate.syncSend("TopicName", msgs, 60000);
//发送过滤消息
//消费端的selectorExpression
rocketMQTemplate.convertAndSend("TopicName:tag", "过滤消息");
//发送事务消息
/* TransactionListenerImpl类 回传的事务状态:
TransactionStatus.CommitTransaction: 提交事务,它允许消费者消费此消息。
TransactionStatus.RollbackTransaction: 回滚事务,它代表该消息将被删除,不允许被消费。
TransactionStatus.Unknown: 中间状态,它代表需要检查消息队列来确定状态。
*/
for (int i = 0; i < 10; i++) {
try {
rocketMQTemplate.sendMessageInTransaction("TopicName", MessageBuilder.withPayload("事务消息:" + i).build(), null);
} catch (Exception e) {
e.printStackTrace();
}
}
//发送顺序消息
/*mqs:要发送消息的topic下的所有消息队列集合,集群的话默认是所有broker的队列
msg:发送的消息
arg:发送消息时传递的参数 通过该参数指定发送到哪个队列,对应 String.valueOf(i)
*/
rocketMQTemplate.setMessageQueueSelector((List<MessageQueue> mqs, Message msg, Object arg) -> {
int queueNum = Integer.valueOf(String.valueOf(arg)) % mqs.size();
return mqs.get(queueNum);
});
for (int i = 0; i < 10; i++) {
rocketMQTemplate.syncSendOrderly("TopicName", "顺序消息1:" + i, String.valueOf(i));
rocketMQTemplate.syncSendOrderly("TopicName", "顺序消息2:" + i, String.valueOf(i));
rocketMQTemplate.syncSendOrderly("TopicName", "顺序消息3:" + i, String.valueOf(i));
rocketMQTemplate.syncSendOrderly("TopicName", "顺序消息4:" + i, String.valueOf(i));
rocketMQTemplate.syncSendOrderly("TopicName", "顺序消息5:" + i, String.valueOf(i));
}
}
}
事务消息的监听:
@RocketMQTransactionListener
class TransactionListenerImpl implements RocketMQLocalTransactionListener {
//可以在这里执行业务代码,决定是否提交
private AtomicInteger transactionIndex = new AtomicInteger(0);
private ConcurrentHashMap<String, Integer> localTrans = new ConcurrentHashMap<String, Integer>();
/**
Broker预提交成功后回调Producer的executeLocalTransaction方法
*/
@Override
public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
String transId = (String) msg.getHeaders().get("rocketmq_TRANSACTION_ID");
System.out.println(msg.toString());
int value = transactionIndex.getAndIncrement();
int status = value % 3;
localTrans.put(transId, status);
if (status == 0) {
System.out.println("预提交" + msg.getPayload());
return RocketMQLocalTransactionState.COMMIT;
}
if (status == 1) {
System.out.println("预回滚" + msg.getPayload());
return RocketMQLocalTransactionState.ROLLBACK;
}
System.out.println("预中间");
return RocketMQLocalTransactionState.UNKNOWN;
}
/**
Broker超时未接受到Producer的反馈,会定时重试调用Producer.checkLocalTransaction,Producer会根据自己的执行情况Ack给Broker
*/
@Override
public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
String transId = (String) msg.getHeaders().get("rocketmq_TRANSACTION_ID");
RocketMQLocalTransactionState retState = RocketMQLocalTransactionState.COMMIT;
Integer status = localTrans.get(transId);
if (null != status) {
switch (status) {
case 0:
retState = RocketMQLocalTransactionState.UNKNOWN;
System.out.println("消息状态回查:中间");
break;
case 1:
retState = RocketMQLocalTransactionState.COMMIT;
System.out.println("消息状态回查:提交");
break;
case 2:
retState = RocketMQLocalTransactionState.ROLLBACK;
System.out.println("消息状态回查:回滚");
break;
}
}
System.out.println("---"+transId+retState+status);
return retState;
}
}
消息消费方:
@Component
@RocketMQMessageListener(topic = "TopicName",
consumerGroup = "springboot-mq-consumer-1",
consumeMode = ConsumeMode.ORDERLY,
selectorExpression ="*")
/**
messageModel = MessageModel.BROADCASTING,广播模式,默认是集群模式
consumeMode = ConsumeMode.ORDERLY,顺序消费,默认是并发消费
广播和顺序不可并存
*/
public class Consumer implements RocketMQListener<String> {
@Override
public void onMessage(String message) {
System.out.println("consumer1.1:"+message);
//如果消费失败,则抛出RuntimeException,RocketMQ会自动重试
//可以手动抛出,也可以使用 Lombok 的 @SneakyThrows 注解来抛出 RuntimeException
}
}