一、死信队列
1.1 什么是死信?
- 死信就是无法被消费的消息。某些时候由于特定的原因导致 queue 中的某些消息无法被消费,这样的消息如果没有后续的处理,就变成了死信,有死信自然就有了死信队列。
1.2 应用场景
- 要保证业务数据的不丢失,就可以启用死信队列,当消息无法被消费,就由死信队列保存。
1.3 死信的原因
- 消息TTL过期
- 队列达到最大长度,交换机路由消息的时候失败了
- 消息被拒后,并且设置参数requeue = false,requeue为true的话表示消息重新进入队列,而不是死信
死信队列本身就是一个队列而已,只不过在创建正常交换机和队列的时候,通过参数绑定一个死信交换机就可以了
Map<String, Object> arguments = new HashMap<>();
arguments.put("x-dead-letter-exchange", DEAD_EXCHANGE); // 设置死信交互机
arguments.put("x-dead-letter-routing-key", "lisi"); // 设置与死信交换机间的routing-key
channel.queueDeclare(NORMAL_QUEUE, false, false, false, arguments);// 这是正常队列的创建
参数:
x-dead-letter-exchange:用于指定死信交换机的名称
x-dead-letter-routing-key:用于指定死信交换机与死信队列的路由
这样正常的队列如果没有办法消费某个消息的时候,他就会把这个消息发送给死信交换机对应的死信队列中
二、延迟队列
首先延迟队列,也只是一个队列,只不过利用了RabbitMQ的某种特性,使得队列中的消息,可以在指定时间才被消费,而不是立刻消费。普通队列的消息都是希望尽快的被消费,他的特点就体现在延迟属性上。
2.1 应用场景
- 订单在十分钟之内未支付则自动取消。
- 新创建的店铺,如果在十天内都没有上传过商品,则自动发送消息提醒。
- 账单在一周内未支付,则自动结算。
- 用户注册成功后,如果三天内没有登陆则进行短信提醒。
- 用户发起退款,如果三天内没有得到处理则通知相关运营人员。
- 预定会议后,需要在预定的时间点前十分钟通知各个与会人员参加会议。
上面这些场景都是比较典型的案例了,都是想在某个主要事件发生的前后完成一项任务,如订单过期后关闭订单;会议开始前十分钟提醒参会人员。
2.2 实现方式
- TTL(Time To Live)相关文章:什么是TTL?
- RabbitMQ插件 rabbitmq_delayed_message_exchange
我们这里主要介绍TTL方式的延迟队列
2.3 实现逻辑:
延迟队列,你可以理解为死信队列+TTL
- 先定义一个普通交换机+普通队列,但是这个队列没有消费者
- 创建一个死信交换机+死信队列,并且让普通交换机指向死信交换机
- 给该队列的消息设置TTL
上述过程基本就可以实现延迟队列了,进入普通队列的消息都有TTL,但是没有消费者,所以一直不会被消费,直到TTL过期,普通队列的消息转入死信队列中,死信队列的消费者,就收到了消息,就可以开始消费了。