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);
}
}