Mq

Rabbit MQ 高级特性详解 - 深入了解并掌握Rabbit MQ的高级功能

silverwq
2022-08-20 / 1 评论 / 303 阅读 / 正在检测是否收录...

ack 应答机制

ack就是生产者,通过设置回调函数,当rabbitmq接收到消息后,会执行这个回调函数,这样生产者就知道消息已经被接收到了。

保证消息100%投递成功

方案一

首先建立一张表,当推送消息的时候,先把消息插入表,并且状态设置为0,当rabbitmq接收到消息后,在生产者的回调函数里将这条消息状态设置为1。同时,有一个定时任务,每隔一段时间,将状态为0的消息再推送一遍即可。这样就可以保证所有消息都会被发送。

但是,由于对数据插入消息;而且这种模式,生产者需要回调。这两步操作都是在生产者端完成的,都会消耗生产者的性能。对于生产者而言,一般都是针对用户的,我们希望做的事情越少越好,以提高对用户的响应时间。

方案二

首先建立一张表,推送消息的时候,先把消息插入表A,当rabbitmq收到消息后,在消费者里,可以把结果插入表B。同时,可以通过定时任务进行比较这两张表,把表A中存在,但是表B中不存在的消息再推送一遍即可。

冥等性

在业务高峰期,容易产生消息重复消费的情况,当消费者消费完消息后,再给生产者返回ack后,由于网络中断,导致生产者还以为没有消费数据,重新推送了消息。又或者用户可能快速点击两下,发送了两条一样的消息。而con-冥等性就是保证消息不会被多次消费。

解决办法有很多,比如用mysql的唯一键对消息进行约束。

return机制

往rabbitmq里发送消息,如果交换机存在,路由键不存在,php不会报任何的错误,所以如果失败了我们就不知道失败的原因是什么。这个时候生产者需要有个return监听器,类似ack机制里的回调函数,这个函数里就知道返回状态。

限流机制

为何要限流:生产者突然往rabbitmq发送上万条消息,单个客户端突然处理这么多消息会导致服务器的负载较大,默认情况下会一次性发送很多消息。

消费者限流api设置:$channel->basic_qos();,可以限制一次性只处理多少条数据,等这些处理完成之后,再发送指定数量的消息过来处理。那么rabbitmq如何知道这些消息已经处理完成了呢,可以通过以下代码来告诉rabbitmq:

// 如果没有执行这个的话,rabbitmq就不知道,就不会继续发送消息
$message->delivery_info['channel']->basic_ack([]);

需要注意的是,要把自动确认关闭掉,这样才能用上面的手工确认。

重回队列

有时候消费者拿到消息后,执行的时候会出问题,这个时候会有个容错机制,将消息重新再发送给rabbitmq,希望再下一次拿到消息的时候能够执行成功。

$message->nack(true);

TTL

代表消息再队列里可以存在的时间,超过时间后,消息就消失了。

// 设置10秒
$args->set('x-message-ttl',10000);

死信队列

比如消息设置ttl,到期后消息消失了,但是我们有时候还是想要知道原来的消息的内容是什么,死信队列就好比回收站,我们可以设置一个死信队列存放这类消息,可以让消失的消息放到死新队列里。
当队列达到最大长度的时候,我们也可以设置死信队列,将消息放到这里。

$args->set('x-dead-letter-exchange','exchange.dlx');
$args->set('x-dead-routing-key','routingkey');
...
0

评论 (1)

取消
  1. 头像
    silverwq 作者
    Windows 10 · Google Chrome

    补充

    回复