RabbitMQ如何保证消息可靠性?
首先RabbirMQ是一个开源的支持多协议的性能优秀的消息中间件,他的消息可靠性,消息延迟以及可用性比较高,但是单机消息吞吐量比较一般。
消息的可靠性是指,消息准确无误的到达消费者手中,不能出现消息的丢失等问题,消息丢失又分为:①生产者发送消息为到达交换机,②消息到达交换机,没有路由到正确的队列,③MQ宕机,队列的消息不见了,④消费者收到消息,还没消费完消费者宕机等几种情况,针对这些问题MQ提供了,生产者确认机制,持久化机制,消费者ack机制等措施来解决。
生产者确认机制:1、生产者开启confirm机制,,一旦消息进入confirm机制,所有在该机制上面发布的消息都会被指派唯一id(从1开始),生产者发送确认消息后,交换机收到消息会执行回调函数,告诉生产者,消息成功投递到交换机中。
2、生产者开启return机制,说的是当消息到达交换机后,但是没有找到匹配的对列时,将消息退回给生产者,默认情况下,如果消息没有匹配到队列会直接被丢弃,采用return机制可以在生产者端监听该消息是否被成功投递到队列中,保证消息正确到达队列。
持久化机制:就是把交换机、队列、消息进行持久化。
交换机持久化,交换机负责将消息路由到队列中,因此对于保证消息的持久化至关重要,在默认的情况下就是持久化。
队列持久化:就是在RabbitMQ重启后保证队列不会丢失,但是并不能保证消息的持久化,默认情况下也是持久化状态。
消息持久化:指消息在发送和接受的过程中,确保消息在系统异常情况下不会丢失,为了实现消息的持久化,需要在发送消息时设置delivery_mode的属性为持久化,这样消息在被发送到交换机后,会被储存到磁盘上的持久化队列中,即使RabbitMQ服务器发生故障,消息也能够得到保留。
消费者ack机制:消费者ack机制分为三种模式,手动ack 自动ack,还有一种none ack一般不用这种,他是只要消息到达了消费者就会返回ack,
手动ack,当消费者消费成功后会返回ack,当消费者消费不成功一致返回nack,把消息放回队列,继续给消费者消费,直到消费成功。
自动 ack,一般搭配重试耗尽的失败策略,定义错误交换机队列,就是在配置上加上重试的次数,当重试的次数达到设定的值后,就会进入错误的交换机,把这一消息存入数据库或者日志中,后期人为解决。
消息重复消费
多个消费者,其中一个消费者消费信息后没有通知队列(没有给mq发ack,或者给mq发ack的过程中挂了、失败了),队列又把消息发给了其他消费者就会重复消费。
消费者的操作不是幂等性操作,幂等性操作就是多次消费消息,除开对性能的影响外,其他没有什么大问题。对于非幂等性的操作,多次消费消息会造成数据的一致性的问题,所以要保证重复消费消息的问题。
怎么解决呢,可以使用redis来进行判断消息是否被消费,如果消息被消费,那么在交换机在把这一个消息发送给另一个消费者后,这和消费者不会有任何动作,如果没有就直接消费。
消息积压问题
生产者生产消息的速度 远高于 消费者消费消息的速度?于是就会造成消息积压在MQ中。
产生堆积的原因有,消费者出现异常,可以修改消费者的代码,让消费者正常工作。
消费者宕机了,修复消费者宕机情况,在临时的开几个消费者,以多倍速消费积压的消息,当积压的消息消费的差不多的情况,关闭消费者。
也可以使用惰性队列,他接受到消息后会直接存在磁盘而非内存,消费者要消费消息时才会从磁盘中读取并加载到内存,支持数百万条的消息存储。
死信交换机
当消息过期超时无人消费,要投递队列信息堆满了,最早的消息成为死信,当该队列配置了死信后的交换机,那么队列中死信就会投递到这个交换机中,这种间换机称为死信交换机。
标签:可靠性,持久,消费者,队列,ack,交换机,MQ,消息 From: https://www.cnblogs.com/szza/p/17702705.html