本文已参与「新人创作礼」活动,一起开启掘金创作之路。
RabbitMQ配置-docker中
1. 获取镜像
#指定版本,该版本包含了web控制页面
docker pull rabbitmq:management
2-a. 创建容器rabbit
docker run -d --hostname my-rabbit --name rabbit -p 15672:15672 -p 5672:5672 rabbitmq:management
默认账密均为 guest
2-b. 配置方式创建容器rabbit:
docker run -d --restart=always -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=123456 --name rabbit -p 5672:5672 -p 15672:15672 rabbitmq:management
设置默认账密为:admin/123456
3. 登录rabbitMQ管理后台
登录网址为:http://127.0.0.1:15672/
PHP使用RabbitMQ
RabbitMQ有很多协议,而php要连接rabbit的话,通常使用AMQP来作为传输协议。下面介绍两种安装AMQP的方法:
a. php安装AMQP-本地电脑环境(win)中
参考文章:blog.csdn.net/eddy23513/a…
-
在 pecl.php.net/package/amq… 找最新稳定版本的,点击进入到下载页
-
选择与自己php版本相对应的dll进行下载(php -v)
-
解压后,将本目录下的
php_amqp.dll
文件(可能有.1、.4的,一样可用)复制到对应php安装目录的php/ext
中 -
在
php.ini
中添加如下代码:[amqp] extension=php_amqp.dll
-
复制
rabbitmq.4.dll
到php目录中,然后修改apache配置文件httpd.conf
,添加如下代码:# rabbitmq LoadFile "对应php安装目录的php/rabbitmq.dll"
-
使用下面代码进行测试 consumer.php:
<?php //连接参数 $config = array( 'host' => '127.0.0.1', 'vhost' => '/', 'port' => 5672, 'login' => 'admin', 'password' => '123456' ); //连接broker $cnn = new AMQPConnection($config); if (!$cnn->connect()) { echo "Cannot connect to the broker"; exit(); } //在连接内创建一个通道 $ch = new AMQPChannel($cnn); //创建一个交换机 $ex = new AMQPExchange($ch); //声明路由键 $routingKey = 'key_1'; //声明交换机名称 $exchangeName = 'exchange_1'; //设置交换机名称 $ex->setName($exchangeName); //设置交换机类型 //AMQP_EX_TYPE_DIRECT:直连交换机 //AMQP_EX_TYPE_FANOUT:扇形交换机 //AMQP_EX_TYPE_HEADERS:头交换机 //AMQP_EX_TYPE_TOPIC:主题交换机 $ex->setType(AMQP_EX_TYPE_DIRECT); //设置交换机持久 $ex->setFlags(AMQP_DURABLE); //声明交换机 $ex->declareExchange(); //创建一个消息队列 $q = new AMQPQueue($ch); //设置队列名称 $q->setName('queue_1'); //设置队列持久 $q->setFlags(AMQP_DURABLE); //声明消息队列 $q->declareQueue(); //交换机和队列通过$routingKey进行绑定 $q->bind($ex->getName(), $routingKey); //接收消息并进行处理的回调方法 function receive($envelope, $queue) { //休眠两秒, sleep(2); echo $envelope->getBody() . "\n"; //显式确认,队列收到消费者显式确认后,会删除该消息 $queue->ack($envelope->getDeliveryTag()); } //设置消息队列消费者回调方法,并进行阻塞 $q->consume("receive");
publisher.php
<?php $config = array( 'host' => '127.0.0.1', 'vhost' => '/', 'port' => 5672, 'login' => 'admin', 'password' => '123456' ); //创建一个新的连接, 连接到broker $cnn = new AMQPConnection($config); if (!$cnn->connect()) { echo "Cannot connect to the broker"; exit(); } $ch = new AMQPChannel($cnn); $ex = new AMQPExchange($ch); //消息的路由键,一定要和消费者端一致 $routingKey = 'key_1'; //交换机名称,一定要和消费者端一致, $exchangeName = 'exchange_1'; $ex->setName($exchangeName); $ex->setType(AMQP_EX_TYPE_DIRECT); $ex->setFlags(AMQP_DURABLE); $ex->declareExchange(); //创建20个消息 for ($i=1;$i<=20;$i++){ //消息内容 $msg = array( 'data' => 'message_'.$i, 'hello' => 'world', ); //发送消息到交换机,并返回发送结果 //delivery_mode:2声明消息持久,持久的队列+持久的消息在RabbitMQ重启后才不会丢失 echo "Send Message:".$ex->publish(json_encode($msg), $routingKey, AMQP_NOPARAM, array('delivery_mode' => 2))."\n"; //代码执行完毕后进程会自动退出 }
b. 使用composer安装amqplib
添加composer.json:
{
"require": {
"php-amqplib/php-amqplib": ">=2.6.1"
}
}
之后,运行composer install
即可。或者不需要添加composer.json,直接运行包引入
composer require php-amqplib/php-amqplib
在引入composer依赖后,即可使用AMQP
示例代码:
new_task.php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
$channel->queue_declare('task_queue', false, true, false, false);
$data = implode(' ', array_slice($argv, 1));
if(empty($data)) $data = "Hello World!";
$msg = new AMQPMessage($data,
array('delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT)
);
$channel->basic_publish($msg, '', 'task_queue');
echo " [x] Sent ", $data, "\n";
$channel->close();
$connection->close();
?>
worker.php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
$channel->queue_declare('task_queue', false, true, false, false);
echo ' [*] Waiting for messages. To exit press CTRL+C', "\n";
$callback = function($msg){
echo " [x] Received ", $msg->body, "\n";
sleep(substr_count($msg->body, '.'));
echo " [x] Done", "\n";
$msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);
};
$channel->basic_qos(null, 1, null);
$channel->basic_consume('task_queue', '', false, false, false, false, $callback);
while(count($channel->callbacks)) {
$channel->wait();
}
$channel->close();
$connection->close();
?>