消息不丢失
Producer-----【1】—>broker----【2】—>consumer
可能会丢失数据的阶段:
- 生产者发送消息到broker
- broker收到后放在内存中,还没来得及刷磁盘挂了
- 消费者消费数据失败
针对不同的情况的解决方式
- 发送到broker失败引起丢失:** 采用同步重试发送,等待broker响应ack,发送失败可以重试几次**
- broker宕机引起的丢失:
** 可以改成同步刷盘机制(默认是异步),收到消息后先持久化到磁盘以后再返回ack消息给producer **
** 主从机制,等消息都同步到slave再通知producer** - 消费失败引起的丢失:** 消费成功后返回ack成功通知,消费失败配置消息重试**
.
重复消费
做好消费者接口的幂等性
- 比如比较重要的场景,例如跟钱相关的用强校验,直接用数据库打标记作为记录,消息是否已经被消费过
- 不是很重要的场景,例如发送短信、邮件通知等使用弱校验,在redis里面打个标记,设置过期时间,一段时间内不会重复消费
顺序消费
发送端
比如同一个业务多个操作具有顺序性,使用业务中共有的唯一id标志,hash以后发送到同一个队列里面去 MessageQueueSelector的实现 SelectMessageQueueByHash ,用业务id进行hash取模将多个操作发送到一个队列里面去
消费端
使用 MessageListenerOrderly进行顺序消费