什么是RabbitMQ?为什么使用RabbitMQ?
RabbitMQ是一款开源,使用Erlang编写的,基于AMQP协议的消息中间件;
RabbitMQ有什么优缺点?
优点:解耦、异步、削峰;
缺点:降低系统稳定性,毕竟加入了消息队列,如果消息队列挂了,系统就凉了,所以系统稳定性就降低了;
增加了系统的复杂性:加入了消息队列要考虑很多问题,比如:一致性问题、如何保证消息不会被重复消费、如何保证消息可靠性传输等。这个时候需要考虑的东西就很多了。
如何保证RabbitMQ的高可用
使用RabbitMQ集群,线上通常使用集群来做
如何保证RabbitMQ不被重复消费
重复消费:
重复消费是指在RabbitMQ正常的情况下,消费端消费了消息之后发送确认消息给MQ,
MQ收到确认消息就将对应的消息从队列中删除,而这里可能回出现几种情况:
1.消费端消费消息不成功,消费者自身出错,无法发送确认消息给MQ;
2.消费端消费消息完成,但是由于网络原因或者其他原因,消息无法到达MQ;
以上可出现的故障可能导致MQ将消息分发给别的消费者,导致重复消费;
要解决上面的问题,需要保证消息的唯一性,即便是多次传输,消息也不会过度消费;或者保证消息的等幂性;
比如:在写入消息队列的数据做唯一标识,消费者消费消息的时候,更具唯一标识判断是否消费过;
如何保证RabbitMQ消息的可靠传输?
消息不可靠的情况坑你是消息丢失,劫持等原因;
丢失又分为生产者丢失消息、消息列表丢失消息、消费者丢失消息等。
生产者丢失消息
就是生产者生产消息发送到MQ队列的时候由于网络问题或其他问题导致消息无法被MQ队列接收
针对此种问题,有2种方案:
1.开启事务发送消息:在发送过程中开启事务,如果发送成功,则提交事务,否则回滚
缺点就是:MQ的吞吐性能下降!
2.开启confirm模式,现实中用的也很多:一旦channel进入confirm模式,
所有在该信道上发布的消息都会被指派一个唯一的ID(从1开始),一旦消息被投递放入队列中,
MQ就会发送一个ACK给生产者(包含消息的唯一ID),这样生产者知道消息正确到达了队列了。
如果rabbitMQ没能处理该消息,则会发送一个Nack消息给生产者,生产者可以重试。
MQ自身丢失数据
可能是MQ本身故障宕机、或者停电什么的些情况
解决方法是开启消息持久化
持久化配置可以和confrim机制配合一起使用,可以在消息持久化之后发送ACK消息给生产者
如果消息在持久化之前MQ阵亡了,生产者就收不到ACK消息了,那么生产者可以自动重发呀,
开启消息持久化也很简单
1.将queue的持久化标识durable设置为true,这代表一个持久化的队列
2.发送消息的时候将deliveryMod=2
经过上面配置,即使是MQ挂了,重启也会能恢复数据
消费者丢失消息
消费者收到消息一般是自动确认消息,将其改为手动模式即可!
消费者收到消息之后,处理消息之前会自动回复RabbitMQ以收到消息;
如果这个时候处理消息失败了,该消息就丢失了!!!
解决方法就是在消息处理之后,手动回复确认消息。
如何保证RabbitMQ消息的顺序性?
单线程消费可以保证消息的顺序性;
对消息进行编号,消费者处理消息是根据编号处理消息
RabbitMQ的消息优先级
RabbitMQ 内部有个优先级,通过在生产者发送到MQ的时候配置`x-max-priority`
x-max-priority的取值范围是0-255之间,取值越高,优先级越高,取值越低,优先级越低。
配置这个优先级的前提条件是 消费端消费速度 大于 生产端的生产速度,否则队列中没有积压消息,也就没有优先级的做法了。
RabbitMQ的集群配置方式
主备模式(兔子窝)
有点儿CAP理论的意思
主节点读写,备用节点留着,主节点挂了,备用节点顶上。
远程模式(早期方案,现在比较少用了)
简单的说就是通过2台不同地区的MQ在网络上进行异地传是数据;
订单比较好解释,本地MQ负载过大,就将消息发送到远方负载低的MQ中,让远端MQ的消费者消费。
镜像模式
就是镜像一样,2个以上的MQ相互复制数据,达到数据不丢失的目的。
多活模式
异地双活模式,多个中心之间互相部分数据共享。
参考资料:
https://www.cnblogs.com/woadmin/p/10537174.html
https://blog.csdn.net/cherishme1988/article/details/69487649
https://www.cnblogs.com/leoyang63/articles/14033945.html