Java 重试机制导致重复消费_RocketMQ-消费重试机制

本文详细介绍了RocketMQ的Producer和Consumer端重试机制。Producer端默认有3次重试机会,Consumer端在异常情况下会重试16次,超时则会无限次重试。消费者可以通过检查消息的`reconsumeTimes`字段来控制重试次数,防止重复消费。此外,文章还探讨了Consumer集群中消息超时的处理情况。
摘要由CSDN通过智能技术生成

介绍:

RocketMQ的消息重试及时分为两种,一种是Producer端重试,一种是Consume端重试。

1、Producer端重试 :

1.1消息发没发成功,默认情况下是3次重试。

2、Consumer端重试:

2.1 exception的情况,一般重复16次 10s、30s、1mins、2mins、3mins等。注意reconsumeTimes这个参数;

2.2 超时情况,这种情况MQ会无限制的发送给消费端。这种情况就是Consumer端没有返回ConsumeConcurrentlyStatus.CONSUME_SUCCESS,也没有返回ConsumeConcurrentlyStatus.RECONSUME_LATER。Consumner超时的情况我们还分为一个Producer和一个Consumer的场景和一个Producer和多个Consumer(Consumer集群)的场景。下面的实例中我们会详细的做实验。

问题,Consumer的默认超时时间是多少?

示例:

Producer端重试

producer端重试的机制比较简单,我们通过看一下源码可以发现,通过设置retryTimesWhenSendFailed定义重试次数,通过设置sendMsgTimeout来定义超时时间

producer.setRetryTimesWhenSendFailed(3); //默认是2

producer.setSendMsgTimeout(6000); //默认是3000

packageorg.hope.lee.producer;importcom.alibaba.rocketmq.client.exception.MQBrokerException;importcom.alibaba.rocketmq.client.exception.MQClientException;importcom.alibaba.rocketmq.client.producer.DefaultMQProducer;importcom.alibaba.rocketmq.client.producer.SendCallback;importcom.alibaba.rocketmq.client.producer.SendResult;importcom.alibaba.rocketmq.common.message.Message;importcom.alibaba.rocketmq.common.message.MessageQueue;importcom.alibaba.rocketmq.remoting.exception.RemotingException;public classProducer {public static voidmain(String[] args) {

DefaultMQProducer producer= new DefaultMQProducer("push_consumer");//producer.setNamesrvAddr("192.168.31.176:9876");

producer.setNamesrvAddr("192.168.31.176:9876;192.168.31.165:9876");try{//设置实例名称

producer.setInstanceName("quick_start_producer");//设置重试次数,默认2

producer.setRetryTimesWhenSendFailed(3);//设置发送超时时间,默认是3000

producer.setSendMsgTimeout(6000);//开启生产者

producer.start();//创建一条消息

Message msg = new Message("PushTopic_tt1", "TagB", "OrderID0034", "uniform_just_for_test".getBytes());

SendResult send =producer.send(msg);

System.out.println("id:--->" + send.getMsgId() + ",result:--->" +send.getSendStatus());}catch(MQClientException e) {

e.printStackTrace();

}catch(RemotingException e) {

e.printStackTrace();

}catch(MQBrokerException e) {

e.printStackTrace();

}catch(InterruptedException e) {

e.printStackTrace();

}

producer.shutdown();

}

}

Consumer端exception的情况。

Producer端发送消息:

packageorg.hope.lee.producer;importcom.alibaba.rocketmq.client.exception.MQBrokerException;importcom.alibaba.rocketmq.client.exception.MQClientException;importcom.alibaba.rocketmq.client.producer.DefaultMQProducer;importcom.alibaba.rocketmq.client.producer.SendCallback;importcom.alibaba.rocketmq.client.producer.SendResult;importcom.alibaba.rocketmq.common.message.Message;importcom.alibaba.rocketmq.common.message.MessageQueue;importcom.alibaba.rocketmq.remoting.exception.RemotingException;public classProducerException {public static voidmain(String[] args) {

DefaultMQProducer producer= new DefaultMQProducer("push_consumer");

producer.setNamesrvAddr("192.168.31.176:9876;192.168.31.165:9876");try{

producer.setInstanceName("quick_start_producer");

producer.setRetryTimesWhenSendFailed(3);

producer.start();for(int i = 0; i < 10; i++) {

Message msg= new Message("PushTopic_tt1", "TagA", "OrderID0034", ("message" +i).getBytes());//目前发现3.2.6版本没有这个方法,3.5.3版本有这个方法,并且必须要设置为false否则会报错//producer.setVipChannelEnabled(false);

SendResult send =producer.send(msg);

System.out.println("id:--->" + send.getMsgId() + ",result:--->" +send.getSendStatus());

}

}catch(MQClientException e) {

e.printStackTrace();

}catch(RemotingException e) {

e.printStackTrace();

}catch(MQBrokerException e) {

e.printStackTrace();

}catch(InterruptedException e) {

e.printStackTrace();

}

producer.shutdown();

}

}

Consumer端接收消息

packageorg.hope.lee.consumer;importjava.util.List;importcom.alibaba.rocketmq.client.consumer.DefaultMQPushConsumer;importcom.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;importcom.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;importcom.alibaba.rocketmq.client.consumer.listener.MessageListener;importcom.alibaba.rocketmq.client.consumer.listener.MessageListenerConcurrently;importcom.alibaba.rocketmq.client.exception.MQClientException;importcom.alibaba.rocketmq.client.producer.DefaultMQProducer;importcom.alibaba.rocketmq.common.consumer.ConsumeFromWhere;importcom.alibaba.rocketmq.common.message.MessageExt;importcom.sun.org.apache.xpath.internal.SourceTree;/*** 消费端重试的情况 :异常情况*/

public classConsumerException {public static void main(String[] args) throwsMQClientException {

DefaultMQPushConsumer consumer= new DefaultMQPushConsumer("push_consumer");

consumer.setNamesrvAddr("192.168.31.176:9876;192.168.31.165:9876");//批量消费,每次拉取10条

consumer.setConsumeMessageBatchMaxSize(10);//①//consumer.setInstanceName("quick_start_consumer");//3.2.6这个版本没有这个方法,3.5.3版本要设置这个方法为false,否则取不到topic//consumer.setVipChannelEnabled(false);//程序第一次启动从消息队列头取数据//如果非第一次启动,那么按照上次消费的位置继续消费

consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);//订阅PushTopic下Tag为push的消息

consumer.subscribe("PushTopic_tt1", "*");

consumer.registerMessageListener(newMessageListenerConcurrently() {public ConsumeConcurrentlyStatus consumeMessage(Listmsgs, ConsumeConcurrentlyContext context) {

MessageExt msg= msgs.get(0);try{

String topic=msg.getTopic();

String msgBody= new String(msg.getBody(), "utf-8&#

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值