RocketMQ Producer retry mechanism

version

4.7.1

Features

Insert picture description here

Official website description

The send method of Producer itself supports internal retry, and the retry logic is as follows:

  • Up to 2 multiple attempts.
  • If the sending in synchronous mode fails, it will turn to the next broker. If the sending in asynchronous mode fails, it will only retry in the current broker. The total time of this method does not exceed the value set by sendMsgTimeout, which is 10s by default.
  • If sending a message to the broker itself generates a timeout exception, it will not try again.
    The above strategy also guarantees to a certain extent that the message can be sent successfully. If the business has high requirements for message reliability, it is recommended that the application add corresponding retry logic: for example, when the send synchronization method fails to send, try to store the message in the db, and then retry periodically by the background thread to ensure that the message must arrive at the Broker.

note

  • Asynchronous sending will retry if an exception occurs during the sending process. When parsing the request result, if other exceptions are found in the response status code (the message may not be correctly processed by the broker), the retry will continue, and the current broker will still be selected for retry. But if the response result is not empty, even if an exception occurs while processing the response, it will not be retried.
  • When sending synchronously, if there is no abnormality in the sending process, but the sending result is not OK, another broker will be selected to continue the retry (you need to open this configuration item: retryAnotherBrokerWhenNotStoreOK)
  • The sequence message fails to be retryed, and the sequence message refers to the synchronization + designated message queue.
  • Sending in asynchronous + designated message queue is not considered as sequential sending, because asynchronous sending cannot guarantee the order of messages. Although there is an exception during the sending process, no retry will be made, but the processing logic after sending is the same as the asynchronous method. If the specified conditions are not met, the retry will be continued, and the synchronous and asynchronous sending process
  • The one-way method is special because it does not wait for the result, so it is different from other methods. There is no such thing as waiting for the result to return before considering whether to continue retrying, but when sending is the same as synchronous sending, the exception will be retried.

Retry logic code

重试逻辑在:源码org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl#sendDefaultImpl(Message msg,final CommunicationMode communicationMode,final SendCallback sendCallback,final long timeout)

Message sending process: send message->sendDefaultImpl->sendKernelImpl, the logic of retry is in sendDefaultImpl, send failed to retry, will call sendKernelImpl again to send the message
order message reason why the message is not retried: sequence sending process: send message->sendKernelImpl , So there is no retry logic.
Message sending retry When queue selection, if there are multiple broker masters, the next retry broker is different from the last one

Producer flow control retry

Messages that failed to be sent due to flow control will not be retried. The following is an excerpt from the official documentation:

Producer flow control, because the processing capacity of the broker reaches the bottleneck; consumer flow control, because the consumption capacity reaches the bottleneck. Producer flow control:

  • When the commitLog file is locked for longer than osPageCacheBusyTimeOutMills, the parameter defaults to 1000ms, and the flow control is returned.
  • If transientStorePoolEnable == true is enabled, and the broker is the host for asynchronous flash disk, and the resources in the transientStorePool are insufficient, the current send request is rejected and flow control is returned.
  • The broker checks the waiting time of the request at the head of the send request queue every 10ms. If it exceeds waitTimeMillsInSendQueue, the default is 200ms, rejects the current send request and returns to flow control.
  • The broker implements flow control by rejecting send requests. Note that the producer flow control will not try to retransmit the message. Consumer flow control:
  • When the number of messages cached locally by the consumer exceeds pullThresholdForQueue, the default is 1000.
  • When the consumer's local cache message size exceeds pullThresholdSizeForQueue, the default is 100MB.
  • When the consumer local cache message span exceeds consumeConcurrentlyMaxSpan, the default is 2000. The result of consumer flow control is to reduce the frequency of pull.

Exception allowing retry when sending

•	RemotingException
•	MQClientException
•	MQBrokerException,如下响应码不重试:
         case ResponseCode.TOPIC_NOT_EXIST:
        case ResponseCode.SERVICE_NOT_AVAILABLE:
        case ResponseCode.SYSTEM_ERROR:
        case ResponseCode.NO_PERMISSION:
        case ResponseCode.NO_BUYER_ID:
        case ResponseCode.NOT_IN_CURRENT_UNIT:

Do not retry in other cases

MQBrokerException is in the message sending result, the sending status is not OK (status code is not ResponseCode.FLUSH_DISK_TIMEOUT, ResponseCode.FLUSH_SLAVE_TIMEOUT, ResponseCode.SLAVE_NOT_AVAILABLE, ResponseCode.SUCCESS), this exception will be thrown.
So this is the reason why the flow control does not retry. The status code returned by the broker flow control: RemotingSysResponseCode.SYSTEM_BUSY

Guess you like

Origin blog.csdn.net/x763795151/article/details/113270910