springBoot集成rocketMQ使用

111 阅读2分钟

消息发送方:

@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
    }
}