rabbitmq是一种MQ,MQ全称为Message Queue, 消息队列是一种应用程序对应用程序的通信方法。优点不必说了,这里就记录我使用rabbitmq的过程。
一、安装
安装Erlang语言环境,再安装rabbitmq,如果想用php操作它就还需要去开启amqp扩展。二、利用队列发送消息
1.以服务方式
这一种要引入文件和命名空间,需要在当前文件放入PhpAmqpLib和vendor这两个。它会向ha1队列发送消息。其中非常重要的是queue_declare('ha1', false, false, false, false),第二个参数false表示没有队列就创建,第三个参数表示持久性。如果不存在ha1命名的队列且第二个参数不是false就会报错。各种报错自己体会。<?php
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPConnection;
use PhpAmqpLib\Message\AMQPMessage;
//创建MQ连接
$connection = new AMQPConnection('127.0.0.1', '5672', 'guest', 'guest');
// $connection->connect();
$channel = $connection->channel();
//声明队列
$channel->queue_declare('ha1', false, false, false, false);//沒有隊列就創建|持久性
//定义要发送消息
$Now = date('Y-m-d H:i:s');
$msg = new AMQPMessage("Hello json or xml data! - {$Now}");
//发送消息
$channel->basic_publish($msg, '', 'ha1');
echo " [x] Sent 'Hello World!' \n";
$channel->close();
$connection->close();
?>
2.以扩展的方式
上一段代码队列是以服务方式运行,下面这一段是以扩展方式,需要php已经开启amqp扩展。这段代码不一样的是,交换机和队列名已经确定,不能自己创建,若不存在就会报错。但是两者绑定关系可以自动生成,需要注意的是绑定的route_key。<?php
$conn_args = array(
'host' => '127.0.0.1',
'port' => '5672',
'login' => 'guest',
'password' => 'guest',
'vhost'=>'/'
);
$e_name = 'test2'; //交换机名
$q_name = 'ha1'; //队列名
//$k_route = array(0=> 'key_1', 1=> 'key_2'); //路由key
$k_route = 'route'; //路由key
//创建连接和channel
$conn = new AMQPConnection($conn_args);
if (!$conn->connect()) {
die("Cannot connect to the broker! <br />");
}
$channel = new AMQPChannel($conn);
//發送消息
//创建交换机
$ex = new AMQPExchange($channel);
$ex->setName($e_name);
$ex->setType(AMQP_EX_TYPE_DIRECT); //direct类型
$ex->setFlags(AMQP_DURABLE); //持久
//创建queue名称,使用exchange,绑定routingkey
$q = new AMQPQueue($channel);
$q->setName($q_name);//队列名称
$q->bind($e_name,$k_route);//交换机名称
echo "Exchange Status:".@$ex->declare()."<br />";
for($i=0; $i<5; ++$i){
$message = 'Hello!';
echo "Send Message:".$ex->publish($message . date('H:i:s'),$k_route)."<br />";
}
?>
三、利用队列接收消息
1.以服务方式
下面是用服务的方式跑队列,并且代码中有一个死循环,不停去监听某一个队列,所以不能用浏览器,需要用cmd打开dos窗口。而用dos窗口操作php需要先设置环境变量,高级系统设置-高级-环境变量-系统环境-PATH,添加“C:\wamp\bin\php\php5.5.12;”即php配置文件所在的文件目录。然后在dos窗口用“cd C:\wamp\www\mq”再执行“php worker.php”,因为我下面这段代码放在C:\wamp\www\mq\worker.php。当前上面这两个命令也可以简化成一句“php C:\wamp\www\mq\worker.php”,表示用php执行worker.php中的下面这段代码。
注意:这里的queue_declare函数照样有自动创建队列的功能,如果使用的时候报错,可以自行修改queue_declare函数的参数测试。
<?
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPConnection;
$connection = new AMQPConnection('127.0.0.1', "5672", 'guest', 'guest');
$channel = $connection->channel();
$channel->queue_declare('ha1', false, true, false, false) ;
echo ' [*] Waiting for messages. To exit press CTRL+C', "\n";
$callback = function($msg){
// 将接收到的消息写入数据库
//$dsn = "mysql:host=localhost;dbname=test";
//$db = new PDO($dsn, 'root', '');
//$res = $db->exec("INSERT INTO rabbitmq values (null , '" . " [x] Received1 ". $msg->body . "')");
echo " [x] Received1 ", $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('ha1', '', false, true, false, false, $callback) ;
while(count($channel->callbacks)) {
$channel->wait();
}
$channel->close();
$connection->close();
?>
2.以扩展方式
如果是用扩展的方式对应也有一串代码,已測試可用但是没有经过优化,仅供参考借鉴。<?php
//连接RabbitMQ
$conn_args = array(
'host' => '192.168.16.220',
'port' => '5672',
'login' => 'guest',
'password' => 'guest',
'vhost'=>'/'
);
$conn = new AMQPConnection($conn_args);//配置
$conn->connect();
//设置queue名称,使用exchange,绑定routingkey
$channel = new AMQPChannel($conn);
$q = new AMQPQueue($channel);
$q->setName('ha3'); // 发送使用的队列名称
//$q->declare();
$q->bind('test2', 'routingkey'); //发送使用的交换机名称
//消息获取
//$messages = $q->get(AMQP_AUTOACK);
//var_dump($messages::body); //输出消息
$i = 0;
while($msg = $q->get(AMQP_AUTOACK)){
$i++;
//echo $msg->body;
//print_r($msg);
echo "<br/>";
}
echo $i;
$conn->disconnect();
?>
四、利用tp操作队列
用tp其实和不用差不多,整合成一个类作为两个方法就可以了,不同的是上面的dos命令“php C:\wamp\www\mq\worker.php”需要修改。比方说我tp项目还是放在C:\wamp\www\mq下,同时发送和接收的方法分别为home模块下index控制器下的index方法和worker方法,发送仍然可以用浏览器,接收用dos,命令为“cd C:\wamp\www\mq”,这个cd命令不可缺少,然后“php index.php home/index/worker”。
rabbitmq的中文文档一直没找到,所以自己把操作过的记录下来,以供参考。