个人名片:
博主:酒徒ᝰ.
个人简介:沉醉在酒中,借着一股酒劲,去拼搏一个未来。
本篇励志:三人行,必有我师焉。
本项目基于B站黑马程序员Java《SpringCloud微服务技术栈》,SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
【SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 点击观看
三、死信交换机
1. 初识死信交换机
- 什么是死信交换机
死信交换机是一种网络设备,它可以在网络中转发数据包,但是它不会像普通交换机一样将数据包从一个端口发送到另一个端口。相反,死信交换机将数据包发送到一个预先设置的邮箱地址,这个邮箱地址通常是一个死信邮箱。当数据包到达死信邮箱时,接收方会收到一封邮件通知,告诉他们有新的数据包可供下载。
死信交换机的优点在于它可以确保数据包的安全性和可靠性。由于数据包不会直接从一个端口发送到另一个端口,因此攻击者无法窃取数据包并篡改其内容。此外,当数据包到达死信邮箱时,接收方可以确认接收到的数据包的完整性并进行相关操作。
在网络安全领域中,死信交换机通常用于安全传输敏感信息,例如公司内部的机密文件或政府机构的敏感信息。此外,死信交换机还可以用于防止拒绝服务攻击(DoS)和分布式拒绝服务攻击(DDoS)。在这些攻击中,攻击者会向目标服务器发送大量垃圾流量,以使其崩溃或过载。使用死信交换机可以避免这种情况的发生,因为攻击者无法直接攻击目标服务器,而只能攻击死信交换机上的邮箱地址。
总之,死信交换机是一种非常有用的网络设备,它可以确保数据包的安全性和可靠性,并防止拒绝服务攻击。
当一个队列中的消息满足下列情况之一时,可以成为死信(dead letter):
- 消费者使用basic.reject或 basic.nack声明消费失败,并且消息的requeue参数设置为false
- 消息是一个过期消息,超时无人消费
- 要投递的队列消息满了,无法投递
如果这个包含死信的队列配置了
dead-letter-exchange
属性,指定了一个交换机,那么队列中的死信就会投递到这个交换机中,而这个交换机称为死信交换机(Dead Letter Exchange,检查DLX)。
如图,一个消息被消费者拒绝了,变成了死信.因为这条消息所在的队列绑定了死信交换机 因此死信会投递给这个交换机,如果这个死信交换机也绑定了一个队列,则消息最终会进入这个存放死信的队列:
队列将死信投递给死信交换机时,必须知道两个信息:
- 死信交换机名称
- 死信交换机与死信队列绑定的RoutingKey
这样才能确保投递的消息能到达死信交换机,并且正确的路由到死信队列。
- 利用死信交换机接收死信(拓展)
在失败重试策略中,默认的RejectAndDontRequeueRecoverer会在本地重试次数耗尽后,发送reject给RabbitMQ,消息变成死信,被丢弃。
我们在consumer服务中,定义一组死信交换机、死信队列:
//建立死信交换机
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "dl.queue", durable = "true"),
exchange = @Exchange(name = "dl.direct", durable = "true", autoDelete = "false"),
key = "dl"
))
public void listenDlQueue(String msg) {
log.info("接收到dl.queue死信消息:{}", msg);
}
//绑定死信交换机
@Bean
public Queue queue() {
return QueueBuilder
.durable("simple.queue")
.deadLetterExchange("dl.direct")
.build();
}
总结
什么样的消息会成为死信?
- 消息被消费者reject或者返回nack
- 消息超时未消费
- 队列满了
死信交换机的使用场景是什么?
- 如果队列绑定了死信交换机,死信会投递到死信交换机;
- 可以利用死信交换机收集所有消费者处理失败的消息(死信),交由人工处理,进一步提高消息队列的可靠性。