Laravel 使用 rabbitmq (Facades)

1.安装依赖

composer require php-amqplib/php-amqplib

2.编写配置文件
\config\queue.php

 [
        
        //......

        'rabbitmq' => [
            'host' => env('RABBITMQ_HOST', '127.0.0.1'),
            'port' => env('RABBITMQ_PORT', 5672),

            'vhost' => env('RABBITMQ_VHOST', '/'),
            'login' => env('RABBITMQ_LOGIN', 'guest'),
            'password' => env('RABBITMQ_PASSWORD', 'guest'),

            'queue' => env('RABBITMQ_QUEUE', 'default'),

            'options' => [

                'exchange' => [

                    'name' => env('RABBITMQ_EXCHANGE_NAME'),

                    /*
                     * Determine if exchange should be created if it does not exist.
                     */

                    'declare' => env('RABBITMQ_EXCHANGE_DECLARE', true),

                    /*
                     * Read more about possible values at https://www.rabbitmq.com/tutorials/amqp-concepts.html
                     */

                    'type' => env('RABBITMQ_EXCHANGE_TYPE', \Interop\Amqp\AmqpTopic::TYPE_DIRECT),
                    'passive' => env('RABBITMQ_EXCHANGE_PASSIVE', false),
                    'durable' => env('RABBITMQ_EXCHANGE_DURABLE', true),
                    'auto_delete' => env('RABBITMQ_EXCHANGE_AUTODELETE', false),
                    'arguments' => env('RABBITMQ_EXCHANGE_ARGUMENTS'),
                ],

                'queue' => [

                    /*
                     * Determine if queue should be created if it does not exist.
                     */

                    'declare' => env('RABBITMQ_QUEUE_DECLARE', true),

                    /*
                     * Determine if queue should be binded to the exchange created.
                     */

                    'bind' => env('RABBITMQ_QUEUE_DECLARE_BIND', true),

                    /*
                     * Read more about possible values at https://www.rabbitmq.com/tutorials/amqp-concepts.html
                     */

                    'passive' => env('RABBITMQ_QUEUE_PASSIVE', false),
                    'durable' => env('RABBITMQ_QUEUE_DURABLE', true),
                    'exclusive' => env('RABBITMQ_QUEUE_EXCLUSIVE', false),
                    'auto_delete' => env('RABBITMQ_QUEUE_AUTODELETE', false),
                    'arguments' => env('RABBITMQ_QUEUE_ARGUMENTS'),
                ],
            ],

            /*
             * Determine the number of seconds to sleep if there's an error communicating with rabbitmq
             * If set to false, it'll throw an exception rather than doing the sleep for X seconds.
             */

            'sleep_on_error' => env('RABBITMQ_ERROR_SLEEP', 5),

            /*
             * Optional SSL params if an SSL connection is used
             * Using an SSL connection will also require to configure your RabbitMQ to enable SSL. More details can be founds here: https://www.rabbitmq.com/ssl.html
             */

            'ssl_params' => [
                'ssl_on' => env('RABBITMQ_SSL', false),
                'cafile' => env('RABBITMQ_SSL_CAFILE', null),
                'local_cert' => env('RABBITMQ_SSL_LOCALCERT', null),
                'local_key' => env('RABBITMQ_SSL_LOCALKEY', null),
                'verify_peer' => env('RABBITMQ_SSL_VERIFY_PEER', true),
                'passphrase' => env('RABBITMQ_SSL_PASSPHRASE', null),
            ],

        ],
        
		//......

    ],
    
];

3.编写组件
\App\Component\Queue\Rabbitmq.php

connection = new AMQPStreamConnection(
            $config['host'], $config['port'], $config['login'], $config['password'], $config['vhost']
        );
        $this->config = $config;
    }

    public function __destruct() {
        //关闭连接
        $this->connection->close();
    }

    /**
     * 生产
     * @param string $queue 队列名
     * @param mixed $data 数据
     * @param bool $durable 持久化
     * @return void
     * @author tom
     */
    public function product($queue, $data, $durable = false)
    {
        if (!$queue) {
            $queue = $this->config['queue'];
        }
        $data = json_encode($data);
        //打开信道
        if ($this->transaction == 1) {
            $channel = $this->channel;
        } else {
            $channel = $this->connection->channel();
            $log = app('log');
            //异步回调消息确认 - 成功
            $channel->set_ack_handler(
                function (AMQPMessage $message) use ($log) {
                    $log->debug('message pub success: ' . $message->body);
                }
            );
            //异步回调消息确认 - 失败
            $channel->set_nack_handler(
                function (AMQPMessage $message) use ($log) {
                    $log->error('message pub fail: ' . $message->body);
                }
            );
            //设为confirm模式
            $channel->confirm_select();
        }
        //声明队列
        $channel->queue_declare(
            $queue, 
            $this->config['options']['queue']['passive'],
            $this->config['options']['queue']['durable'],
            $this->config['options']['queue']['exclusive'],
            $this->config['options']['queue']['auto_delete']
        );
        //打包数据
        $properties = [
            'delivery_mode' => $durable ? AMQPMessage::DELIVERY_MODE_PERSISTENT : AMQPMessage::DELIVERY_MODE_NON_PERSISTENT,
        ];
        $msg = new AMQPMessage($data, $properties);
        //推送
        $channel->basic_publish($msg, '', $queue);
        if ($this->transaction != 1) {
            //阻塞等待消息确认
            $channel->wait_for_pending_acks();
            //关闭信道
            $channel->close();
        }
    }

    /**
     * 消费
     * @param string $queue 队列名
     * @param mixed $callback 闭包函数
     * @return void
     * @author tom
     */
    public function consumer($queue, \closure $callback)
    {
        if (strlen($queue) == 0) {
            $queue = $this->config['queue'];
        }
        //打开信道
        $channel = $this->connection->channel();
        //声明队列
        $channel->queue_declare(
            $queue, 
            $this->config['options']['queue']['passive'],
            $this->config['options']['queue']['durable'],
            $this->config['options']['queue']['exclusive'],
            $this->config['options']['queue']['auto_delete']
        );
        //流量控制
        $channel->basic_qos(null, 10, null);
        //消费
        $channel->basic_consume($queue, '', false, false, false, false, $callback);
        while(count($channel->callbacks)) {
            $channel->wait();
        }
        //关闭信道
        $channel->close();
    }

    /**
     * 发布
     * @param string $exchage 交换机
     * @param mixed $data 数据
     * @param bool $durable 持久化
     * @param string $routekey 路由
     * @return void
     * @author tom
     */
    public function publish($exchage, $data, $durable = false, $routekey = '')
    {
        if (strlen($exchage) == 0) {
            throw new \Exception('未指定交换机名');
        }
        $data = json_encode($data);
        //打开信道
        if ($this->transaction == 1) {
            $channel = $this->channel;
        } else {
            $channel = $this->connection->channel();
            $log = app('log');
            //异步回调消息确认 - 成功
            $channel->set_ack_handler(
                function (AMQPMessage $message) use ($log) {
                    $log->debug('message pub success: ' . $message->body);
                }
            );
            //异步回调消息确认 - 失败
            $channel->set_nack_handler(
                function (AMQPMessage $message) use ($log) {
                    $log->error('message pub fail: ' . $message->body);
                }
            );
            //设为confirm模式
            $channel->confirm_select();
        }
        //声明交换机
        $channel->exchange_declare(
            $exchage, 
            'topic',
            $this->config['options']['exchange']['passive'],
            $this->config['options']['exchange']['durable'],
            $this->config['options']['exchange']['auto_delete']
        );
        //打包数据
        $properties = [
            'delivery_mode' => $durable ? AMQPMessage::DELIVERY_MODE_PERSISTENT : AMQPMessage::DELIVERY_MODE_NON_PERSISTENT,
        ];
        $msg = new AMQPMessage($data, $properties);
        //发布
        $channel->basic_publish($msg, $exchage, $routekey);
        if ($this->transaction != 1) {
            //阻塞等待消息确认
            $channel->wait_for_pending_acks();
            //关闭信道
            $channel->close();
        }
    }

    /**
     * 订阅
     * @param string $exchage 交换机
     * @param string $queue 队列名
     * @param mixed $callback 闭包函数
     * @param string $routekey 路由
     * @return void
     * @author tom
     */
    public function subscribe($exchage, $queue, \closure $callback, $routekey = '')
    {
        if (strlen($exchage) == 0) {
            throw new \Exception('未指定交换机名');
        }
        if (strlen($queue) == 0) {
            $queue = $this->config['queue'];
        }
        //打开信道
        $channel = $this->connection->channel();
        //声明交换机
        $channel->exchange_declare(
            $exchage, 
            'topic',
            $this->config['options']['exchange']['passive'],
            $this->config['options']['exchange']['durable'],
            $this->config['options']['exchange']['auto_delete']
        );
        //声明队列
        $channel->queue_declare(
            $queue, 
            $this->config['options']['queue']['passive'],
            $this->config['options']['queue']['durable'],
            $this->config['options']['queue']['exclusive'],
            $this->config['options']['queue']['auto_delete']
        );
        //绑定队列
        $channel->queue_bind($queue, $exchage, $routekey);
        //流量控制
        $channel->basic_qos(null, 10, null);
        //消费
        $channel->basic_consume($queue, '', false, false, false, false, $callback);
        while(count($channel->callbacks)) {
            $channel->wait();
        }
        //关闭信道
        $channel->close();
    }

    /**
     * 开启事务
     * @return void
     * @author tom
     */
    public function begin()
    {
        //打开信道
        $this->channel = $this->connection->channel();
        $this->transaction = 1;
        $this->channel->tx_select();
    }

    /**
     * 提交事务
     * @return void
     * @author tom
     */
    public function commit()
    {
        if (!$this->channel) {
            throw new \Exception('未开启事务');
        }
        $this->channel->tx_commit();
        $this->channel->close();
        $this->channel = null;
        $this->transaction = 0;
    }

    /**
     * 回滚事务
     * @return void
     * @author tom
     */
    public function rollback()
    {
        if (!$this->channel) {
            throw new \Exception('未开启事务');
        }
        $this->channel->tx_rollback();
        $this->channel->close();
        $this->channel = null;
        $this->transaction = 0;
    }
}

4.注册服务
\App\Providers\AppServiceProvider.php

public function register()
    {
		//......
        $this->app->singleton('Rabbitmq', function ($app) {
            return new Rabbitmq(config('queue.connections.rabbitmq'));
        });
        //......
    }

5.创建门面
\app\Facades\Rabbitmq.php

6.注册门面
\config\app.php

'aliases' => [
	//......
	'Rabbitmq' => App\Facades\Rabbitmq::class,
	//......
]

7.使用

use Rabbitmq;

class yourClass
{
	function yourfuc()
	{
		//更多方法请查看:\App\Compoent\Queue\Rabbitmq.php
        Rabbitmq::product('yourQueue', 'Hello ttttt!', true);
	}
}

你可能感兴趣的:(php)