消息队列如何保证消息可靠传输
可靠意味着:生产者不重复生产消息(多)、消费者不重复消费消息(多)、消息在传输中不能丢失(少)
1、消息重复:
- 对于生产者,一般不会出现多生产的情况。不过为了配合消费者的重复判断逻辑实现,可以在生成消息时,多加一个全局唯一id,这样消费者在每次拿到消息后根据id判断是否消费过
- 对于消费者,不能重复消费,我们可以通过实现幂等性来实现,或者说即使重复消费了,也不会对结果产生影响(我们也需要从代码的层面去实现,比如数据库的唯一索引)
2、消息丢失
- 生产者发送消息时,一定要确认broker确实接收并完成了持久化工作(RabbitMQ的confirm机制、Kafka的ack机制)
- broker要等待消费者确认已经消费了消息之后再去删除掉此消息
死信队列和延时队列:
- 死信队列:消费者消费失败的消息队列(一般都是重试之后依然失败的消息)
- 延时队列:等待在指定时间之后才可以被消费的队列,比如“已下单代付款”的订单,半小时后如果未付款则取消订单
消息队列有哪些作用:
- 解耦:A、B两系统间不用再相互依赖(不管是接口调用还是数据库读)
- 异步:A给消息队列发完消息就可以不用管B的消费情况,直接去忙自己的
- 消峰:使用消费者pull的模式,在流量极具增加的时候,消息会在消息队列中排队,不会影响消费者的速度
消息队列的优缺点和使用场景:
- 优点:见上一题
- 缺点:
- 增加系统复杂度(幂等、重复消费等问题的处理)
- 系统可