RabbitMQ 死信队列
rabbitmq也有死信队列,以下几种情况会有把消息投递到死信队列:
- 消息被拒绝,且requeue设置为false。
- 消息过期(队列过期并不会把消息投递给死信队列)
- 由于超过了队列的消息最大数被抛弃
消息投递给死信队列的时候,也会经过交换器,这个交换器称之为死信交换器,但是他依然是一个正常的交换器。
要设置队列的死信交换,在声明队列时需要指定可选的x-dead-letter-exchange参数。主要是下面的代码:
1 | Map<String, Object> args = new HashMap<String, Object>(); |
示例:
1 | // 定义队列的名称 |
流程是这样的:
- 定义交换器”exchange.dlx”。
- 定义死信交换器”some.exchange.name”。
- 定义队列”queue.dlx”,以及指定死信交换器的参数配置。
- 队列”queue.dlx”绑定了交换器”exchange.dlx”和路由键”route.dlx”。
- 定义死信队列”some.queue.name”。
- 死信队列”some.queue.name”绑定了交换器”some.exchange.name”和路由键”route.dlx”。
由于我们上面定义了队列的消息只有2秒的存在时间,所以2秒后就会进入死信队列。从web控制台可以看出,消息到了死信队列。对这个队列的消费,跟正常的队列没有什么区别。
指定路由
在上面的例子中,路由由于没指定,经死信交换器后,路由还是原来的路由,rabbitmq提供了一个参数,可以改变路由:
1 | args.put("x-dead-letter-routing-key", "some-routing-key"); |
完整代码如下:
1 | // 定义队列的名称 |
运行结果同上,注意的是,如果运行了上面的例子,需要先把队列从rabbitmq删除再运行这个例子,不然由于队列的配置不一样,会报错。