RabbitMQ 消息队列 - php

前言

此案例采用 pub/sub订阅者模式,生成一次,多次消费

由于项目越来越大,尤其在订单这一块做了很多活动,这时候就很难维护,需要把每一块解耦,作为消费者

减少用户的等待时间,避免出现相关业务失败问题

即使相关业务失败,也不会影响主流程

依赖

  • php 7.2+
  • php-sockets 、mbstring 扩展
  •  Erlang 语言
  • 基于Erlang开发的rabbitMQ应用
  • laravel 6+

安装

安装Erlang 及rabiitMq: https://www.jianshu.com/p/bc6da5db58ca

 生产者

# 生成一个命令
user> php artisan make:command SendMqCommand

# 在 app\console\Commands\SendMqCommand中编辑以下

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Exchange\AMQPExchangeType;
use PhpAmqpLib\Message\AMQPMessage;

class SendMqCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'send_mq';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        /**
         * 发送消息
         */
        $exchangeName = 'order3';
        $routeKey = 'orderCreate3';
        $message = json_encode(['order_id' => 50]);
        /*注意*/这里不需要交换机绑定队列,否则只能生产一条消息,只能被多个队列其中一个消费

        $connection = new AMQPStreamConnection(
            'localhost',
            '5672',
            'guest',
            'guest',
            '/'
        );
        $channel = $connection->channel();


        $channel->exchange_declare($exchangeName, AMQPExchangeType::FANOUT, false, true, false);

        $message = new AMQPMessage($message, array('content_type' => 'text/json'));
        $channel->basic_publish($message, $exchangeName);

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

    }
}

消费者1

#生成一个消费者命令
user > php artisan make:command OrderCreateCommand


<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Exchange\AMQPExchangeType;


class OrderCreateCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'order_create1';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        /**
         * 接收消息
         */
        $exchangeName = 'order3';
        $routeKey = 'orderCreate3';
        $queue = 'order_deal3';
        $consumerTag = 'consumer3';

        $connection = new AMQPStreamConnection(
            'localhost',
            '5672',
            'guest',
            'guest',
            '/'
        );
        $channel = $connection->channel();
        $channel->queue_declare($queue, false, true, false, false);
        $channel->exchange_declare($exchangeName, AMQPExchangeType::FANOUT, false, true, false);
        $channel->queue_bind($queue, $exchangeName);
        $channel->basic_consume($queue, $consumerTag, false, false, false, false, function ($message)
        {
            echo "\n--------\n";
            echo $message->body;
            echo "\n--------\n";

            $message->ack();

            // Send a message with the string "quit" to cancel the consumer.
            if ($message->body === 'quit') {
                $message->getChannel()->basic_cancel($message->getConsumerTag());
            }
        });



        register_shutdown_function(function ($channel, $connection)
        {
            $channel->close();
            $connection->close();
        }, $channel, $connection);

        while ($channel ->is_consuming()) {
            $channel->wait();
        }

    }
}

 

消费者2 

只需要在消费者1的命令基础上,增加一个命令文件,把其中代码$queue变量改为不重复的队列名称如 order_deal4

操作 

# 启动消费1、2,监听,订阅订单创建的消息
user > php artisan order_create1
user > php artisan order_create2

# 生成者负责发送订单创建消息
user > php artisan send_msg

最终效果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值