这里总结一下rocketmq常见的一些问题,后续还会补充。
消息重复消费问题:
rocketmq消息重复消费问题无非就是消息发送的时候,broker没有返回确认消息导致发送方重新发送消息,或者采用集群模式有多个组导致消息被每个组消费一次导致重复消费。 解决办法:实现幂等,可以把消息特有的id记录到第三方中比如redis来实现消息幂等。
保证消息发送顺序问题:
我们都知道rocketmq的一个topic底层默认有4个queue,因此想要完全保证顺序发送消息需要满足这些条件,1.同一个topic2.同一个queue3.一个线程去发送消息
案例:
消息发送方:
//选择queue来发送消息
/*
* message:消息
* queue选择器
* 传给queue选择器的参数
* 超时时间
*/
producer.send(message, new MessageQueueSelector() {
public MessageQueue select(List<MessageQueue> list, Message message, Object arg) {
return list.get(Integer.valueOf(arg.toString()));
}
},1,3000);
消息消费方:
//MessageListenerConcurrently 并发消费,一个queue可能开启多个线程
consumer.registerMessageListener(new MessageListenerConcurrently() {
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
for (MessageExt msg : msgs) {
byte[] body = msg.getBody();
System.out.println(new String(body));
}
//如果不确认能否消费消息
if("1".equals("2")){
return ConsumeConcurrentlyStatus.RECONSUME_LATER;
}
//默认情况下,这条消息只会被一个consumer消费 点对点
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
//MessageListenerOrderly 顺序消费,一个queue开启一个线程
//设置最大开启线程数
consumer.setConsumeThreadMax(1);
//设置最小开启线程数
consumer.setConsumeThreadMin(1);
consumer.registerMessageListener(new MessageListenerOrderly() {
public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext consumeOrderlyContext) {
for (MessageExt msg : msgs) {
byte[] body = msg.getBody();
System.out.println(new String(body));
}
//默认情况下,这条消息只会被一个consumer消费 点对点
return ConsumeOrderlyStatus.SUCCESS;
}
});