RabbitMQ使用二 工作队列

本文介绍了如何使用RabbitMQ实现工作队列,包括生产者和两个消费者的代码示例。重点强调了在修改消费者代码后,需要重启rabbitmq服务以使变更生效。测试结果显示,消费者1的处理速度比消费者2快,因此能处理更多的任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个就比较简单了,只是还要强调一下

如果前面执行了消费者,那么后面修改消费者代码后,重启rabbitmq服务才能立即生效

代码

代码基本都来自官网

https://www.rabbitmq.com/tutorials/tutorial-two-php.html

生产者

<?php
namespace app\rabbit\controller;
use PhpAmqpLib\Message\AMQPMessage;

class NewTask
{
   public function task($message='Hello World!') {
       $connection = RabbitMQConnection::getConnection();
       $channel = $connection->channel();

       //参数3表示,是否是持久性的队列。
       $channel->queue_declare('task_queue', false, true, false, false);

       //用循环,一次多放一些数据
       for ($i = 0; $i < 20; $i++) {
            $newmsg = '';
            $newmsg = $message.'--'.$i;

            //第二个参数为消息持久
            $msg = new AMQPMessage($newmsg, array('delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT));
            $channel->basic_publish($msg, '', 'task_queue');

            echo ' [x] Sent '.$newmsg.PHP_EOL;
        }
       $channel->close();
       $connection->close();
    }
}
 

看效果,这里的task_queue队列有20个消息,并且重启rabbitmq服务后,该队列也不会消失了

 

消费者1

代码注释里我加了一些自己反复测试,得到的结论

<?php
namespace app\rabbit\controller;
use think\Request;
use think\Db;

class ReceiveWork{

   public function dowork() {
//     echo 1212;die();

      $connection = RabbitMQConnection::getConnection();
        $channel = $connection->channel();

        //第三个参数,表示该队列数据是不是要持久化,持久化之后,会自动保存在erlang数据库中
        $channel->queue_declare('task_queue', false, true, false, false);

        echo " [*] Waiting for messages. To exit press CTRL+C\n";

        $callback = function ($msg) {
            $data = [
                'content'  => '[111111] Received '.$msg->getBody(),
                // 'content' => $msg->delivery_info['delivery_tag'],
                'add_time' => time(),
            ];
            Db::name('logs')->insert($data);
            sleep(1);

            //不加这句,就只保存了1次数据,应该是没有收到确认
            //$msg->delivery_info['channel'] 拿到了消息对应的队列频道对象
            //basic_ack是AMQPChannel类的方法,用于消息确认确认
            //$msg->delivery_info['delivery_tag'] 打印出来的值是 1应该表示的是这条消息是不是确认收到
            $msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);
        };
        //分配的任务不能超过1个,也就是说当前任务没有完成时,不分配新的任务
        //没有这一句,用两个消费者去一个队列里取值时,只有第一个消费者在一直工作,
        $channel->basic_qos(null, 1, null);

        //第四个参数,是否不用确认,false为要确认,设置为false后,进程关闭,任务会继续执行
        $channel->basic_consume('task_queue', '', false, false, false, false, $callback);

        while (count($channel->callbacks)) {
            $channel->wait();
        }

        $channel->close();
        $connection->close();

   }
}

消费者2

与消费者1代码基本一样,只是在记录的时候为了做区分,改成222222。然后休眠时间改成2

'content' => '[222222] Received '.$msg->getBody(),

sleep(2);

 

测试

在url访问生产者接口,队列里有了数据后,再访问消费者1,消费者2的接口。到数据库看效果

消费者1每次存数据后sleep(1)秒,消费者2每次存数据后sleep(2)秒。就有了如下效果。消费者1处理的速度比消费者2处理的速度快,存入数据库的数据就多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值