介绍:
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&#