2019年12月10日09:54:28
原文:https://www.rabbitmq.com/tutorials/tutorial-one-php.html
介紹
先決條件
本教程假定RabbitMQ 已在標准端口(5672)的本地主機上安裝並運行。如果您使用其他主機,端口或憑據,則連接設置需要進行調整。
在哪里獲得幫助
如果您在閱讀本教程時遇到困難,可以 通過郵件列表與我們聯系。
RabbitMQ是消息代理:它接受並轉發消息。您可以將其視為郵局:將要發布的郵件放在郵箱中時,可以確保Mailperson先生或女士最終將郵件傳遞給收件人。以此類推,RabbitMQ是一個郵箱,一個郵局和一個郵遞員。
RabbitMQ與郵局之間的主要區別在於,它不處理紙張,而是接收,存儲和轉發數據消息的二進制斑點。
RabbitMQ和一般的消息傳遞使用一些術語。
-
生產僅意味着發送。發送消息的程序是生產者:
-
隊列是RabbitMQ內部的郵箱的名稱。盡管消息流經RabbitMQ和您的應用程序,但它們只能存儲在隊列中。甲隊列僅由主機的存儲器&磁盤限制約束,它本質上是一個大的消息緩沖器。許多生產者可以發送進入一個隊列的消息,許多消費者可以嘗試從一個隊列接收數據。這就是我們表示隊列的方式:
-
消費與接收具有相似的含義。一個消費者是一個程序,主要是等待接收信息:
請注意,生產者,消費者和經紀人不必位於同一主機上。實際上,在大多數應用程序中卻沒有。一個應用程序既可以是生產者,也可以是消費者。
“Hello World”
(使用php-amqplib客戶端)
在本教程的這一部分中,我們將用PHP編寫兩個程序。發送單個消息的生產者和接收消息並打印出來的消費者。我們將介紹php-amqplib API 中的一些細節,僅着眼於此非常簡單的事情。這是消息傳遞的“ Hello World”。
在下圖中,“ P”是我們的生產者,“ C”是我們的消費者。中間的框是一個隊列-RabbitMQ代表使用者保留的消息緩沖區。
php-amqplib客戶端庫
RabbitMQ使用多種協議。本教程介紹了AMQP 0-9-1,這是一個開放的通用消息傳遞協議。RabbitMQ有許多不同語言的客戶。在本教程中,我們將使用php-amqplib,並使用Composer 進行依賴項管理。
將composer.json文件添加到您的項目中:
{ "require": { "php-amqplib/php-amqplib": ">=2.9.0" } }前提是已安裝Composer並正常運行,則可以運行以下命令:
composer.phar install
還有一個適用於Windows的Composer安裝程序。
現在我們已經安裝了php-amqplib庫,我們可以編寫一些代碼。
正在發送
我們將其稱為消息發布者(發送者)send.php,並將消息接收者 稱為receive.php。發布者將連接到RabbitMQ,發送一條消息,然后退出。
在 send.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();
該連接抽象了套接字連接,並為我們處理協議版本協商和身份驗證等。在這里,我們連接到本地計算機上的代理,即本地 主機。如果我們想連接到另一台計算機上的代理,則只需在此處指定其名稱或IP地址。
接下來,我們創建一個通道,該通道是用於完成工作的大多數API所在的位置。
要發送,我們必須聲明要發送到的隊列。然后我們可以將消息發布到隊列:
$channel->queue_declare('hello', false, false, false, false); $msg = new AMQPMessage('Hello World!'); $channel->basic_publish($msg, '', 'hello'); echo " [x] Sent 'Hello World!'\n";
聲明隊列是冪等的-僅當隊列不存在時才創建。消息內容是一個字節數組,因此您可以在此處編碼任何內容。
最后,我們關閉通道和連接;
$channel->close(); $connection->close();
發送不起作用!
如果這是您第一次使用RabbitMQ,但沒有看到“已發送”消息,那么您可能會不知所措,想知道可能是什么問題。代理可能是在沒有足夠可用磁盤空間的情況下啟動的(默認情況下,它至少需要200 MB的可用空間),因此拒絕接受消息。檢查代理日志文件以確認並減少限制(如有必要)。該配置文件文檔會告訴你如何設置disk_free_limit。
接收
這就是我們的發布者。我們的接收者正在偵聽RabbitMQ發出的消息,因此與發布單個消息的發布者不同,我們將使其繼續運行以偵聽消息並將其打印出來。
該代碼(在receive.php中)具有與send幾乎相同的 include和use:
require_once __DIR__ . '/vendor/autoload.php'; use PhpAmqpLib\Connection\AMQPStreamConnection;
設置與發布者相同;我們打開一個連接和一個通道,並聲明要消耗的隊列。請注意,這與發送發布到的隊列匹配。
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest'); $channel = $connection->channel(); $channel->queue_declare('hello', false, false, false, false); echo " [*] Waiting for messages. To exit press CTRL+C\n";
請注意,我們也在這里聲明隊列。因為我們可能在發布者之前啟動使用者,所以我們想確保隊列存在,然后再嘗試從中使用消息。
我們將告訴服務器將隊列中的消息傳遞給我們。我們將定義一個可調用的PHP ,它將接收服務器發送的消息。請記住,消息是從服務器異步發送到客戶端的。
$callback = function ($msg) { echo ' [x] Received ', $msg->body, "\n"; }; $channel->basic_consume('hello', '', false, true, false, false, $callback); while ($channel->is_consuming()) { $channel->wait(); }
當$ channel有回調時,我們的代碼將阻塞。每當我們收到一條消息時,我們的$ callback函數都會傳遞給收到的消息。
放在一起
現在我們可以運行兩個腳本。在終端中,運行使用者(接收方):
php receive.php
然后,運行發布者(發送者):
php send.php
消費者將打印通過RabbitMQ從發件人那里得到的消息。接收方將繼續運行,等待消息(使用Ctrl-C停止它),因此請嘗試從另一個終端運行發送方。
列表隊列
您可能希望查看RabbitMQ擁有哪些隊列以及隊列中有多少條消息。您可以使用rabbitmqctl工具(作為特權用戶)進行操作:
sudo rabbitmqctl list_queues在Windows上,省略sudo:
rabbitmqctl.bat list_queues
