Introduction to RabbitMQ
It must be mentioned that rabbitmq is an open source implementation of a message queuing protocol (AMQP) provided by LShit, written by Erlang, known for its high performance, robustness and scalability (and therefore inherits these advantages).
Baidu Encyclopedia is also very clear about RabbitMQ. It is suggested that we look at it and amqp protocol.
RabbitMQ: http://www.rabbitmq.com/ If you want to download and install, you must first install Erlang.
RabbitMQ's. net client can be easily accessed by entering rabbitmq in nuget.
RabbitMQ compared with other message queues has been written by immortals. Message Queue Shootout
The test cases in this article are: 1 million 1k messages sent and received per second as shown below.
If you install rabbitmq, he will provide an operation monitoring page, the page is as follows, he almost provides all the operation of rabbitmq, and monitoring, so after you install it, you can see more, multi-operation.
Some nouns in RabbitMQ describe the whole process of message delivery to consumption
From the title of the picture above, we can see some unfamiliar English words, which make us feel ignorant and unable to operate. So I've got a picture for you to see. Maybe it will help you understand these new words.
After reading these terms, you may not have a clue, so I will tell you the whole process of news from production to consumption, maybe more in-depth, Exchange, Queue are able to set related properties, queue persistence, switch type.
Note: First of all, this process is divided into three parts: 1. Client (production message queue), 2. RabbitMQ server (responsible for routing rules binding and message distribution), 3. Client (message in consumption message queue)
Note: As can be seen from the graph, a message can travel through the network once but be distributed to different message queues, and then consumed by multiple clients. This process is the core mechanism of RabbitMQ, the route type and consumption mode of RabbitMQ.
Types of Exchange in RabbitMQ
There are four types, direct, fanout, topic, headers. Among them, headers are not commonly used. This article will not introduce them. The other three types will be introduced in detail.
So what do these types mean? After Exchange binds to queues, messages are distributed to message queues according to different binding rules according to the type of exchang. One message can be distributed to multiple message queues or one message can be distributed to a message queue. See below for details.
Let's start with Routing Key. What's this? He is an identifier in the exchange and message queue binding. Some routing types correspond to message queues by identity, while others ignore routing key. See below specifically.
1. Exchange type direct
He looks for queues based on the switch name and routing key.
Note: Messages are sent from client to switch ChangeA, RoutingKey is routingkey.ZLH, so whether you send a message to Queue1 or Queue2, a message will be saved in Queue1, Queue2, Queue3, three queues. This is the direct ed routing rule of the switch. As long as you find the queue that the router binds to routingkey, how many queues it has, and how many queues it distributes.
2. Exchange type fanout
This type ignores Routingkey, which is the broadcast mode.
Note: Messages are sent from the client. As long as queue is bound to exchange, he distributes them to all queues bound to exchang regardless of your Routingkey.
3. Exchange type topic
This type of routing rules is quite useful and flexible if you master them. He matches it according to RoutingKey's settings, and there are two wildcards here:
* It stands for any word. For example, topic.zlh. *, he can match topic.zlh. one, topic.zlh. two, topic.zlh. abc,....
Note: This graph looks messy, but it matches according to the matcher. Here I suggest you do the next message queue specific operation.
The specific operation is as follows
public static void Producer(int value) { try { var qName = "lhtest1"; var exchangeName = "fanoutchange1"; var exchangeType = "fanout";//topic,fanout var routingKey = "*"; var uri = new Uri("amqp://192.168.10.121:5672/"); var factory = new ConnectionFactory { UserName = "123", Password = "123", RequestedHeartbeat = 0, Endpoint = new AmqpTcpEndpoint(uri) }; using (var connection = factory.CreateConnection()) { using (var channel = connection.CreateModel()) { //Setting the type of switch channel.ExchangeDeclare(exchangeName, exchangeType); //Declare a queue, set whether the queue is persistent, exclusive, and automatically delete channel.QueueDeclare(qName, true, false, false, null); //Binding message queues, switches, routing key channel.QueueBind(qName, exchangeName, routingKey); var properties = channel.CreateBasicProperties(); //Queue persistence properties.Persistent = true; var m = new QMessage(DateTime.Now, value+""); var body = Encoding.UTF8.GetBytes(DoJson.ModelToJson<QMessage>(m)); //Send information channel.BasicPublish(exchangeName, routingKey, properties, body); } } } catch (Exception ex) { Console.WriteLine(ex.Message); } }
Consumption of message queues and message acknowledgment Ack
1. Consumption of message queues
Note: If there are a large number of messages waiting for operation in a message queue, we can use multiple clients to process messages. The distribution mechanism here is polling in load balancing algorithm. The first message to A, the next to B, the next to A, the next to B... and so on.
2. In order to ensure the security of the message and ensure that the message is correctly processed before it can be deleted in the message queue of the server. Then rabbitmq provides ack response mechanism to achieve this function.
There are two ways to answer ack: 1. automatic response; 2. manual response. The specific implementation is as follows.
public static void Consumer() { try { var qName = "lhtest1"; var exchangeName = "fanoutchange1"; var exchangeType = "fanout";//topic,fanout var routingKey = "*"; var uri = new Uri("amqp://192.168.10.121:5672/"); var factory = new ConnectionFactory { UserName = "123", Password = "123", RequestedHeartbeat = 0, Endpoint = new AmqpTcpEndpoint(uri) }; using (var connection = factory.CreateConnection()) { using (var channel = connection.CreateModel()) { channel.ExchangeDeclare(exchangeName, exchangeType); channel.QueueDeclare(qName, true, false, false, null); channel.QueueBind(qName, exchangeName, routingKey); //Define the consumers of this queue QueueingBasicConsumer consumer = new QueueingBasicConsumer(channel); //false is a manual response and true is an automatic response channel.BasicConsume(qName, false, consumer); while (true) { BasicDeliverEventArgs ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue(); byte[] bytes = ea.Body; var messageStr = Encoding.UTF8.GetString(bytes); var message = DoJson.JsonToModel<QMessage>(messageStr); Console.WriteLine("Receive a Message, DateTime:" + message.DateTime.ToString("yyyy-MM-dd HH:mm:ss") + " Title:" + message.Title); //If it's an automatic response, don't write the following code. if ((Convert.ToInt32(message.Title) % 2) == 1) { channel.BasicAck(ea.DeliveryTag, false); } } } } } catch (Exception ex) { Console.WriteLine(ex.Message); } }
Original address: https://www.cnblogs.com/knowledgesea/p/5296008.html