为了完全理解并牢记这些特性,我对这些特性进行了按照作用的对象进行了分类
MQ 总共有三个部分组成
Producer:消息生成者
MQ:队列
Consumer:消费者
为了保证消息的可靠性传输,包括投递消息的生产方能投递成功,和消息消费的消费方正确消费,RabbitMQ 提供了两个确认机制,由于消息按照流通的顺序从左到右,因此为保证可靠性,MQ必须对 Producer进行确认,Consumer 必须对 MQ 进行确认,由于 不能在 MQ 写代码来控制,因此这两个确认分别在生产者和消费者中来控制(这是基于 MQ的消息确认发出和消息确认接收都准确无误的情况下),这两个确认都有成功和失败两种情况
1.在消息的生产方提供确认消息的回调,用于接收来自 MQ 的确认 (称为 confirm 机制)【另外还有一种称为 return 的机制可以监听不可达消息】
2.在消息的消费方对消息进行手动确认,用于对 MQ的消息进行确认 (称为 ack /nack机制)
基于这个确认机制,MQ 实现了限流和重回队列的功能,限流是手动对每条消息进行成功确认,如果消费者对消息进行失败确认则可以设置重新放回队列。(如果不确认,MQ不会下发下一条消息,该消费者阻塞,只要进行了确认,不管是成功确认还是失败确认,都会进行下一条的放出)
实际上,由于网络的不可预测性,虽然两方有了确认机制,但也不是百分之百可靠的,可以通过先把消息落库,在通过mvcc的机制来保证可靠投递和幂等消费(可靠投递是确保消息投递到mq中,幂等消费是指即使mq中有多条相同的消息,可以能保证该消息能正确消费并且只消费一次)
TTL
另外在生产者端可以对消息设置过期时间,消息设置过期时间(ttl)分为两种:
1.通过设置消息的属性来设置过期时间,这样同一个队列中的每个消息可以有不同的 ttl 时间(数据定期从队头删除)
2.通过设置队列的属性来设置消息的过期时间,这样同一个队列中的所有消息都具有相同的 ttl 时间(数据定期惰性删除除)
若只设置了ttl但没有绑定死信队列,则根据删除策略直接删除数据,只有当设置了过期时间并且该队列设置了死心队列,则在消息过期后该消息会进入到绑定的死信队列中
死信队列
1.当消息设置了过期时间并且该队列设置了死信队列,死信队列与普通队列的声明是完全一样的,只是如果在另一个队列中声明死信队列为这个队列时,他才是死信队列
死信消息进入死信队列的情况:
1.设置了ttl的消息到了过期时间并且设置了绑定的死信队列;
2.当设置了队列的最大消息长度并且该队列设置了死信队列(队列的长度可以由rabbitmq启动服务时指定,也可以由客户端声明队列时指定,既可以指定队列长度个数,也可以指定消息的总字节数,只有ready的消息才会被计数)
网友评论