訳-PaHP rabbitMQ Tutorial-5

9863 ワード

Topics
(using php-amqplib)
In the previous tutorial we improved our logging system. Instead of using a fanout exchange only capable of dummy broadcasting, we used a direct one, and gained a possibility of selectively receiving the logs.
前節では、ログシステムを改善しました.fanoutスイッチの代わりにバカなブロードキャストしかできないので,指向性スイッチを用いて,メッセージの選択的受信を可能にした.
Although using the direct exchange improved our system, it still has limitations - it can't do routing based on multiple criteria.
指向性スイッチを使用すると、システムが改善されますが、多重条件に基づいてルーティングできないという限界があります.
In our logging system we might want to subscribe to not only logs based on severity, but also based on the source which emitted the log. You might know this concept from the syslog unix tool, which routes logs based on both severity (info/warn/crit...) and facility (auth/cron/kern...).
ログ・システムでは、重大度レベルに基づくコンテンツだけでなく、メッセージ・パブリケーション・ソースに基づくコンテンツもサブスクリプションしたい場合があります.この概念はsyslog unixツールから知ることができます.重大度とデバイスルーティングログに基づいています.
That would give us a lot of flexibility - we may want to listen to just critical errors coming from 'cron' but also all logs from 'kern'.
それは私たちに大きな柔軟性をもたらします.cronからの致命的なエラーとkernからのすべてのメッセージを聞くだけだと思います.
To implement that in our logging system we need to learn about a more complex topic exchange.
私たちのログシステムでこの柔軟性を実現するためには、より複雑なtopicスイッチを学ぶ必要があります.
Topic exchange
Messages sent to a topic exchange can't have an arbitrary routing_key - it must be a list of words, delimited by dots. The words can be anything, but usually they specify some features connected to the message. A few valid routing key examples: "stock.usd.nyse", "nyse.vmw", "quick.orange.rabbit". There can be as many words in the routing key as you like, up to the limit of 255 bytes.
topicスイッチに送信されたメッセージは、任意のrouting_に送信できません.key-カンマで区切られた単語のリストでなければなりません.
The binding key must also be in the same form. The logic behind the topic exchange is similar to a direct one - a message sent with a particular routing key will be delivered to all the queues that are bound with a matching binding key. However there are two important special cases for binding keys:
binding keyも同じフォーマットでなければなりません.topicスイッチの背後にある論理は指向性スイッチと似ています.特定のrouting keyを持つメッセージは、routing keyに一致するbinding keyをバンドルしたすべてのキューに送信されます.
  • * (star) can substitute for exactly one word.
  • *(アスタリスク)は、単語
  • を表すことができます.
  • # (hash) can substitute for zero or more words.
  • #(井戸番号)は、0個以上の単語
  • を表すことができる.
    It's easiest to explain this in an example:
    In this example, we're going to send messages which all describe animals. The messages will be sent with a routing key that consists of three words (two dots). The first word in the routing key will describe speed, second a colour and third a species: "..".
    この例では、動物を記述するすべてのメッセージを送信します.送信時、これらのメッセージには3つの単語(2つのポイント番号で区切る)からなるrouting keyがある.最初の単語は速度を表すために使用され、2番目は色を表すために使用され、最後の単語は種類を表すために使用されます:「..
    We created three bindings: Q1 is bound with binding key "*.orange.*"and Q2 with "*.*.rabbit"and "lazy.#".
    3つのバンドルを作成する:「*.orange.*」でQ 1をバインドし、「*.*.rabbit」と「lazy.#」でQ 2をバインドする.
    These bindings can be summarised as:
    これらのバンドルは、次のように要約できます.
  • Q1 is interested in all the orange animals.
  • Q 1すべてのオレンジ色の動物が好き
  • Q2 wants to hear everything about rabbits, and everything about lazy animals.
  • Q 2ウサギや怠惰な動物について知りたい
  • A message with a routing key set to "quick.orange.rabbit"will be delivered to both queues. Message "lazy.orange.elephant"also will go to both of them. On the other hand "quick.orange.fox"will only go to the first queue, and "lazy.brown.fox"only to the second. "lazy.pink.rabbit"will be delivered to the second queue only once, even though it matches two bindings. "quick.brown.fox"doesn't match any binding so it will be discarded.
    どちらのキューもrouting keyが「quick.orange.rabbit」に設定されているというメッセージを受信します.「lazy.orange.elephant」に設定したのも同じです.
    ただし、「quick.orange.fox」は最初のキューにのみ入り、「lazy.brown.fox」は2番目のキューにのみ入ります.「lazy.pink.rabbit」は、2つの困難なルールに一致するが、2番目のキューに1回だけ入る.「quick.brown.fox」は誰とも一致しないため、破棄されます.
    What happens if we break our contract and send a message with one or four words, like "orange"or "quick.orange.male.rabbit"? Well, these messages won't match any bindings and will be lost.
    もし私たちの制約を破ったらどうなりますか?たとえば、「orange」や「quick.orange.male.rabbit」のような1つまたは4つの単語を持つメッセージを送信します.
    よし!バンドルルールに一致しないため、メッセージが失われます.
    On the other hand "lazy.orange.male.rabbit", even though it has four words, will match the last binding and will be delivered to the second queue.
    しかし「lazy.orange.male.rabbit」というrouting keyは、4つの単語があるにもかかわらず、2番目のキューに入ります(ニャーのために?
    Topic exchange
    Topic exchange is powerful and can behave like other exchanges.
    Topicスイッチは強力で、他のスイッチの動作をシミュレートすることができます.
    When a queue is bound with "#"(hash) binding key - it will receive all the messages, regardless of the routing key - like in fanout exchange.
    キューが#のbinding keyをバンドルすると、fanoutスイッチのようにrouting keyを無視してすべてのメッセージを受信します.△何を意味するか覚えていますか.
    When special characters "*"(star) and "#"(hash) aren't used in bindings, the topic exchange will behave just like a direct one.
    バンドルで特殊文字のアスタリスクと井戸番号が使用されていない場合、topicスイッチの動作は指向性スイッチと同じです.
    Putting it all together(合体!!!うんざりでしょ?ハッ、もう一回!)
    We're going to use a topic exchange in our logging system. We'll start off with a working assumption that the routing keys of logs will have two words: ".".
    ログシステムでtopicスイッチを使用します.ログのrouting keyesには「.」があると仮定します.
    The code is almost the same as in the previous tutorial.
    コードは以前のほとんどのお母さんと生まれました.
    The code for emit_log_topic.php:
    emit_log_topic.phpコード:
    <?php
    
    require_once __DIR__ . '/vendor/autoload.php';
    use PhpAmqpLib\Connection\AMQPConnection;
    use PhpAmqpLib\Message\AMQPMessage;
    
    $connection = new AMQPConnection('localhost', 5672, 'guest', 'guest');
    $channel = $connection->channel();
    
    $channel->exchange_declare('topic_logs', 'topic', false, false, false);
    
    $routing_key = $argv[1];
    if(empty($routing_key)) $routing_key = "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," 
    "; $channel->close(); $connection->close(); ?>

    The code for receive_logs_topic.php:
    <?php
    
    require_once __DIR__ . '/vendor/autoload.php';
    use PhpAmqpLib\Connection\AMQPConnection;
    
    $connection = new AMQPConnection('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]
    "); 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', "
    "; $callback = function($msg){ echo ' [x] ',$msg->delivery_info['routing_key'], ':', $msg->body, "
    "; }; $channel->basic_consume($queue_name, '', false, true, false, false, $callback); while(count($channel->callbacks)) { $channel->wait(); } $channel->close(); $connection->close(); ?>

    To receive all the logs:
    すべてのログを受信:
    $ php receive_logs_topic.php "#"
    

    To receive all logs from the facility "kern":
    kernからのすべてのログを受信します.
    $ phpreceive_logs_topic.php "kern.*"
    

    Or if you want to hear only about "critical"logs:
    あるいは「致命的」なログだけを受信したいと思っています
    $ php receive_logs_topic.php "*.critical"
    

    You can create multiple bindings:
    多重バインドもできます
    $ php receive_logs_topic.php "kern.*" "*.critical"
    

    And to emit a log with a routing key "kern.critical"type:
    「kern.critical」routing key付きのログを発行するには、次のように入力します.
    $ php emit_log_topic.php "kern.critical" "A critical kernel error"
    

    Have fun playing with these programs. Note that the code doesn't make any assumption about the routing or binding keys, you may want to play with more than two routing key parameters.
    上のコードがルーティングやバンドルされていない例に注意して、2つ以上のrouting keyパラメータを体験したいかもしれません.
    Some teasers:
  • Will "*"binding catch a message sent with an empty routing key?
  • アスタリスクは空のrouting keyのメッセージに一致しますか?
  • Will "#.*"catch a message with a string ".."as a key? Will it catch a message with a single word key?
  • "#.*"は"."に一致します.メッセージですか?単一の単語に一致しますか?
  • How different is "a.*.#"from "a.#"?
  • 「a.*.#」と「a.#」の違いは何ですか?
  • (Full source code for emit_log_topic.php and receive_logs_topic.php)
    Emit_log_topic.phpおよびreceive_logs_topic.phpソースコード.
    Next, find out how to do a round trip message as a remote procedure call in tutorial 6
    次回は、リモート・プロシージャ呼び出しのように情報の往復を完了する方法について説明します.