生产者
1.同步发送
SendStatus stockSendStatus = rocketMqTemplate.syncSend(RocketTopic.SYNC_TOPIC,new GenericMessage<>("测试同步发送")).getSendStatus(
if (!Objects.equals(stockSendStatus,SendStatus.SEND_OK)) { // 消息发不出去就抛异常,发的出去无所谓 throw new RuntimeException("发送失败"); }
2.延迟发送消息
// 1m后发送 SendStatus sendStatus = rocketMqTemplate.syncSend(RocketTopic.SYNC_TOPIC, new GenericMessage<>("测试延迟消息"), 3000, 5).getSendStatus(); if (!Objects.equals(sendStatus,SendStatus.SEND_OK)) { // 消息发不出去就抛异常,发的出去无所谓 throw new RuntimeException("发送失败"); }
3.异步发送消息
rocketMqTemplate.asyncSend(RocketTopic.ASYNC_TOPIC, new GenericMessage<>("异步发送消息"), new SendCallback() { @Override public void onSuccess(SendResult sendResult) { System.out.println("异步消息 发送成功"); } @Override public void onException(Throwable throwable) { System.out.println("异步消息 发送失败"); } });
rocketMqTemplate.asyncSend(RocketTopic.ASYNC_TOPIC, new GenericMessage<>("异步发送消息"), new SendCallback() { @Override public void onSuccess(SendResult sendResult) { System.out.println("异步消息 发送成功"); } @Override public void onException(Throwable throwable) { System.out.println("异步消息 发送失败"); } },3000); //自定义发送失败时间,不填使用默认值
4.单向消息
是指producer向 broker发送消息,执行API时直接返回,不等待broker 服务器的响应
rocketMqTemplate.sendOneWay(RocketTopic.ASYNC_TOPIC,new GenericMessage<>("单项消息发送"));
5.顺序消息
rocketMqTemplate.syncSendOrderly(RocketTopic.SYNC_TOPIC_ORDERLY,"1001消息创建--1","1001"); rocketMqTemplate.syncSendOrderly(RocketTopic.SYNC_TOPIC_ORDERLY,"1001消息创建--2","1001"); rocketMqTemplate.syncSendOrderly(RocketTopic.SYNC_TOPIC_ORDERLY,"1001消息创建--3","1001"); rocketMqTemplate.syncSendOrderly(RocketTopic.SYNC_TOPIC_ORDERLY,"1002消息创建--1","1002"); rocketMqTemplate.syncSendOrderly(RocketTopic.SYNC_TOPIC_ORDERLY,"1002消息创建--2","1002"); rocketMqTemplate.syncSendOrderly(RocketTopic.SYNC_TOPIC_ORDERLY,"1002消息创建--3","1002");
消费者
1.顺序消息的消费者
consumeMode = ConsumeMode.ORDERLY //设置为单线程消费
@Component @RocketMQMessageListener(topic = RocketTopic.SYNC_TOPIC_ORDERLY,consumerGroup = RocketTopic.SYNC_TOPIC_ORDERLY, consumeMode = ConsumeMode.ORDERLY ) public class SyncSendOrderlyListener implements RocketMQListener{ @Override public void onMessage(String s) { System.out.println(s); } }
2.集群消费者
messageModel = MessageModel.CLUSTERING //没有设置 默认集群
@Component @RocketMQMessageListener(topic = RocketTopic.SYNC_TOPIC,consumerGroup = RocketTopic.SYNC_TOPIC_ORDERLY, messageModel = MessageModel.CLUSTERING ) public class SyncSendConsumer implements RocketMQListener{ }
常见问题及解决
1.rocketmq怎么解决消息重复消费。
因为rocketmq执行至少发送一次的形式,所以不可避免的就会出现消息重复发送,所以在发送端无法做到,只能在消费端做端,可以采用消费端幂等性设计:实现幂等性的方式有很多,比如在业务系统中为每条消息生成唯一的处理 ID,并将处理结果保存在数据库中,当重复消费时,在数据库中查询该消息是否已经被处理过;或者数据库产生唯一性标志,当消费后重新消费插入时报错。
2.rocketmq怎么解决消息堆积
可以从以下几点出发考虑:消费者并发度调整,可以提高consumer的线程数或并发度,调整消费者消费模式,在 Push 模式下,消息到达后立即推送给 Consumer 进行处理,适用于对实时性要求较高的场景。在 Pull 模式下,Consumer 主动向 Broker 获取消息,适用于对延迟要求不高但吞吐量大的场景。选择合适的消费模式可以帮助解决消息堆积问题。线上出现这个问题后 先限流,然后扩容,临时写个分发消息的程序,将积累的消息直接均匀轮询写入临时建好的queue里面,然后再扩容重新部署consumer,加快消费,处理完后,重复恢复原来架构。
3.rocketmq怎么防止消息丢失
防止消息丢失要从多方面考虑,生产者可以使用同步生产或者事务消息进行生产消息,但这样性能就有所下降,设置为同步刷盘,RocketMQ 将 Producer 发送的消息首先写入内存中的 PageCache,再定时将 PageCache 中的消息异步刷写到磁盘中。为了保证消息不丢失,可以在发送消息时设置 Message #setWaitStoreMsgOK(true)
,让 Producer 在消息写入 PageCache 并成功刷盘后才返回发送结果。