Prerequisite
This tutorial assumes that RABBITMQ is already installed and is running on a localhost
standard port (5672). If you use a different host, port, or certificate, you need to adjust the connection settings.
Where to get help
If you're having trouble reading this tutorial, you can contact us via the mailing list.
Routing
Use. NET client)
in tutorial [3], we built a simple log system where we could broadcast messages to multiple recipients.
In this tutorial, we'll add a feature to the journaling system that allows it to subscribe to only a subset of messages. For example, print all log messages to
Console, only critical error messages are written to the log file (save to disk space).
Binding
In the previous example, we created a binding. I wonder if you remember the following code:
channel.QueueBind(queue: queueName, exchange: "logs", routingKey: "");
A binding is an association between a exchanger and a queue. It can be simply understood that a queue is interested in messages from this exchanger.
The binding can take an extra routingKey
parameter, in order to avoid confusion with the BasicPublish
same parameter in the method, we call it binding key
(the translator Note: Here is a route key from the declaration angle of a nickname). Here's how to create a binding using the binding key:
channel.QueueBind(queue: queueName, exchange: "direct_logs", routingKey: "black");
The meaning of the binding key depends on the type of exchanger. Like the type of exchanger we used before fanout
, it ignores its value (translator Note: Depending on fanout
the characteristics of the exchanger, it will not be able to broadcast the message to all subscribed queues, even if routingKey
the specified does not filter the message).
Direct switch
In the previous tutorial, our logging system broadcasts all the messages to all consumers, and now we want to extend them to filter messages based on the severity of the messages. For example, we want a script that writes log messages to disk to receive only critical error messages, rather than wasting disk space on messages of a warning or message type.
Previously we used a fanout
switch, but it didn't give us enough flexibility-it could only be broadcast unconsciously.
Now we will replace it with a direct
switch, direct
the routing algorithm behind the switch is simple-the message will go into its binding key
exact routing key
matching queue.
To illustrate this point, please refer to the following settings:
In the settings above, we can see that the direct
type switch is X
bound to two queues. The first queue is bound by key orange
, the second queue has two bindings, one is bound by key black
and the other by key green
.
With this setting, a message that uses a routing key is released to the orange
switch and eventually routed to the queue Q1
, where the route key black
or green
message goes to the queue Q2
, and all other messages are discarded.
Multiple bindings
It is perfectly legal to bind multiple queues with the same binding key. In our example, we can X
Q1
add a key to black
the binding between and. In this case, the direct
Exchanger will fanout
broadcast the message to all matching queues, like a switch, and the routed key will be black
sent to the queue separately Q1
Q2
.
Send log
We will use the above model for the log system, and we will use the direct switch instead of the Fanout type when sending the message. We will use the severity of the log as the routing key, so that the receiving script will be able to choose the severity it expects to receive. Let's focus first on sending logs.
We are going to use the above model in our log system, we will send a message to a direct
type exchanger instead of a fanout
type switch. We will use the severity of the log as routing key
. In this case, the receiving script can selectively receive messages of its expected severity. Let's start by focusing on how to send logs.
As always, we need to create a switch first:
channel.ExchangeDeclare(exchange: "direct_logs", type: ExchangeType.Direct);
Ready to send a message:
var body = Encoding.UTF8.GetBytes(message);channel.BasicPublish(exchange: "direct_logs", routingKey: severity, basicProperties: null, body: body);
For simplicity's sake, we assume that severity
it can be info
, warning
or error
any value.
Subscription
Receiving messages will work like the previous tutorial, with one exception-we will create a new binding for each severity that we are interested in.
As in the previous tutorial, receiving the message this piece works very well, except for a different one--that is, we create a new binding for each severity of interest (log).
You can immediately receive the message as you did in the previous tutorial, but with a different point, we'll create a binding for each of the log severity that we're interested in.
You can immediately receive messages like the previous tutorials, but with a little difference, we need to create a new binding for each log severity that we are interested in.
var queueName = channel.QueueDeclare().QueueName;foreach(var severity in args){ channel.QueueBind(queue: queueName, exchange: "direct_logs", routingKey: severity);}
Grouped together
Code for the
EmitLogDirect.cs
class:
Using system;using system.linq;using rabbitmq.client;using system.text;class emitlogdirect{public static void Main (str Ing[] args) {var factory = new ConnectionFactory () {HostName = "localhost"}; using (var connection = factory. CreateConnection ()) using (var channel = connection. Createmodel ()) {channel. Exchangedeclare (Exchange: "Direct_logs", type: "direct"); var severity = (args. Length > 0)? Args[0]: "Info"; var message = (args. Length > 1)? String. Join ("", args. Skip (1). ToArray ()): "Hello world!"; var BODY = Encoding.UTF8.GetBytes (message); Channel. Basicpublish (Exchange: "Direct_logs", Routingkey:severity, Basicproperties:null, Body:body); Console.WriteLine ("[x] Sent ' {0} ': ' {1} '", Severity, MESsage); } Console.WriteLine ("Press [Enter] to exit."); Console.ReadLine (); }}
Code for the
ReceiveLogsDirect.cs
class:
Using system;using rabbitmq.client;using rabbitmq.client.events;using system.text;class ReceiveLogsDirect{Public static void Main (string[] args) {var factory = new ConnectionFactory () {HostName = "localhost"}; using (var connection = factory. CreateConnection ()) using (var channel = connection. Createmodel ()) {channel. Exchangedeclare (Exchange: "Direct_logs", type: "direct"); var queuename = Channel. Queuedeclare (). QueueName; if (args. Length < 1) {Console.Error.WriteLine ("Usage: {0} [info] [WARNING] [Error]", Environment.getcommandlineargs () [0]); Console.WriteLine ("Press [Enter] to exit."); Console.ReadLine (); Environment.exitcode = 1; Return } foreach (var severity in args) {channel. Queuebind (Queue:queuename, Exchange: "Direct_logs", routingkey:severity); } Console.WriteLine ("[*] waiting for messages."); var consumer = new Eventingbasicconsumer (channel); Consumer. Received + = (model, ea) = {var BODY = ea. Body; var message = Encoding.UTF8.GetString (body); var routingkey = ea. Routingkey; Console.WriteLine ("[x] Received ' {0} ': ' {1} '", Routingkey, message); }; Channel. Basicconsume (Queue:queuename, Autoack:true, Consumer:co Nsumer); Console.WriteLine ("Press [Enter] to exit."); Console.ReadLine (); } }}
Create your project as usual (see tutorial [1]).
If you only want to warning
error
save and (not include info
) the log messages to a file, simply open the console and enter:
cd ReceiveLogsDirectdotnet run warning error > logs_from_rabbit.log
If you want to see all the log messages on the screen, open a new terminal and do the following:
cd ReceiveLogsDirectdotnet run info warning error# => [*] Waiting for logs. To exit press CTRL+C
For example, to issue error
a log message, you only need to enter:
cd EmitLogDirectdotnet run error "Run. Run. Or it will explode."# => [x] Sent 'error':'Run. Run. Or it will explode.'
Full source code for EmitLogDirect.cs and ReceiveLogsDirect.cs.
Skip to tutorial [5] to learn how to listen for messages based on patterns.
Written in the last
This article is translated from the RABBITMQ official Tutorial C # version. This article describes if there is a discrepancy with the official, please take the official latest content prevail.
The level is limited, translation is not good please forgive me, if there are translation errors please correct me.
- original link: RabbitMQ tutorial-routing
- Lab Environment: RabbitMQ 3.7.4,. NET Core 2.1.3, Visual Studio Code
- Last NEW: 2018-08-31