六、RabbitMQ - PHP 操作 RabbitMQ - 死信队列的设置

作者: 温新

分类: 【PHP RabbitMQ】

阅读: 1419

时间: 2023-02-27 07:38:26

hi,我是温新,一名 PHPer

版本:erlang-25.2.1、rabbitmq_server-3.11.9

系统版本:Rocky Linux 9.1

学习目标:了解死信队列

本篇文章结合官方文档编写及参考网络资料编写,虽非全部原创,但也是结合了自己的理解,若转载请附带本文 URL,编写不易,持续编写更不易,谢谢!

什么是死信队列

死信,在官网中对应的单词为“Dead Letter”。“死信”是RabbitMQ中的一种消息机制,当你在消费消息时,如果队列里的消息出现以下情况:

  • 消息被拒绝,使用 channel.basicNack 或 channel.basicReject ,并且此时requeue 属性被设置为false。
  • 消息在队列的存活时间超过设置的生存时间(TTL)时间。
  • 消息队列的消息数量已经超过最大队列长度。

实现死信队列

如何实现死信队列?下面一起来看看。

消息被拒绝

消息被拒绝,消费者中使用 (basic.reject/basic.nack),并且 requeue = false。

# 消费者
$callback = function ($msg) {
    // 拒绝接收消息
    $msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);
};

$channel->basic_qos(null, 1, null);
$channel->basic_consume($queueName,'', false,false,false,false,$callback);

消息被拒绝接收后就会进入到死信队列中。

消息过期

对于队列而言

可以使用 x-message-ttl 参数设置当前队列中所有消息的过期时间(单位毫秒)。一旦消息过期,就会从队列中删除。

// 在正常队列中设置消息过期时间
$this->channel->exchange_declare('my-logs', 'direct',false, false, false);
$args = new AMQPTable([
    // 消息过期时间
    'x-message-ttl'             => 20000,
    // 死信交换机
    'x-dead-letter-exchange'    => 'dead-exc',
    // 死信路由键
    'x-dead-letter-routing-key' => 'dead-key'
]);
$this->channel->queue_declare('user-log-1', false, true,false,false,false,$args);
$this->channel->queue_bind('user-log-1', 'my-logs', 'user');

对于单个消息

发布消息时,使用 expiration 参数设置单个消息的过期时间。要注意的是,即使消息过期,也不会马上从队列中抹去,因为每条消息是否过期是在即将投递到消费者之前判定的。

$args = new AMQPTable([
    // 消息过期时间
    'expiration'             => 20000,
    // 死信交换机
    'x-dead-letter-exchange'    => 'dead-exc',
    // 死信路由键
    'x-dead-letter-routing-key' => 'dead-key'
]);

要是两个都设置了,则以最短时间为准。

x-message-ttlexpiration 有什么不一样?

x-message-ttl:队列中已过期的消息在队列头部,RabbitMQ 只要定期从队头开始扫描是否有过期的消息即可。

expiration:该消息即将被消费时判断是否过期,过期则删除。

队列达到最大长度

设置队列长度限制

x-max-length 设置最大消息数;

x-max-length-bytes 设置最大长度(以字节为单位)。

如果设置了两个参数,则两者都将适用,将强制执行首先达到的限制。

$args = new AMQPTable([
	// 设置最大消息数
    'x-max-length' => 2,
    'x-dead-letter-exchange'    => 'dead-exc',
    'x-dead-letter-routing-key' => 'dead-key'
]);

队列溢出行为

x-overflow 设置溢出行为,可选值为 drop-head(默认)、 reject-publish 或 reject-publish-dlx。

  • drop-head:从队列前端(即队列中最旧的消息)删除或死信消息。
  • reject-publish:直接丢弃最近发布的消息。假设 x-max-length = 5,发送消息 1-10,最终剩消息 1-5。
$args = new AMQPTable([
    'x-max-length' => 2,
    'x-overflow'   => 'reject-publish',
    'x-dead-letter-exchange'    => 'dead-exc',
    'x-dead-letter-routing-key' => 'dead-key'
]);
  • reject-publish-dlx:最近发布的消息会进入死信队列。假设 x-max-length = 5,发送消息 1-10,最终消息 1-5 进入队列,消息 6-10 会进入死信队列。
请登录后再评论