RabbitMQ は、アーラン言語で開発された人気のオープンソース メッセージ キュー システムであり、AMQP (Advanced Message Queuing Protocol) を完全に実装しています。 Web サイトは次のとおりです: http://www.rabbitmq.com/ チュートリアルとサンプル コード (Python および Java) があります。
7af40ad162d9f2d36b6bf89fa8ec8a136327cc4c
AMPQ プロトコルは、さまざまなメッセージ キューの要件を満たすために概念的に複雑です。まず、rabbitMQ はデフォルトで何も設定せずに起動しますが、動作するにはクライアントの接続、スイッチの設定などが必要です。これらの基本的な考え方が明確になっていないと、その後のプログラミング設計で問題が発生しやすくなります。
1.vhosts: 仮想ホスト。
RabbitMQ エンティティは複数の仮想ホストを持つことができ、ユーザーと権限の設定は仮想ホストに依存します。一般的な PHP アプリケーションの場合、ユーザー権限の設定は必要ありません。デフォルトで存在する「/」を使用するだけで済みます。簡単な設定例:
$conn_args = array(
'host' => '127.0.0.1',
'port' => '5672',
'login' => 'guest',
'password ' = > 'guest',
'vhost'=>'/'
);
2. 接続とチャネル: 接続とチャネル
接続は、クライアントとサーバーの間に接続があります。接続上で確立できます。これは論理接続として理解できます。一般的なアプリケーションでは、1 つのチャネルで十分であり、さらにチャネルを作成する必要はありません。サンプルコード:
//接続とチャネルを作成します
$conn = new AMQPConnection($conn_args);
if (!$conn->connect()) {
die("ブローカーに接続できません!n");
}
$channel = new AMQPChannel($conn);
3.exchange と routingkey: スイッチとルーティング キー
さまざまな種類のメッセージを区別するために、スイッチとルーティングの 2 つの概念が設定されています。たとえば、タイプ A のメッセージを「C1」という名前のスイッチに送信し、タイプ B のメッセージを「C2」という名前のスイッチに送信します。クライアントが C1 に接続してキュー メッセージを処理する場合、タイプ A のメッセージのみを取得します。さらに、タイプ A のメッセージが多数ある場合は、区別をさらに改良する必要があります。たとえば、クライアントが K 人のユーザーに対するタイプ A のメッセージのみを処理する場合、この目的にルーティングキーが使用されます。
$e_name = 'e_linvo'; //スイッチ名
$k_route = array(0=> 'key_1', 1=> 'key_2') //ルーティングキー
//スイッチを作成します
$ex = 新しい AMQPExchange ($channel);
$ex->setName($e_name);
$ex->setType(AMQP_EX_TYPE_DIRECT); //ダイレクトタイプ
$ex->setFlags(AMQP_DURABLE); //persistence
echo Status:".$ex->declare()."n";
for($i=0; $i echo "Send Message:".$ex->publish ($message . date('H:i:s'), $k_route[i%2])."n";
}
上記のコードからわかるように、メッセージを送信するときは、 「スイッチ」だけで十分です。スイッチの背後に対応する処理キューがあるかどうかについては、送信側は気にする必要はありません。 routingkey は空の文字列にすることができます。この例では、以下のルーティング キーの役割を理解しやすくするために、2 つのキーを使用してメッセージを交互に送信します。
スイッチには 2 つの重要な概念があります:
A、タイプ。 3 つのタイプがあります。ファンアウト タイプが最も単純で、このモデルはルーティング キーを無視します。ダイレクト タイプは、特定のルーティング キーを使用して最もよく使用されます。このモデルでは、メッセージの受信時に 'key_1' をバインドすると、key_1 のメッセージのみを受信します。最後のメッセージは Topic です。これは Direct に似ていますが、'key_*' などのワイルドカード マッチングをサポートします。 key_1 と key_2 を受け入れます。トピックは見栄えがしますが、不正確になる可能性があるため、ダイレクトを使用することをお勧めします。
B、粘り強さ。永続的に指定されたスイッチは再起動時にのみ再構築できます。それ以外の場合は、クライアントが世代を再宣言する必要があります。
特に明確な概念が必要です。スイッチの永続性はメッセージの永続性と等しくありません。永続化できるのは永続化キュー内のメッセージだけです。キューがない場合、メッセージには保存する場所がありません。PHP では、メッセージ自体にも永続化スイッチに配信されるメッセージが永続化されます。永続的なメッセージ。アドホックは必要ありません。
4.queue: キュー
ここまで話した後は、キューについて話しましょう。実際、キューは受信者 (消費者) 専用であり、要求に基づいて受信者によって作成されます。スイッチは、キューが作成された場合にのみ、新しく受信したメッセージをキューに送信します。キューが作成される前に、スイッチはメッセージを書き込みません。つまり、キューが確立される前に送信されたメッセージはすべて破棄されます。下の図は、RabbitMQ の公式図よりも鮮明です。キューは ReceiveMessage の一部です。
024f78f0f736afc37053e415b219ebc4b7451266
$e_name = 'e_linvo'; //スイッチ名
$q_name = 'q_linvo' //キュー名
$k_route = ''; /ルーティングkey
//接続とチャネルを作成します
$conn = new AMQPConnection($conn_args);
if (!$conn->connect()) {
die("ブローカーに接続できません!n");
}
$channel = new AMQPChannel($conn);
//スイッチを作成します
$ex = new AMQPExchange($channel);
$ex->setName($e_name);
$ex->setType(AMQP_EX_TYPE_DIRECT); / /direct type
$ex->setFlags(AMQP_DURABLE); //Persistence
echo "Exchange Status:".$ex->declare()."n";
//キューを作成
$q = new AMQPQueue ($channel);
$q->setName($q_name);
$q->setFlags(AMQP_DURABLE); //Persistence
//ルーティングキーを指定します
echo 'Queue Bind : '.$q->bind($e_name, $k_route)."n";
//ブロッキングモードでメッセージを受信
echo "Message:n";
$q->consume('processMessage', AMQP_AUTOACK ) ; //自動 ACK 応答
$conn->disconnect();
/**
* 消費コールバック関数
* メッセージの処理
*/
function processMessage($envelope, $queue) {
var_dump($envelope->getRoutingKey);
$ msg = $envelope->getBody();
echo $msg."n"; //メッセージの処理
}
上記の例からわかるように、スイッチはメッセージ送信者またはメッセージ消費者によって作成できます。
キューを作成した後 (行:20)、キューが機能するためには、キューをスイッチ (行:25) にバインドする必要があります。ルーティングキーもここで指定します。一部の情報では「bindingkey」と書かれていますが、これは実際には同じものです。2 つの名詞を使用すると混同しやすくなります。
メッセージを処理するには 2 つの方法があります:
A、1 回限り。 $q->get([...]) を使用すると、メッセージが取得されたかどうかに関係なく、このメソッドはポーリング
B を使用してメッセージ キューを処理するために使用されます。 $q->consum( callback, [...] ) を使用すると、プログラムはメッセージを受信するたびに、コールバックで指定された関数が一度呼び出され、一定の時間になるまで終了しません。コールバック関数は FALSE を返します。
コールバックに関して、さらにいくつか説明します。PHP の call_back は、たとえば、次のように配列の使用をサポートしています。 $c = new MyClass(); $c->counter = 100; , 'myfunc') ) このようにして、作成した処理クラスを呼び出すことができます。 MyClass の myfunc のパラメータ定義は、上記の例の processMessage のパラメータ定義と同じです。
上記の例では、 $routingkey = '' を使用することは、すべてのメッセージを受信することを意味します。これを $routingkey = 'key_1' に変更すると、結果の唯一の内容が routingkey を key_1 に設定していることがわかります。
注: routingkey = 'key_1' と routingkey = 'key_2' は 2 つの異なるキューです。前提: client1 と client2 は両方とも key_1 のキューに接続されています。メッセージは client1 によって処理された後、client2 によって処理されません。 Routingkey = '' は別の代替方法です。 client_all は '' にバインドされます。すべてのメッセージが処理されると、client1 と client2 にはメッセージがなくなります。
プログラム設計の観点からは、交換の名前、さまざまな種類のタグを区別するためのキーの使用方法、メッセージが生成される場所にメッセージ送信コードを挿入する方法を計画する必要があります。バックエンド処理では、キーごとに 1 つ以上のクライアントを起動して、メッセージ処理のリアルタイム性を向上させることができます。マルチスレッドのメッセージ処理に PHP を使用する方法については、次のセクションで説明します。
その他のメッセージ モデルについては、以下を参照してください: http://www.rabbitmq.com/tutorials/tutorial-two-python.html
b03533fa828ba61e15fc0e5f4034970a304e59b4
http://nonfu.me/p/8833.html
以上、RabbitMQ と PHP (1) - RabbitMQ の原理と動作例を、関連コンテンツも含めて紹介しました。PHP チュートリアルに興味のある友人の参考になれば幸いです。