RabbitMQ之过期时间(TTL)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RabbitMQ之过期时间(TTL)相关的知识,希望对你有一定的参考价值。
参考技术ATTL(Time To Live),即过期时间。RabbitMQ可以对消息和队列设置TTL。
两种方法可以设置消息的 TTL :
(1):通过队列属性设置,队列中所有消息都有相同的过期时间。
(2):对消息本身进行单独设置,每条消息的 TTL 可以不同。
注:如果两种方法一起使用,则消息的 TTL 以两者之间较小的那个数值为准。消息在队列中的生存时间一旦超过设置 TTL 值时,就会变成“死信”( Dead Message ),消费者将无法再收到该消息(如果队列设置了死信队列,那么这条消息就会被转发到死信队列上,该消息就可以被正常消费)。
在 channel.queueDeclare 方法中加入 x-message-ttl 参数,这个参数的单位是毫秒。
原生api
SpringBoot
如果不设置 TTL ,则表示此消息不会过期,如果将 TTL 设置为0,表示除非此时可以直接将消息投递到消费者,否则该消息会被立即丢弃。
在channel.basicPublish 方法中加入 expiration属性参数,单位为毫秒。
原生api
SpringBoot
通过 channel.queueDeclare 方法中的 x-expires 参数可以控制队列被自动删除前处于未使用状态的时间。未使用的意思是队列上没有任何的消费者,队列也没有被重新声明,并且在过期时间段内也未调用过Basic.Get 命令。
RabbitMQ会确保在过期时间到达后将队列删除,但是不保障删除的动作有多及时 。在RabbitMQ 重启后,持久化的队列的过期时间会被重新计算。
用于表示过期时间的 x-expires 参数以毫秒为单位 ,并且服从和 x-message-ttl一样的约束条件,不过不能设置为 0。比如该参数设置为 1000 ,则表示该队列如果在1 秒钟之内未被使用则会被删除。
原生api
SpringBoot
RabbitMQ学习笔记5:RabbitMQ高级
一、TTL队列过期时间
1.过期时间TTL是什么?
过期时间TTL表示可以对消息设置预期的时间,在这个时间内都可以被消费者接收获取;过了之后消息将自动被删除。
2.RabbitMQ可以对消息和队列设置TTL,目前有两种方法可以设置:
- 第一种方法是通过队列属性设置,队列中所有消息都有相同的过期时间。
- 第二种方法是对消息进行单独设置,每条消息TTL可以不同。
如果上述两种方法同时使用,则消息的过期时间以两者之间TTL较小的那个数值为准。消息在队列的生存时间一旦超过设置的TTL值,就称为dead message被投递到死信队列,消费者将无法再收到该消息。
二、死信队列
DLX.全称为Dead-Letter-Exchange,可以称之为死信交换机,也有人称之为死信邮箱。当消息在一个队列中变成死信(dead message)之后,它能被里新发送到另一个交换机中,这个交换机就是DLX,绑定DLX的队列就称之为死信队列。
消息变成死信,可能是由于以下的原因:
- 消息被拒绝
- 消息过期
- 队列达到最大长度
- DLX也是一个正常的交换机,和一般的交换机没有区别,它能在任何的队列上被指定,实际上就是设置某一个队列的属性。当这个队列中存在死信时, Rabbitmq就会自动地将这个消息里新发布到设置的DLX上去,进而被路由到另一个队列,即死信队列。
- 要想使用死信队列,只需要在定义队列的时候设置队列参数 x-dead-letter-exchange 指定交换机即可。
三、延迟队列
有时候不想让消费者立马拿到消息消费,就涉及到延迟队列的使用,使用场景比如典型的付款,提交订单以后,用户如果迟迟没有支付,设置一个过期时间半小时,半小时后进入死信队列进行处理,由系统自动取消订单,所以延迟队列的实现可以使用消息过期+死信队列的方式来实现。
四、内存磁盘监控
当内存使用超过配置的阈值或者磁盘空间剩余空间对于配置的阈值时,RabbitMQ会暂时阻塞客户端的连接,并且停止接收从客户端发来的消息,以此避免服务器的崩溃,客户端与服务端的心态检测机制也会失效。
监控方式:
- 内存警告
- 内存控制(使用命令的方式 或 配置文件的方式)
- 内存换页(在某个Broker节点及内存阻塞生产者之前,它会尝试将队列中的消息换页到磁盘以释放内存空间,持久化和非持久化的消息都会写入磁盘中,其中持久化的消息本身就在磁盘中有一个副本,所以在转移的过程中持久化的消息会先从内存中清除掉。)
- 磁盘预警(当磁盘的剩余空间低于确定的词值时,RabbitMQ同样 会阻塞生产者,这样可以避免因非持久化的消息持续换页而耗尽磁盘空间导致服务器崩溃。)
五 、RabbitMQ集群
RabbitMQ这款消息队列中间件产品本身是基于Erlang编写, Erlang语言天生具备分布式特性(通过同步Erlang 群名节点的magic cookie来实现) 。因此, RabbitMQ天然支持Clustering,这使得RabbitMQ本身不需要像ActiveMQ、Kafka那样通过ZooKeeper分别来实现HA方案和保存集群的元数据。
集群是保证可靠性的一种方式,同时可以通过水平扩展以达到增加消息吞吐是能力的目的。在实际使用过程中多采取多机多实例部署方式。
集群搭建:
- 启动第一个节点 rabbit-1;
- 启动第二个节点 rabbit-2;
- 验证启动 “ps aux|grep rabbitmq”;
- rabbit-1作为主节点;
- rabbit-2作为从节点;
- 验证集群状态;
- Web监控。
注意:主节点关闭后从节点无法访问,从节点关闭主节点依然存在。
六、基于MQ的分布式事务
1.在不同系统间如何保存数据一致性的解决方案就是分布式事务所做的事情。
- 分布式事务指事务的操作位于不同的节点上,需要保证事务的AICD特性。
-
原子性:是指事务是一个不可再分割的工作单元,事务中的操作要么都发生,要么都不发生。
-
一致性:是指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。这是说数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。
-
隔离性:多个事务并发访问时,事务之间是隔离的,一个事务不应该影响其它事务运行效果。
-
持久性:这是最好理解的一个特性:持久性,意味着在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。(完成的事务是系统永久的部分,对系统的影响是永久性的,该修改即使出现致命的系统故障也将一直保持)
- 例如在下单场景下,库存和订单如果不在同一个节点上,就涉及分布式事务
2.解决方案
- 2PC 两阶段提交
- TCC 补偿事务
- 本地消息表(异步确保)
- MQ事务消息(异步场景,通用性较强)
3.基于MQ的分布式事务整体设计思路
4.基于MQ的分布式事务消息问题
- 可靠生产和推送确认
- 可靠消费
- 可靠消费重试机制
- 可靠消费死信队列
5.基于MQ分布式事务解决方案优缺点
优点:
1、通用性强
2、拓展方便
3、耦合度低,方案也比较成熟
缺点:
1、基于消息中间件,只适合异步场景
2、消息会延迟处理,需要业务上能够容忍
建议
1、尽量去避免分布式事务
2、尽量将非核心业务做成异步
以上是关于RabbitMQ之过期时间(TTL)的主要内容,如果未能解决你的问题,请参考以下文章
RabbitMQ 消息过期时间(TTL) --- 2022-04-03