消息队列
消息队列的关注点
- 消息不丢
- 消息可堆积
如何保证消息不丢?
消息队列的三个组成部分:生产者、消息队列、消费者
因此消息是否会发生丢失,在于以下三个环节
- 生产者会不会丢数据
- 消费者会不会丢数据
- 消息中间件会不会丢数据
生产者丢消息
当生产者在发布消息时,可能会发生
- 消息没有发出去:网络故障或其它问题导致发布失败,中间件直接返回失败
- 消息发了出去:网络问题导致发布超时,可能数据已发送成功,也可能没有发送成功。比如数据已发送成功,但读取响应结果超时了
针对上面的方式,都可以采用重发的方式进行处理。宁可重发也不能丢失。
生产者都会通过设置一个最大重试次数,超过上限,就需要记录日志报警处理
重发之后,消费者会引入一个新的问题,就是有可能会收到多条重复的消息。这时消费就需要对重复的消息进行处理,保证消息的幂等性,即处理多条同样的消息会有相同的结果
消费者丢消息
消费者拿到消息后,还没处理完就异常宕机了。这时候,消费者是否还能重新接收到处理失败数据?
解决这个问题,需要消费者在处理完消息后,必须通知队列中间件,队列中间件才会把处理完成的数据标记为处理,否则仍然将这些数据发送给消费者。
队列中间件会不会丢数据
消息中间件必须在宕机的时候,保证原本消息队列里的数据在中间件恢复的时候依旧存在。或者通过集群的方式保证某一结点挂了,集群的数据不丢失。
消息可堆积
消息存储在内存或者是硬盘中,如果存储在内存中的话,如果消息过多,当内存不够的时候,超过堆积上线的消息将会丢失。
当消息堆积时,一般有两种解决方案:
- 生产者限流,避免消费者处理不及时,导致持续积压
- 丢弃消息:中间件丢弃旧的消息,只保留固定长度的消息