Laravel 使用 rabbitmq (Facades)

1.安装依赖

composer require php-amqplib/php-amqplib

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

<?php

return [

    'connections' => [
        
        //......

        '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

<?php
/**
 * rabbitmq
 * 队列操作
 */
namespace App\Component\Queue;

use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

class Rabbitmq
{
    /**
     * mq连接实例
     * @var AMQPStreamConnection
     * @author tom
     */
    protected $connection;

    /**
     * mq信道实例
     * @var \PhpAmqpLib\Channel\AMQPChannel
     * @author tom
     */
    protected $channel;

    /**
     * 配置信息
     * @var string
     * @author tom
     */
    protected $config;

    /**
     * 是否开启事务
     * @var integer
     * @author tom
     */
    protected $transaction = 0;

    public function __construct($config = [])
    {
        if (empty($config)) {
            throw new \Exception('rabbitmq配置无效');
        }
        //新建mq连接
        $this->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

<?php
/**
 * Rabbitmq操作
 */
namespace App\Facades;

use Illuminate\Support\Facades\Facade;

/**
 * @see \App\Component\Queue\Rabbitmq
 */
class Rabbitmq extends Facade
{
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return 'Rabbitmq';
    }
}

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);
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值