rabbitmq的六種模式學習筆記

來源於官方手冊(通俗易懂) https://www.rabbitmq.com/tutorials/tutorial-one-php.html

1. Hello World / Simple /簡單 模式

生產者:send.php

<?php
/**
 * Simple 模式 - 生產者
 * RabbitMq 6種模式
 * Date: 2020/4/20 下午4:15
 */

require_once __DIR__. '/../vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

//創建一個 連接 到 RabbitMq服務器
//注意 協議版本
$connection = new AMQPStreamConnection('192.168.8.234', 5672, 'guest', 'guest');

//創建一個channel,大多數 API 都要使用它來做一些事情。
$channel = $connection->channel();

//爲了發送,我們必須聲明 一個隊列queue 來發送
//聲明隊列 是冪等性的,隊列只在它不存在的時候創建
$channel->queue_declare(
    'hello',
    false,
    false,
    false,
    false
);

//消息的內容是 字節數組 格式,所以你可以 對其進行編碼(encode)
$msg = new AMQPMessage('Hello World:');
$channel->basic_publish(
    $msg,
    '',         //交換機名稱
    'hello'   //路由key
);

echo " [x] Sent 'Hello World!'\n";

//關閉channel
$channel->close();

//關閉連接
$channel->close();

receive.php

<?php
/**
 * Simple 模式 - 消費者
 * RabbitMq 6種模式
 * Date: 2020/4/20 下午4:15
 */

require_once __DIR__. '/../vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;

// 不像生產者(publisher),消費者receiver 爲了接收消息 需要監聽(listening) RabbitMQ

$connection = new AMQPStreamConnection('192.168.8.234', 5672, 'guest', 'guest');
$channel = $connection->channel();

//注意, 這裏也聲明瞭隊列(queue),因爲這個消費者啓動的程序 可能 早於生產者程序的啓動,
//在這裏也聲明爲了確保,在我們試着從它裏邊消費時,這個隊列是存在的。
$channel->queue_declare(
    'hello',
    false,
    false,
    false,
    false
);

//記住,消息被server 異步發送給 client(消費端)的
//需要定義一個 回調函數, 參數是 消息
$callback = function ($msg) {
    echo ' [x] Received ', $msg->body, "\n";
};

//
$channel->basic_consume(
    'hello',
    '',
    false,
    true,
    false,
    false,
    $callback
);

//不論何時,我們接收到了消息,我們將調用 $callback 函數,參數爲"消息"
while ($channel->is_consuming()) {
    $channel->wait();
}

$channel->close();
$connection->close();


2、 工作隊列模式 Work Queue

 

【消息丟失】

在沒有ack 情況下 像 一個任務 執行需要幾秒鐘,如果一個worker 被kill 或者其他服務器問題,這個worker 接收的這個消息被沒有被正確處理, 而在隊列裏邊 它已經被標記爲for deletion。這樣情況 這個消息就丟了

爲了 確保 一個消息 永不丟失,RabbitMQ 支持 消息確認(message acknowledgments)

【消息確認機制】

//如果一個 消費者 consumer 死掉了(他的channel 被關閉,connection被關閉,或者 tcp連接斷了),這時它沒有發送 一個 ack RabbitMQ 將理解爲 這個消息沒有被完全處理,將重新把它放到 隊列裏。如果這時候,有其他的 消費者在線,它將很快將此消息投遞給其他的消費者。

注意:不存在 消息 超時時間,即便是 處理一個消息需要非常長非常長的時間。

【忘記確認】

這是常見的錯誤,後果很嚴重。由於它不能夠釋放任何沒被確認的消息,它將佔用越來越多的內存。

爲了能夠找出 這種類型 的錯誤。使用命令:

//sudo rabbitmqctl list_queues name messages_ready messages_unacknowledged
 

消息的持久性 (durability)

當 RabbitMQ quit 或者宕機,它會丟掉 隊列或消息 除非你告訴它不要這樣。

爲了消息不丟失。 我們需要做2件事,標記隊列 和 消息 都爲 持久化(durable)

1. 這個 durable =true 的標誌,需要生產者 和消費者 都去設置 

2. 在AMQPMessage 中 設置 delivery_mode=2

【注意消息的 持久化!】

標記消息爲 持久化,不能夠完全 保證消息不丟失。因爲這裏存在很短的時間窗口:當RabbitMQ收到消息還沒有保存。 // RabbitMQ 不會針對每個消息 來進行 fsync, 他會先保存到 緩存裏。 // 這種持久機制 不是強壯的,但是對於簡單的任務隊列是足夠了。如果你需要一個更加強壯的保障機制, // 你可以使用 publisher_confirms.

【注意】:RabbitMQ 不允許你 使用不同的參數 去重新定義一個 已經存在的 隊列queue,如果這樣做了,它將返回一個錯誤error

【公平的分發】

 默認地: RabbitMQ 它 不看 消費者的未確認消息的數量,它僅僅不加思考地 分發每一個 n-th 消息到 n-th 消費者。

爲了改變這種分發策略! 可以使用 basic_qos 設置 prefetch_count=1;

// 含義是:不要分發 一個新消息給 一個消費者 除非它已經處理並確認了之前的一個消息。

$channel->basic_qos(null, 1, null);

 

new_task.php 代碼如下:

<?php
/**
 * workerQueue 模式 - 生產者
 * 這種模式與 simple沒有本質的區別(代碼層面的)它加上了持久化,公平分發等參數,啓用多個worker 來模擬真正的工作上的用法
 * 基於此原因,生產環境中不要使用simple例子中的代碼
 * RabbitMq 6種模式
 * Author: zhaozhiliang
 * Email: [email protected]
 * Date: 2020/4/20 下午4:15
 */

require_once __DIR__. '/../../vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

//創建一個 連接 到 RabbitMq服務器
//注意 協議版本
$connection = new AMQPStreamConnection('192.168.21.234', 5672, 'guest', 'guest');

//創建一個channel,大多數 API 都要使用它來做一些事情。
$channel = $connection->channel();

//爲了發送,我們必須聲明 一個隊列queue 來發送
//聲明隊列 是冪等性的,隊列只在它不存在的時候創建
$channel->queue_declare(
    'task_queue',  //前一個 hello
    false,
    true,  //持久化 false
    false,
    false
);

//消息的內容是 字節數組 格式,所以你可以 對其進行編碼(encode)
$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'   //路由key ; 之前爲task_queue
);

echo " [x] Sent ", $data, "\n";

//關閉channel
$channel->close();

//關閉連接
$channel->close();


//默認地
// RabbitMQ 將 按照順序地 發送每個消息 給 下一個 消費者;
// 平均每個消費者 將得到 相同數量的消息。這種分發消息的方式 叫  round-robin (輪詢)

/**
 * //運行結果 -shell1
[root@liang workQueues]# php new_task.php First message.
[x] Sent First message.
[root@liang workQueues]# php new_task.php Second message..
[x] Sent Second message..
[root@liang workQueues]# php new_task.php Third message...
[x] Sent Third message...
[root@liang workQueues]# php new_task.php Fourth message....
[x] Sent Fourth message....
[root@liang workQueues]# php new_task.php Fifth message.....
[x] Sent Fifth message.....

 // shell2
[x] Received Second message..
[x] Done
[x] Received Fourth message....
[x] Done
 
 // shell3
[x] Received First message.
[x] Done
[x] Received Third message...
[x] Done
[x] Received Fifth message.....
[x] Done

 *
 *
 */

worker.php 代碼如下:

<?php
/**
 * Simple 模式 - 消費者
 * RabbitMq 6種模式
 * Author: zhaozhiliang
 * Email: [email protected]
 * Date: 2020/4/20 下午4:15
 */

require_once __DIR__. '/../../vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;

// 不像生產者(publisher),消費者receiver 爲了接收消息 需要監聽(listening) RabbitMQ

$connection = new AMQPStreamConnection('192.168.21.234', 5672, 'guest', 'guest');
$channel = $connection->channel();

//注意, 這裏也聲明瞭隊列(queue),因爲這個消費者啓動的程序 可能 早於生產者程序的啓動,
//在這裏也聲明爲了確保,在我們試着從它裏邊消費時,這個隊列是存在的。
$channel->queue_declare(
    'task_queue', //之前爲hello
    false,
    true,   //之前爲false
    false,
    false
);

//假的任務 消耗的時間,一個點一秒鐘
$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', //之前爲hello
    '',
    false,
    false,  //true 不確認; false 確認
    false,
    false,
    $callback
);

//不論何時,我們接收到了消息,我們將調用 $callback 函數,參數爲"消息"
while ($channel->is_consuming()) {
    $channel->wait();
}

$channel->close();
$connection->close();


3、發佈訂閱模式Publish/Subscribe 

 

 

投遞一個消息給 多個消費者。

模式被叫做   發佈/訂閱  “publish/subscribe”

 

爲了說明這個模式 。我們將 構建一個 簡單的 日誌系統。

發佈日誌 消息 將廣播給 所有 消費者receivers

一個 消費者 worker 記錄日誌到 硬盤; 另一個消費者 worker 打印日誌到 屏幕上。

RbbitMQ 的消息模式裏面,生產者從來 不要直接發送 任何消息到一個 隊列queue.

替代地, 生產者可以 發送消息 到 exchange.   

exchange 決定 發送給哪個 隊列。

exchange 的類型 有 direct, topic, headers  , fanout.

列出 exchanges

sudo rabbitmqctl list_exchanges

default exchange 默認exchange

在之前的教程中,我們不知道exchanges,但是 仍然能夠發送消息給 隊列queues.

這個很可能是因爲: 我們正在使用一個默認的 exchange, 它 被定義 使用 空字符串“”

臨時隊列

1 。不論何時 我們連接到 Rabbit 我們需要一個 新的,空的 隊列。爲了做到這樣,

我們可以創建一個隊列,使用隨機的名字,更好的方式是 讓 rabbitmq server 來選擇一個隨機的名字

,我們來用。

2 。 一旦 我們 斷開連接, 消費者隊列 應該被 自動地刪除。

list($queue_name, ,) = $channel->queue_declare("");

名字可能像:amq.gen-JzTY20BRgKO-HjmUJj0wLg

當聲明它的連接  關閉時, queue 將被 關閉,因爲 它被聲明爲 exclusive

綁定:

已經創建了一個 fanout類型的 exchange 和 一個 queue, 現在

我們需要告訴 exchage 去 發送 消息 給 我們的 queue

$channel->queue_bind($queue_name, 'logs');

相關命令:

列出存在的綁定。

rabbitmqctl list_bindings

生產者代碼:emit_log.php

<?php
/**
 * Author: zhaozhiliang
 * Date: 2020/4/21 下午3:46
 */

require_once __DIR__. '/../../vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

//創建一個 連接 到 RabbitMq服務器
$connection = new AMQPStreamConnection('192.168.21.234', 5672, 'guest', 'guest');

//創建一個channel,大多數 API 都要使用它來做一些事情。
$channel = $connection->channel();

$channel->exchange_declare('logs', 'fanout', false,false, false);

$data = implode('', array_slice($argv, 1));
if (empty($data)) {
    $data = "info: Hello World!";
}

$msg = new AMQPMessage($data);

$channel->basic_publish($msg, 'logs');

echo ' [x] Sent ', $data, "\n";

$channel->close();
$connection->close();

 

如果exchange還沒有綁定隊列,這些消息將被 丟失 。不過這個對我們來說還 ok了,

因爲沒有 消費者正在監聽

消費者代碼:receive_logs.php

<?php
/**
 * Author: zhaozhiliang
 * Date: 2020/4/21 下午4:29
 */

require_once __DIR__ . '/../../vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;

$connection = new AMQPStreamConnection('192.168.21.234', 5672, 'guest', 'guest');
$channel = $connection->channel();

$channel->exchange_declare('logs', 'fanout', false, false, false);

list($queue_name, ,) = $channel->queue_declare("", false, false,true, false);

$channel->queue_bind($queue_name, 'logs');

echo " [*] Waiting for logs. To exit press CTRL+C\n";

$callback = function ($msg) {
    echo ' [x] ', $msg->body, "\n";
};

$channel->basic_consume($queue_name, '', false, true, false, false, $callback);

while ($channel->is_consuming()) {
    $channel->wait();
}

$channel->close();
$connection->close();

如果你想保存日誌 到文件:

php receive_logs.php > logs_from_rabbit.log

如果你想 在屏幕上 看到日誌輸出:

php receive_logs.php

生產者。

php emit_log.php

爲了 解決 如何 去 監聽 一個 消息的子集,看 教程4

4. 路由模式

 

在前面日誌的系統的基礎上,增加功能。

如: 只有 嚴重錯誤的 消息 才記錄到 硬盤上,另一方面打印 所有的日誌信息到控制檯上。

綁定:

$channel->queue_bind($queue_name, 'logs');

可以簡單地讀: 此queue  對 exchange 上的消息 感興趣

 

第三個參數: binding key

binding key 含義 取決於  exchange 類型

對於 fanout 類型 exchange。 我們可以簡單的忽略掉 此參數(不傳遞)

 

Direct 類型 exchange

fanout 類型的 exchange ,這種不能給我們 更多的 靈活性,它只是 簡單的廣播

type =direct  ;  只要queue 它的binding key 匹配上 消息的 routing key ,隊列就能收到消息。

 

多綁定:

多個隊列queue 使用 相同的 binding key。 如果這樣來設計,那麼它的行爲就 類似 fanout。如下圖:

生產日誌/ 發射日誌 (emitting logs)

改進後的日誌系統 使用的 queue 結構如下:

生產者代碼:emit_log_direct.log

<?php
/**
 * Author: zhaozhiliang
 * Date: 2020/4/21 下午3:46
 */

require_once __DIR__. '/../../vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

//創建一個 連接 到 RabbitMq服務器
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');

//創建一個channel,大多數 API 都要使用它來做一些事情。
$channel = $connection->channel();

$channel->exchange_declare('direct_logs', 'direct', false,false, false);

$severity = isset($argv[1]) && !empty($argv[1]) ? $argv[1] : 'info';

$data = implode('', array_slice($argv, 2));
if (empty($data)) {
    $data = "info: Hello World!";
}

$msg = new AMQPMessage($data);

$channel->basic_publish($msg, 'direct_logs', $severity);

echo ' [x] Sent ',$severity, ":",  $data, "\n";

$channel->close();
$connection->close();

消費者代碼:receive_logs_direct.log

<?php
/**
 * Author: zhaozhiliang
 * Date: 2020/4/21 下午4:29
 */

require_once __DIR__ . '/../../vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;

$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();

$channel->exchange_declare('direct_logs', 'direct', false, false, false);

list($queue_name, ,) = $channel->queue_declare("", false, false,true, false);

$severities = array_slice($argv, 1);
if (empty($severities)) {
    file_put_contents('php://stderr', "Usage: $argv[0] [info] [warning] [error]\n");
    exit(1);
}


//對 日誌 各種級別 進行綁定
foreach($severities as $severity) {
    $channel->queue_bind($queue_name, 'direct_logs', $severity);
}

echo " [*] Waiting for logs. To exit press CTRL+C\n";

$callback = function ($msg) {
    echo ' [x] ', $msg->body, "\n";
};

$channel->basic_consume($queue_name, '', false, true, false, false, $callback);

while ($channel->is_consuming()) {
    $channel->wait();
}

$channel->close();
$connection->close();

5 、topics  通配符模式

儘管使用 direct exchange 提高了 我們的系統,它仍然有限制, 它不能 基於多個準則來 路由。

像unix 的 syslog 工具,它 是基於 安全級別( info/warning/critical …) 和 設備來源 (auth/cron/kernel…)

比如 syslog 可以做到 僅 監聽 來自 cron 的errors 信息 和 來自 kern 的所有log信息

我們的log系統 爲了做到 像syslog 那樣,我們需要 topic exchange

routing_key  由  點號連接着的一列單詞 如:quick.orange.rabbit  最大長度 255個字符。

binding keys  有兩個特別重要的情況:

星號* 代替一個單詞

# 號  可以代替 0 或 多個單詞。

 

routing key 由 3個單詞 組成 speed.colour.species   //速度。顏色。物種

我們創建3個 binding key:

Q1  是  用 binding key     *.orange.*

Q2  的 binding key   *.*.rabbit  和 lazy.#

一個消息 它的 routing key 被設置爲 “quick.orange.rabbit” ,將被投遞給 2個queue

消息“ lazy.orange.elephant ,也將被投遞給2個queue

"quick.orange.fox"  將去到 第一個 queue

lazy.brown.fox 將去到 第二個queue

lazy.pink.rabbit" 將被投遞給 第二個 queue 一次。即便是它 和 2個 binding key 都匹配

"quick.brown.fox"  不匹配任何binding ,所以它將被丟棄。

 

像  "orange" or "quick.orange.male.rabbit  是 一個單詞或者 四個單詞 ,不匹配任何 binding key ,將被丟棄

 "lazy.orange.male.rabbit 儘管它有四個單詞,將匹配 lazy.#  將去到 第二個 queue

注意:當一個 queue 綁定了 “#”,它將接收所有的消息,忽略 routing key ,就像 fanout exchange

當 binding key 中沒有 *  和 #,那麼 topic exchange 的行爲就像 direct exchange

生產者代碼:emit_log_topic.php

<?php
/**
 * Author: zhaozhiliang
 * Date: 2020/4/21 下午11:14
 */

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->exchange_declare('topic_logs', 'topic', false, false, false);

$routing_key = isset($argv[1]) && !empty($argv[1]) ? $argv[1] : 'anonymous.info';
$data = implode(' ', array_slice($argv, 2));
if (empty($data)) {
    $data = "Hello World!";
}

$msg = new AMQPMessage($data);

$channel->basic_publish($msg, 'topic_logs', $routing_key);

echo ' [x] Sent ', $routing_key, ':', $data, "\n";

$channel->close();
$connection->close();

消費者代碼:receive_logs_topic.php

<?php
/**
 * Author: zhaozhiliang
 * Date: 2020/4/21 下午11:21
 */

require_once __DIR__ . '/../../vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;

$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();

$channel->exchange_declare('topic_logs', 'topic', false, false, false);

list($queue_name, ,) = $channel->queue_declare("", false, false, true, false);

$binding_keys = array_slice($argv, 1);
if (empty($binding_keys)) {
    file_put_contents('php://stderr', "Usage: $argv[0] [binding_key]\n");
    exit(1);
}

foreach ($binding_keys as $binding_key) {
    $channel->queue_bind($queue_name, 'topic_logs', $binding_key);
}

echo " [*] Waiting for logs. To exit press CTRL+C\n";

$callback = function ($msg) {
    echo ' [x] ', $msg->delivery_info['routing_key'], ':', $msg->body, "\n";
};

$channel->basic_consume($queue_name, '', false, true, false, false, $callback);

while ($channel->is_consuming()) {
    $channel->wait();
}

$channel->close();
$connection->close();

6、 RPC  

如果 我想在 遠端的 計算機上 運行 一個 函數 並等待函數的 返回結果 。 這種模式 通常叫做 RPC

例子 : service 只返回 數字。

Callback queue  

消息的屬性:

AMQP   0-9-1 協議預定義了 14個屬性,大多數 很少用,有幾個還是能用到的 如:

delivery_mode  //標記消息是否是持久的

content_type   //編碼格式,通常使用json編碼,如: application/json

reply_to   //通常用來命名 一個 callback queue

correlation_id  // 用於 關聯 Rpc  response  和  requests

correlation id

如果我們看到一個 unknown 的 correlation_id 值,我們可以安全地刪除 這個消息。

你可能會問,爲什麼我們是忽略 unknown 消息,而不是 發出一個error 錯誤呢。

這是由於 在服務端存在 罕見的情況。

rpc server 發送完answer 後,還沒來得及發送 ack message  給 request,這時候 rpc server 死掉了。

如果這樣的事發生了,重啓rpc server後 將再次處理request。 

這就是爲什麼 client 必須能優雅地處理 重複的 響應,並且 RPC server的處理 也應該是冪等性的。

 

client 代碼:rpc_client.php

<?php
/**
 * Author: zhaozhiliang
 * Email: [email protected]
 * Date: 2020/4/23 下午10:48
 */

require_once __DIR__ . '/../../vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

class FibonacciRpcClient
{
    private $connection;
    private $channel;
    private $callback_queue;
    private $response;
    private $corr_id;
    
    public function __construct()
    {
        $this->connection = new AMQPStreamConnection(
            'localhost',
            5672,
            'guest',
            'guest'
        );
        $this->channel = $this->connection->channel();
        list($this->callback_queue, ,) = $this->channel->queue_declare(
            "",
            false,
            false,
            true,
            false
        );
        
        $this->channel->basic_consume(
            $this->callback_queue,
            '',
            false,
            true,
            false,
            false,
            array(
                $this,
                'onResponse'
            )
        );
    }
    
    public function onResponse($rep)
    {
        if($rep->get('correlation_id') == $this->corr_id) {
            $this->response = $rep->body;
        }
    }
    
    public function call($n)
    {
        $this->response = null;
        $this->corr_id = uniqid();
        
        $msg = new AMQPMessage(
            (string) $n,
            array(
                'correlation_id' => $this->corr_id,
                'reply_to' => $this->callback_queue
            )
        );
        $this->channel->basic_publish($msg, '', 'rpc_queue');
        while(!$this->response) {
            $this->channel->wait();
        }
        return intval($this->response);
        
    }
}

$fibonacci_rpc = new FibonacciRpcClient();
$response = $fibonacci_rpc->call(30);
echo ' [.] Got ', $response, "\n";

 

server代碼:

<?php
/**
 * Author: zhaozhiliang
 * Email: [email protected]
 * Date: 2020/4/22 下午11:50
 */

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('rpc_queue', false, false, false, false);

function fib($n)
{
    if ($n == 0) {
        return 0;
    }
    if ($n == 1) {
        return 1;
    }
    return fib($n-1) + fib($n-2);
}

echo " [x] Awaiting RPC requests\n";

$callback = function($req) {
    $n = intval($req->body);
    echo '[.] fib(', $n, ")\n";
    
    $msg = new AMQPMessage(
        (string) fib($n),
        array('correlation_id' => $req->get('correlation_id'))
    );
    
    $req->delivery_info['channel']->basic_public(
        $msg,
        '',
        $req->get('reply_to')
    );
    
    $req->delivery_info['channel']->basic_ack(
        $req->delivery_info['delivery_tag']
    );
    
};

$channel->basic_qos(null, 1, null);
$channel->basic_consume('rpc_queue',
    '',
    false,
    false,
    false,
    false,
    $callback
    );

while($channel->is_consuming()) {
    $channel->wait();
}

$channel->close();
$connection->close();

 

如果 RPC server 太慢,你可以僅僅 再運行 另外一個 server就可以了

對於client ,client 需要一個 網絡來回 對於一個 單獨的RPC request.

 

 

rabbitmq命令:

sudo rabbitmqctl list_queues

sudo rabbitmqctl list_queues name messages_ready messages_unacknowledged

列出 exchanges

sudo rabbitmqctl list_exchanges

列出存在的綁定。

rabbitmqctl list_bindings

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章