用php操作消息隊列,RabbitMQ消息隊列在PHP下的應用大全

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的中文文檔一直沒找到,所以自己把操作過的記錄下來,以供參考。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章