Article catalog
Message queue RocketMQ: (I) overview
Message queuing RocketMQ: (II) system architecture
Message queue RocketMQ: (III) sending ordinary messages (three methods)
Message queue RocketMQ: (IV) sequential messages
Message queue RocketMQ: (V) delay message
Message queue RocketMQ: (VII) batch messages
Message queue RocketMQ: (VIII) message filtering
7, Message sending retry
Producer's mechanism for resending failed messages is called message sending retry mechanism, also known as message re delivery mechanism.
For message re delivery, you should pay attention to the following points:
- If the producer sends messages synchronously or asynchronously, the sending failure will be retried, but there is no retry mechanism for the sending failure of oneway message
- Only ordinary messages have a send retry mechanism, and sequential messages do not
- The message re delivery mechanism can ensure that the message is sent successfully and not lost as much as possible, but it may cause message duplication. Message duplication does not occur under normal circumstances. When there is a large amount of messages and network jitter, message duplication will become a probability event
There are three strategies for message sending retry: synchronous sending failure strategy, asynchronous sending failure strategy and message disk brushing failure strategy
1. Synchronous sending failure policy
For ordinary messages, the round robin strategy is adopted by default to select the queue to send messages. If the sending fails, it will retry 2 times by default. However, when retrying, the Broker that failed to send last time will not be selected, but other brokers will be selected.
DefaultMQProducer producer = new DefaultMQProducer("pg"); producer.setNamesrvAddr("rocketmqOS:9876"); // Set the number of times to retry sending when synchronous sending fails. The default is 2 times producer.setRetryTimesWhenSendFailed(3); // Set the sending timeout to 5s, and the default is 3s producer.setSendMsgTimeout(5000);
If the number of retries exceeds, an exception will be thrown, and the Producer will ensure that the message is not lost.
When RemotingException, MQClientException and MQBrokerException occur in the Producer, the Producer will automatically resend the message.
2. Asynchronous send failure policy
When the asynchronous sending fails to retry, the asynchronous retry will not select other brokers, but only retry on the current Broker, so this policy cannot guarantee that the message will not be lost.
DefaultMQProducer producer = new DefaultMQProducer("pg"); producer.setNamesrvAddr("rocketmqOS:9876"); // Specifies that no retry sending will be performed after asynchronous sending fails producer.setRetryTimesWhenSendAsyncFailed(0);
3. Message disk brushing failure policy
Message swiping timeout (Master, Slave). By default, messages will not be sent to other brokers. For important messages, you can enable it by setting the retryAnotherBrokerWhenNotStoreOK property to true in the Broker's configuration file.
8, Message consumption retry
After the consumer fails to consume a message, the message will be re delivered according to the message retry mechanism. If the message has not been successfully consumed after reaching the retry times, the message will be put into the dead letter queue.
No matter how many times a message is retried, the Message ID of these retried messages will not change
1. Retry consumption of sequential messages
Sequential message: after the Consumer fails to consume the message, in order to ensure the order of the message, it will automatically retry the message continuously until the consumption is successful. The default interval between consumption retries is 1000ms. During retry, the application will be blocked in message consumption.
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("cg"); // The consumption retry time interval of sequential message consumption failure, in milliseconds, the default is 1000, and its value range is [10, 30000] consumer.setSuspendCurrentQueueTimeMillis(100);
Since the retry of sequential messages is endless and uninterrupted until the consumption is successful, for the consumption of sequential messages, it is important to ensure that the application can timely monitor and handle the consumption failure, so as to avoid permanent blocking of consumption.
Note: the sequence message does not have a send failure retry mechanism, but has a consumption failure retry mechanism
2. Consumption retry of unordered messages
For unordered messages (normal messages, delayed messages, transaction messages), when the Consumer fails to consume messages, the message retry effect can be achieved by setting the return status.
Note: the retry of unordered messages only takes effect for the cluster consumption mode; The broadcast consumption mode does not provide failure retry feature, that is, after consumption fails, the failure message will not be retried and new messages will continue to be consumed.
For retry consumption under disordered message cluster consumption, each message is allowed to be retried up to 16 times by default. If the message still fails after 16 retries, the message will be delivered to the dead letter queue. The message retry interval is as follows:
retry count | Time between last retry | retry count | Time between last retry |
---|---|---|---|
1 | 10 seconds | 9 | 7 minutes |
2 | 30 seconds | 10 | 8 minutes |
3 | 1 minute | 11 | 9 minutes |
4 | 2 minutes | 12 | 10 minutes |
5 | 3 minutes | 13 | 20 minutes |
6 | 4 minutes | 14 | 30 Minutes |
7 | 5 minutes | 15 | 1 hour |
8 | 6 minutes | 16 | 2 hours |
If a message fails to consume all the time, it will be retried 16 times in the next 4 hours and 46 minutes. Beyond this time range, the message will not be retried and will be delivered to the dead letter queue.
Modify consumption retry times:
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("cg"); // Modify consumption retry times consumer.setMaxReconsumeTimes(10);
3. Maximum number of retries for custom messages
Allow the maximum number of retries to be set when the Consumer starts. The retry interval will follow the following policy:
- If the maximum number of retries is less than or equal to 16, the retry interval is described in the table above
- The maximum number of retries is more than 16, and the retry interval of more than 16 times is 2 hours each time
- The setting of the maximum number of message retries is valid for all Consumer instances under the same Group ID
- If only one of the two Consumer instances under the same Group ID is set, the configuration will take effect for both Consumer instances
- The configuration takes effect by overwriting, that is, the last started Consumer instance will overwrite the configuration of the previously started instance
4. Consumption retry configuration
In the cluster consumption mode, if the message consumption fails and the message is expected to be retried later, it needs to be explicitly configured in the implementation of the message listener interface (choose one of the three methods):
- Return consumeconcurrantlystatus RECONSUME_ Later (recommended)
- Return Null
- Throw exception
consumer.registerMessageListener(new MessageListenerConcurrently() { @Override public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) { //The message processing logic throws an exception and the message will be retried. doConsumeMessage(message); //Method 1: return action Reconsumelater, the message will be retried. return ConsumeConcurrentlyStatus.RECONSUME_LATER; //Method 2: return null and the message will be retried. return null; //Method 3: throw an exception directly and the message will be retried. throw new RuntimeException("Consumer Message exception"); } });
5. Consumption does not retry configuration
In the cluster consumption mode, if the message fails, it is expected that the message will not be retried. You need to catch the exceptions that may be thrown in the consumption logic and finally return consumeconcurrentystatus CONSUME_ Success, this message will not be retried after that.
consumer.registerMessageListener(new MessageListenerConcurrently() { @Override public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) { try { doConsumeMessage(message); } catch (Throwable e) { //Catch all exceptions in the consumption logic and return consumeconcurrantlystatus CONSUME_ SUCCESS return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } //The message processing is normal, and the consumption success is returned directly return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } });
6. Get message retries
After receiving the message, the consumer can obtain the number of retries of the message in the following ways:
@Override public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) { for (MessageExt msg : msgs) { //Gets the number of retries for the message. System.out.println(msg.getReconsumeTimes()); } return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; }
9, Dead letter queue
When the first consumption of a message fails, the message queue will automatically retry the consumption; After reaching the maximum number of retries, if the consumption still fails, it indicates that the consumer cannot correctly consume the message under normal circumstances. At this time, the message queue will not immediately discard the message, but send it to the special queue corresponding to the consumer.
Under normal circumstances, messages that cannot be consumed are called dead letter messages, and the special queue for storing dead letter messages is called dead letter queue.
1. Dead letter message features
- It will no longer be consumed normally by consumers
- The validity period is the same as the normal message, which is 3 days. It will be deleted automatically after 3 days
2. Dead letter queue feature
- A dead letter queue corresponds to a Group ID instead of a single consumer instance. Name is% DLQ%consumerGroup@consumerGroup
- If a Group ID does not produce a dead letter message, the corresponding dead letter queue will not be created
- A dead letter queue contains all dead letter messages generated by the corresponding Group ID, no matter which Topic the message belongs to