RabbitMQ Erlang "Topics"

Source: Internet
Author: User
Tags rabbitmq

Original link: http://www.rabbitmq.com/tutorials/tutorial-five-python.html

In the previous example, we improved our log system. Exchage with the Fanout type can only broadcast messages. Instead of using direct, we get the possibility of selectively receiving messages.

Although using the direct type of exchange improves our system, it is still flawed and cannot be routing based on multiple criteria.

In our log system, we may want to subscribe to logs not only based on severity, but also based on the source code of the release log. You may know the concept of the Syslog UNIX tool, which is based on strict (Info/warning/crit ...). and dexterous (Auth/cron/kern).
This will give us a lot of flexibility-we may want to listen to serious errors and all the logs in Kern that come only from the ' Corn ' log.

In order to implement that in our log system, we need to learn more complex topic exchange.

Topic Exchange

Messages sent to topic Exchange cannot be arbitrarily defined by a routing key--routing key must be a "." List of words separated by a number. The word can be arbitrary, but in general it should represent some of the characteristics of the message. For example, some of the following routing key:

"Stock.usd.nyse" "NYSE.VMW" "Quick.orange.rabbit"

Routing Key has a maximum length limit of 255 bytes.

The binding key for the queue must also be in the same format. Topic Exchange logic is similar to direct exchange-a message with the specified routing key will be sent to the message queue with the same binding key.

Binding Key has two exceptions:

    • * (Star) represents a word

    • # (hash) represents 0 or more words

As the following example

In this example we will send a message describing the animal. The routing key of a message consists of three words, the first word represents the speed of the animal, the second word represents the color of the animal, and the third word represents the species of the animal. "<celerity>.<colour>.<species>"

We create three bindings: Q1 uses the binding key "*.orange.*", Q2 uses the binding key "*.*.rabbit" and "lazy.#". That is to say, Q1 is interested in animals that are colored orange, and Q2 is interested in all rabbit and speed-lazy animals.

Messages Routing key ' Qucik.orange.rabbit ' will be sent Q1 and Q2 queues, and "lazy.orange.elephant" messages will also be sent to Q1 and Q2.  "Quick.orange.fox" just go to Q1, "Lazy.brown.fox" only to Q2. "Lazy.pink.rabbit" will be sent to Q2 once, although it matches two bindings. "Quick.brown.fox" does not match any binding, so it is discarded.

If we break the rules, what happens if we send a word or a four-word message, such as "orange" or "quick.orange.male.rabbit"? Well, this message will not match any one of the bindings and will be discarded.

Another situation, "lazy.orange.male.rabbit", although he is also four words, but it will match Q2 binding will be sent to Q2. Because it matches the "lazy.#"

Tipic Exchange is powerful and you can behave like other exchanges.

When a queue's binding key is "#" (hash)-it will receive all messages, ignoring routing key: to Fanout exchange.

The topic Echange and direct exchange behavior will be the same when the "*" and "#" special characters are not used in bindings.

Putting it all together

We ' re going to use aTopic exchange in our logging system. We'll start off with a working assumption that the routing keys of logs would have both words: "<facility>.<severity>".

emit_log_topic.erl

-module (emit_log_topic).-compile ([Export_all]).-include_lib ("Amqp_client/include/amqp_client.hrl"). Main (ARGV)  ->    {ok, Connection} =         amqp_connection:start (#amqp_params_network {host =  "localhost"}),     {ok,  channel} = amqp_connection:open_channel (Connection),     amqp_channel:call ( channel, # ' Exchange.declare ' {exchange = << "Topic_logs" >>,                                                      type = << "topic" &GT;&GT;}),     {RoutingKey, Message} = case Argv of                                  [] ->                                      {<< "Anonymous.info" >>, << "hello  world! " >>};                                 [R] ->                                      { List_to_binary (R), << "hello world!" >>};                                 [R | Msg] ->                                      {list_to_binary (R),  list_to_binary (String:join (Msg,  " ")}                             end,    amqp_ Channel:cast (channel,                       # ' Basic.publish ' {                         exchange  = << "Topic_logs" >>,                         routing_key = RoutingKey},                        #amqp_ Msg{payload = message}),     io:format (" [x] sent ~p:~p~n",  [ Routingkey, message]),     ok = amqp_channel:close (channel),     ok = amqp_connection:close (connection),     ok.

Receiver_logs_topic.erl

-module (receive_logs_topic).-compile ([Export_all]).-include_lib ("Amqp_client/include/amqp_client.hrl"). Main ( ARGV)  ->    {ok, Connection} =         amqp_connection:start (#amqp_params_network {host =  "localhost"}),     {ok,  channel} = amqp_connection:open_channel (Connection),     amqp_channel:call ( channel, # ' Exchange.declare ' {exchange = << "Topic_logs" >>,                                                      type = << "topic" &GT;&GT;}),     # ' QUEUE.DECLARE_OK ' {queue = queue} =         amqp_chaNnel:call (channel, # ' Queue.declare ' {exclusive = true}),     [amqp_channel: Call (channel, # ' Queue.bind ' {exchange = << "Topic_logs" >>,                                                 routing_key = list_to_binary (Bindingkey),                                                 queue = queue})      | |  bindingkey <- argv],    io:format (" [*] waiting for  logs. to exit press&nbsP Ctrl+c~n "),     amqp_channel:subscribe (channel, # ' Basic.consume ' {queue =  queue,                                                       no _ack = true}, self ()),    receive         # ' Basic.consume_ok ' {} -> ok    end,    loop (Channel ). Loop (Channel)  ->    receive        {# ' Basic.deliver ' {routing_key = routingkey},  #amqp_msg {payload = body}} ->             io:format (" [x] ~p:~p~n",  [ Routingkey, boDY]),             loop (Channel)      end.

Receive all the logs

Receive all logs from facility that are "kern"

Receive the "Critical" log:

To create multiple bindings:

Send a log of "kern.critical" type routing key:



RabbitMQ Erlang "Topics"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.