版本:4.2.0
producer的重试机制分两种情况:同步发送,异步发送
同步发送:
private SendResult sendDefaultImpl(Message msg, CommunicationMode communicationMode, SendCallback sendCallback, long timeout) throws MQClientException, RemotingException, MQBrokerException, InterruptedException { ... if (topicPublishInfo != null && topicPublishInfo.ok()) { MessageQueue mq = null; Exception exception = null; SendResult sendResult = null; // 同步发送的次数,默认三次,这里异步发送的次数为1,实际发送次数在回调里面 int timesTotal = communicationMode == CommunicationMode.SYNC ? 1 + this.defaultMQProducer.getRetryTimesWhenSendFailed() : 1; int times = 0; String[] brokersSent = new String[timesTotal]; while(true) { String info; // 通过循环来实现重试机制 if (times < timesTotal) { info = null == mq ? null : mq.getBrokerName(); MessageQueue mqSelected = this.selectOneMessageQueue(topicPublishInfo, info); if (mqSelected != null) { mq = mqSelected; brokersSent[times] = mqSelected.getBrokerName(); long endTimestamp; try { beginTimestampPrev = System.currentTimeMillis(); sendResult = this.sendKernelImpl(msg, mq, communicationMode, sendCallback, topicPublishInfo, timeout); endTimestamp = System.currentTimeMillis(); this.updateFaultItem(mq.getBrokerName(), endTimestamp - beginTimestampPrev, false); switch(communicationMode) { case ASYNC: return null; case ONEWAY: return null; case SYNC: // 如果没有开启retryAnotherBrokerWhenNotStoreOK配置项,则不会重试 if (sendResult.getSendStatus() == SendStatus.SEND_OK || !this.defaultMQProducer.isRetryAnotherBrokerWhenNotStoreOK()) { return sendResult; } } } catch (RemotingException var24) { endTimestamp = System.currentTimeMillis(); this.updateFaultItem(mqSelected.getBrokerName(), endTimestamp - beginTimestampPrev, true); this.log.warn(String.format("sendKernelImpl exception, resend at once, InvokeID: %s, RT: %sms, Broker: %s", invokeID, endTimestamp - beginTimestampPrev, mqSelected), var24);