RabbitMQ基本原理
首先,建議去大概了解下RabbitMQ(以下簡稱mq)的基本工作原理,可以參考這篇文章
最主要的幾個對象如下
對象名稱 | |
---|---|
borker | 相當於mq server |
channel | 通道或者頻道 |
exchange | 交換機 |
queue | 隊列 |
vhost | 虛擬主機(項目隊列隔離使用) |
這幾個對象在上面的文章說描述的已經非常清楚,這里不要敘述了。
安裝操作庫
在你的項目目錄下的composer.json文件中增加下面內容
{
"require": {
"php-amqplib/php-amqplib": "2.7.*" //增加這行
}
}
然后接着執行composer update php-amqplib/php-amqplib
。更加方便的做法是如果你的項目已經有了composer.json那么執行執行composer require php-amqplib/php-amqplib
便可以直接進行安裝了
示例演示
首先需要定義交換機、隊列以及路由關鍵字(routing key) 下面是示例代碼
<?php
require 'vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
$conf = [
'host' => '127.0.0.1',
'port' => 5672,
'user' => 'kd_dev',
'pwd' => 'kd_dev',
'vhost' => '/',
];
$exchangeName = 'kd_sms_send_ex'; //交換機名
$queueName = 'kd_sms_send_q'; //隊列名稱
$routingKey = 'sms_send'; //路由關鍵字(也可以省略)
$conn = new AMQPStreamConnection( //建立生產者與mq之間的連接
$conf['host'], $conf['port'], $conf['user'], $conf['pwd'], $conf['vhost']
);
$channel = $conn->channel(); //在已連接基礎上建立生產者與mq之間的通道
$channel->exchange_declare($exchangeName, 'direct', false, true, false); //聲明初始化交換機
$channel->queue_declare($queueName, false, true, false, false); //聲明初始化一條隊列
$channel->queue_bind($queueName, $exchangeName, $routingKey); //將隊列與某個交換機進行綁定,並使用路由關鍵字
$msgBody = json_encode(["name" => "iGoo", "age" => 22]);
$msg = new AMQPMessage($msgBody, ['content_type' => 'text/plain', 'delivery_mode' => 2]); //生成消息
$r = $channel->basic_publish($msg, $exchangeName, $routingKey); //推送消息到某個交換機
$channel->close();
$conn->close();
有幾個地方需要注意:
- $routingKey其實是可以省略的,但是一般都帶上方便交換機對消息進行不同隊列的推送
- 如果綁定的時候使用了$routingKey,那么在bashic_publish的時候也要指定$routingKey,不然交換機無法路由到指定隊列,默認就推送到不使用關鍵字的隊列了(這在我實驗的時候遇到的一個坑)
- 上面的exchange_declare和queue_declare以及queue_bind其實也不是必須的,如果在代碼運行之前這行交換機和隊列名稱以及通過管理后台的方式手動添加在mq上,那么可以執行使用,而不需要上面的這3句代碼。
執行上面的代碼后你也可以在mq管理后台看到對應的顯示,如下圖
添加后的交換機顯示
添加后的隊列顯示
隊列與交換機的綁定關系,以及綁定的路由關鍵字
路由匹配
上面的代碼中,當我們聲明初始化交換機的時候第二個參數使用direct
參數,其實還有另外3種參數可選。分別為
規則 | 說明 |
---|---|
direct | 精准推送 |
fanout | 廣播。推送到綁定到此交換機下的所有隊列 |
topic | 組播。比如上面我綁定的關鍵字是sms_send,那么他可以推送到*.sms_send的所有隊列 |
headers | 這個目前不知道是如何推送的 |
---更新---
更新一下在創建交換機和隊列的時候各個常用參數說明
name: $queue // should be unique in fanout exchange. [隊列名稱]
passive: false // don't check if a queue with the same name exists [是否檢測同名隊列]
durable: false // the queue will not survive server restarts [是否開啟隊列持久化]
exclusive: false // the queue might be accessed by other channels [隊列是否可以被其他隊列訪問]
auto_delete: true //the queue will be deleted once the channel is closed. [通道關閉后是否刪除隊列]
name: $exchange [交換機名稱]
type: direct [路由類型]
passive: false []
durable: true [交換機是否開啟持久化]
auto_delete: false //the exchange won't be deleted once the channel is closed.