在ACK重发哪里有疑问
来源:7-26 IM服务中的消息ACK确认机制(下)

qianlan02
2024-12-28
// 为-1时说明已经被清除了。也就是正确收到了
if (retryTimes < 0) {
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
//只支持一次重发
if (retryTimes < 2) {
msgAckCheckService.recordMsgAck(imMsgBody, retryTimes + 1);
msgAckCheckService.sendDelayMsg(imMsgBody);
routerHandlerService.sendMsgToClient(imMsgBody);
} else {
msgAckCheckService.doMsgAck(imMsgBody);
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
为什么重发次数大于等于2的时候我们直接将记录删除,并最终返回了成功?如果没有收到ACK确认的话并不能认为一定成功吧
写回答
1回答
-
Danny_Idea
2024-12-29
if (retryTimes < 2) { msgAckCheckService.recordMsgAck(imMsgBody, retryTimes + 1); msgAckCheckService.sendDelayMsg(imMsgBody); routerHandlerService.sendMsgToClient(imMsgBody); } else { msgAckCheckService.doMsgAck(imMsgBody); }
这里的doMsgAck可能是函数命名的问题容易让人理解有所歧义,它底层的代码如下:
public void doMsgAck(ImMsgBody imMsgBody) { String key = cacheKeyBuilder.buildImAckMapKey(imMsgBody.getUserId(), imMsgBody.getAppId()); redisTemplate.opsForHash().delete(key, imMsgBody.getMsgId()); redisTemplate.expire(key,30, TimeUnit.MINUTES); }
这段代码主要是将之前redis中的记录给删除,避免说如果大量离线用户无法接收消息,则会有大量无用缓存占用redis内存的问题。
其实经过之前一定次数的重试(每次重试都有一定的时间间隔),多次都未能成功,则很可能用户已经是和IM产生断联行为了,再做过多重试的话,意义并不高,因此此时选择放弃重试会更合理一些(删除缓存)。
012024-12-30
相似问题