by shihang.mai
1. 消息不丢失
首先需要知道
- producer发送msg给broker,broker返回ack给producer
- consumer向broker拉取消息,处理成功,返回ack给broker
1.1 从producer-broker分析
生产者只要接收到返回的确认响应,就代表消息在生产阶段未丢失。
利用同步发送、异步发送,等待ack状态,ack状态包括
- SendStatus.SEND_OK
- SendStatus.FLUSH_DISK_TIMEOUT
- SendStatus.FLUSH_SLAVE_TIMEOUT
- SendStatus.SLAVE_NOT_AVAILABLE
无论用哪种形式发送,设置重试一定次数
1.2 broker自身
1.2.1 设置同步刷盘
默认:消息只要到了 Broker 端,将会优先保存到内存中,然后立刻返回ack给producer。随后 Broker 定期批量的将一组消息从内存异步刷入磁盘。
若想保证 Broker 端不丢消息,保证消息的可靠性,我们需要将消息保存机制修改为同步刷盘方式,即消息存储磁盘成功,才会返回ack给producer
## 默认情况为ASYNC_FLUSH,异步刷盘
flushDiskType = SYNC_FLUSH
若 Broker 未在同步刷盘时间内(默认为 5s)完成刷盘,将会返回 SendStatus.FLUSH_DISK_TIMEOUT 状态给生产者。
1.2.2 设置salve同步复制
默认:消息写入 master 成功,就可以返回ack给producer,接着消息将会异步复制到 slave 节点
master 节点将会同步等待 slave 节点复制完成,才会返回ack给producer
## master节点配置
## 默认为 ASYNC_MASTER
brokerRole=SYNC_MASTER
1.2.3 小结
严格保证息不丢失,可采取如下措施
master端
#设置同步刷盘才返回ack给producer
flushDiskType = SYNC_FLUSH
#设置同步消息给salve
brokerRole=SYNC_MASTER
salve端
#角色为salve
brokerRole=slave
#设置同步刷盘才返回ack给master
flushDiskType = SYNC_FLUSH
生产者判断ack返回状态是否是SendStatus.SEND_OK
,如果是其他状态,重试发送
1.3 从broker-consumer分析
只有当业务逻辑真正执行成功,我们才返回 ConsumeConcurrentlyStatus.CONSUME_SUCCESS。否则我们需要返回 ConsumeConcurrentlyStatus.RECONSUME_LATER,稍后再重试即可
2. 幂等
利用幂等令牌.幂等令牌时指生产者和消费者两者中的既定协议.在业务中通常是具备唯一业务标识的字符串,如:订单号、流水号等。且一般由生产者端生成并传递给消费者端
在消费端操作业务之前,先判断缓存中是否有幂等令牌,如果有直接返回消费成功,否则进行业务操作
在插入库的时候,通过唯一键做最后一道幂等防线
参考博客:
https://www.cnblogs.com/goodAndyxublog/p/12563813.html