Good afternoon, Habr! I want to share a textbook-reference book of knowledge that I managed to collect on RabbitMQ and condense into short recommendations and conclusions.
Table of contents
RabbitMQ. Part 1. Introduction. Erlang, AMQP and RPC
RabbitMQ. Part 2. Understanding Exchanges
RabbitMQ. Part 3. Understanding Queues and Bindings
RabbitMQ. Part 4. Understanding what messages and frames are
RabbitMQ. Part 5: Publishing and Consuming Message Performance
RabbitMQ. Part 6. Overview of the Federation and Shovel Modules
RabbitMQ. Part 7. Details about Connection and Chanel
RabbitMQ. Part 8. RabbitMQ in .NET
RabbitMQ. Part 9. Monitoring
Briefly about AMQP
AMQP (Advanced Message Queuing Protocol) is an open protocol for passing messages between system components. The main idea is that individual subsystems (or independent applications) can exchange messages arbitrarily through an AMQP broker that performs routing, possibly guarantees delivery, distribution of data flows, subscription to the desired message types.
Protocol AMQP introduces three concepts:
exchange (exchange point or exchange) - messages are sent to it. exchange point distributes the message in one or more queues. She routes messages to a queue based on created links (binding) between it and the queue
queue (queue) - a data structure on disk or in RAM, which stores links to messages and gives copies of messages consumers (to consumers)
binding (binding) - a rule that tells the exchange point which of the queues these messages should fall into
The project source code is located in the repository at GitHub. Architecture rabbitmq-server based on Erlang and BEAM.
Erlang developed by the company Ericsson in the mid-1980s as a distributed, fault-tolerant, real-time system for applications requiring 99,999% uptime. Erlang used in various industries and modern applications, for example in WhatsApp. You can read more in the article WhatsApp architecture, which Facebook bought for $19 billion
Briefly about RabbitMQ
Rabbit MQ is an open source message broker. It routes messages according to all the basic principles of the protocol AMQP described in spit-up. RabbitMQ implements and complements the protocol AMQP.
The basic idea of the messaging model in RabbitMQ thing is producer (publisher) does not send messages directly to the queue. In fact, and quite often, the publisher doesn't even know if the message will be delivered to any queue at all.
Instead, the publisher can only send messages to the exchange. On the one hand, the exchange receives messages from publishers, and on the other hand, it sends them to queues. The exchange must know exactly what to do with the received message. Should it be added to a specific queue? Should it be added to multiple queues? Or the message should be ignored.
Briefly work RabbitMQ can be described as follows:
The publisher sends a message to a specific exchange
The exchange, having received a message, routes it to one or more queues in accordance with the binding rules between it and the queue
The queue stores a link to this message. The message itself is stored in RAM or on disk
As soon as the consumer is ready to receive a message from the queue, the server creates a copy of the message by reference and sends
The consumer receives the message and sends an acknowledgment to the broker
The broker, having received confirmation, removes a copy of the message from the queue. Then deletes from RAM and from disk
RPC
Process RPC (remote procedure call) underlies almost all interactions with the nucleus RabbitMQ. For example, initial discussions of client terms with RabbitMQ, shows a certain process RPC. Once this sequence is completed, RabbitMQ will be ready to accept requests from the client:
Also in specification AMQP both client and server can issue commands. This means that the client is waiting to interact with the server. Commands are classes and methods. For example, Connection.Start - method call Start Class Connection.
Connection and channels
For this exchange of information between the client and the server, channels. Channels are created within specific connection. Each channel is isolated from other channels. In the synchronous case, it is not possible to execute the next command until a response is received.
In order to be able to send commands in parallel, you have to open several channels. Each channel creates a separate Erlang process. One connection can have multiple channels (multiplexing). For each channel, there are certain structures and objects in memory. Therefore, the more channels there are within a connection, the more memory is used by RabbitMQ to manage such a connection.
A simple example of creating a connection and a channel using RabbitMQ.Client:
// ...
private void TryConnect()
{
var factory = new ConnectionFactory()
{
HostName = "host_name",
UserName = "user_name",
Password = "p@ssword",
// Включение автоматичекого восстановления
// соединения после сбоев сети
AutomaticRecoveryEnabled = true
};
_connection = factory.CreateConnection();
}
// ...
public void CreateChanel()
{
_channel = _connection.CreateModel();
// other options
}
Opening a new connection for every operation is strongly discouraged as it lead to high costs. Channels also need to be persistent, but many protocol errors cause the channel to close, so the lifetime of a channel can be shorter than that of a connection.
Where is RabbitMQ used?
In the context of microservices, the protocol AMQP and its implementation in RabbitMQ often used for asynchronous interaction between services.
In the context IIOT protocol AMQP and its implementation in RabbitMQ used for data exchange between servers (server-server). Also using the plugin MQTT Plugin RabbitMQ which is an implementation of the protocol MQTT for transferring data between a sensor and a server in low-speed, high-latency environments (for a complete list of supported protocols, see project site).
In the next article, we will begin to understand in more detail with Exchanges.