{"id":73065,"date":"2020-03-06T20:42:13","date_gmt":"2020-03-06T17:42:13","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings"},"modified":"2020-03-06T20:42:13","modified_gmt":"2020-03-06T17:42:13","slug":"rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings","status":"publish","type":"post","link":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings","title":{"rendered":"RabbitMQ. Part 3. Understanding Queues and Bindings","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><code>Queue<\/code> (queue) \u2014 a data structure on disk or in memory that stores references to messages and returns their copies <code>consumers<\/code> (to consumers). <code>Queue<\/code> is a <noindex><a rel=\"nofollow\" href=\"http:\/\/erlang.org\/doc\/reference_manual\/processes.html\">Erlang process<\/a><\/noindex> with state (where the messages themselves can be cached). 1,000 queues can take up roughly 80Mb.<\/p>\n<p><\/p>\n<p><code>Binding<\/code> (binding) \u2014 a rule that tells the broker which queue messages should go to.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3 id=\"oglavlenie\">Table of Contents<\/h3>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/488654\/\">RabbitMQ. Part 1. Introduction. Erlang, AMQP and RPC<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/489086\/\">RabbitMQ. Part 2. Understanding Exchanges<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/490960\/\">RabbitMQ. Part 3. Understanding Queues and Bindings<\/a><\/noindex><\/li>\n<li>RabbitMQ. Part 4. Understanding what messages and frames are<\/li>\n<li>RabbitMQ. Part 5. Performance of Message Publishing and Consumption<\/li>\n<li>RabbitMQ. Part 6. Overview of Federation and Shovel Modules<\/li>\n<li>RabbitMQ. Part 7. Detailed about Connection and Channel<\/li>\n<li>RabbitMQ. Part 8. RabbitMQ in .NET<\/li>\n<li>RabbitMQ. Part 9. Monitoring<\/li>\n<\/ul>\n<p><\/p>\n<h4 id=\"vremennye-ocheredi\"><em>Temporary queues<\/em><\/h4>\n<p><\/p>\n<p>If a queue is created with a set parameter <code>autoDelete<\/code>, then such a queue gains the ability <strong>to automatically delete itself<\/strong>. Such queues are usually created when the first client connects and are deleted when all clients disconnect. <\/p>\n<p><\/p>\n<p>If a queue is created with a set parameter <code>exclusive<\/code>, then such a queue <strong>allows only one consumer to connect<\/strong> and is deleted if the channel closes. Until the channel closes, the client can disconnect\/reconnect, but only within the same connection. If the parameter <code>exclusive<\/code> is set, then the parameter <code>autoDelete<\/code> has no effect.<\/p>\n<p><\/p>\n<p>Features:<\/p>\n<p><\/p>\n<ul>\n<li>in case of a brief disconnection we will lose messages that have not yet reached the consumer<\/li>\n<li>we may encounter the phenomenon <code>binding churn<\/code>. This phenomenon occurs when the number of create\/delete operations for queues and bindings reaches very large values. In clustered mode, such a flow of operations will spread across all nodes and create a substantial load. This process can be optimized by controlling the number of subscriptions.<\/li>\n<\/ul>\n<p><\/p>\n<h4 id=\"postoyannye-ocheredi\"><em>Durable queues<\/em><\/h4>\n<p><\/p>\n<p>If a queue is created with a set parameter <code>durable<\/code>, then such a queue <strong>retain their state<\/strong> and recover after the server\/broker restarts. This queue will exist until the command is invoked <code>Queue.Delete<\/code>. <\/p>\n<p><\/p>\n<h4 id=\"highly-available-ocheredi\"><em>Highly Available queues<\/em><\/h4>\n<p><\/p>\n<p>HA queues require a clustered RabbitMQ environment. In clustered mode, all information about exchanges, queues, bindings, and consumers will be copied to all nodes.<\/p>\n<p><\/p>\n<p>When a message is published to an HA queue, it is stored on each node related to that HA queue. After the message is consumed on one of the nodes, all copies of that message will be deleted on the other nodes. <\/p>\n<p><\/p>\n<p>HA queues can span all nodes in a cluster or be limited to individual ones. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Part 3. Understanding Queues and Bindings\" src=\"\/wp-content\/uploads\/2020\/03\/46d560ab33e686ddf9adb0b18b4bb0b0.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Features:<\/p>\n<p><\/p>\n<ul>\n<li>Using HA queues leads to performance penalties. When placing a message into a HA queue or consuming a message from a HA queue, RabbitMQ must coordinate across all nodes (usually 2-3 nodes are sufficient).<\/li>\n<\/ul>\n<p><\/p>\n<h4 id=\"sozdanie-ocheredi\"><em>Creating a queue<\/em><\/h4>\n<p><\/p>\n<p>The creation of a queue occurs through a synchronous <code>RPC<\/code> request to the server. The request is made using the method <code>Queue.Declare<\/code>, called with the parameters:<\/p>\n<p><\/p>\n<ul>\n<li>the name of the queue<\/li>\n<li>other parameters<\/li>\n<\/ul>\n<p><\/p>\n<p>Example of creating a queue using <noindex><a rel=\"nofollow\" href=\"https:\/\/www.rabbitmq.com\/dotnet.html\">RabbitMQ.Client<\/a><\/noindex>:<\/p>\n<p><\/p>\n<pre><code class=\"cs\">\/\/ ...\nchannel.QueueDeclare(\n    queue: &quot;my_queue&quot;,\n    durable: false,\n    exclusive: false,\n    autoDelete: false,\n    arguments: null\n);\n\/\/ ...<\/code><\/pre>\n<p><\/p>\n<ul>\n<li><code>queue<\/code> \u2014 the name of the queue we want to create. The name must be unique and cannot coincide with a system queue name.<\/li>\n<li><code>durable<\/code> \u2014 if true, the queue will <strong>save its state<\/strong> and be restored after the server\/broker restarts.<\/li>\n<li><code>exclusive<\/code> \u2014 if true, the queue will allow only one consumer to connect.<\/li>\n<li><code>autoDelete<\/code> \u2014 if true, the queue gains the ability <strong>to automatically delete itself<\/strong><\/li>\n<li><code>arguments<\/code> \u2014 optional arguments. Let's discuss in more detail below.<\/li>\n<\/ul>\n<p><\/p>\n<h5 id=\"arguments\"><em>arguments<\/em><\/h5>\n<p><\/p>\n<ul>\n<li><code>x-message-ttl<\/code>(<code>x-message-time-to-live<\/code>) \u2014 allows you to set the expiration time for messages in milliseconds. If the queue is created with a set argument value <code>x-message-ttl<\/code>, then such a queue will <strong>automatically discard messages that have expired.<\/strong>Setting the argument value <code>x-message-ttl<\/code> specifies the maximum age for all messages in this queue. Creating such a queue <strong>helps prevent receiving outdated information.<\/strong>This can be utilized in real-time systems. If a queue that has a dead-letter exchange is set with the argument value <code>x-message-ttl<\/code>, then rejected messages in this queue <strong>will start having an expiration time.<\/strong>.<\/li>\n<li><code>x-expires<\/code> \u2014 sets the value in milliseconds after which the queue is deleted. A queue can only expire if it has no subscribers. If there are subscribers connected to the queue, it can only be automatically deleted when all subscribers call <code>Basic.Cancel<\/code> or disconnect. The lifespan of the queue can only end if there hasn't been a request to it <code>Basic.Get<\/code>. Otherwise, the current expiration setting is reset, and the queue will no longer be automatically deleted. Also <strong>there are no guarantees on how quickly the queue is deleted after its expiration<\/strong>.<\/li>\n<li><code>x-max-length<\/code> \u2014 sets the maximum number of messages in the queue. If the number of messages in the queue exceeds the maximum, the oldest messages will start to be deleted<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Part 3. Understanding Queues and Bindings\" src=\"\/wp-content\/uploads\/2020\/03\/738f23dcfdd173a66be619032b46c5cc.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ul>\n<li><code>x-max-length-bytes<\/code> \u2014 sets the maximum allowed total size of the payload of messages in the queue. If the established value is exceeded (a queue overflow occurs upon the next message publication), the oldest messages will begin to be deleted<\/li>\n<li><code>x-overflow<\/code> \u2014 this argument is used to configure the behavior resulting from a queue overflow. Two values are available: <code>drop-head<\/code> (default value) and <code>reject-publish<\/code>. If you choose <code>drop-head<\/code>, the oldest messages will be deleted. If you choose <code>reject-publish<\/code>, message reception will be suspended<\/li>\n<li><code>x-dead-letter-exchange<\/code> \u2014 specifies the exchange to which rejected messages that are not re-queued are sent<\/li>\n<li><code>x-dead-letter-routing-key<\/code> \u2014 specifies an optional routing key for rejected messages<\/li>\n<li><code>x-max-priority<\/code> \u2014 allows sorting by priorities in the queue with a maximum priority value of 255 (RabbitMQ versions 3.5.0 and higher). The number specifies the maximum priority that the queue will support. If the argument is not set, the queue will not support message priorities<\/li>\n<li><code>x-queue-mode<\/code> \u2014 allows you to switch the queue to <strong>lazy mode<\/strong>. In this mode, as many messages as possible will be stored on disk. The use of RAM will be minimal. If it is not set, the queue will store messages in memory to deliver messages as quickly as possible<\/li>\n<li><code>x-queue-master-locator<\/code> \u2014 if we have a cluster, you can specify the master queue<\/li>\n<li><code>x-ha-policy<\/code> \u2014 used when creating HA queues and determines how a message will be distributed across nodes. If the value is set to <code>all<\/code>, the message will be stored on all nodes. If the value is set to <code>nodes<\/code>, the message will be stored on specific nodes of the cluster<\/li>\n<li><code>x-ha-nodes<\/code> \u2014 specifies the nodes to which a certain queue will belong <code>HA<\/code><\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Part 3. Understanding Queues and Bindings\" src=\"\/wp-content\/uploads\/2020\/03\/a8f660b6c0a43626e4025cf7769a4425.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>If queue creation <strong>is possible<\/strong>, the server will send an synchronous <code>RPC<\/code> response <code>Queue.DeclareOk<\/code>. If queue creation <strong>is not possible<\/strong> (the request was refused <code>Queue.Declare<\/code>), then <strong>the channel will be closed<\/strong> by the server using the command <code>Channel.Close<\/code> and the client will receive an exception <noindex><a rel=\"nofollow\" href=\"https:\/\/www.rabbitmq.com\/releases\/rabbitmq-dotnet-client\/v3.6.10\/rabbitmq-dotnet-client-3.6.10-client-htmldoc\/html\/type-RabbitMQ.Client.Exceptions.OperationInterruptedException.html\">OperationInterruptedException<\/a><\/noindex>, which will contain an error code and its description. <\/p>\n<p><\/p>\n<p><strong>Re-invocation<\/strong> <code>Queue.Declare<\/code> <strong>with similar parameters<\/strong> will return useful information about this queue. For example, the total number of messages waiting in this queue and the total number of consumers subscribed to it. <\/p>\n<p><\/p>\n<p>Call <code>Queue.Declare<\/code> under the user credentials that do not have the required rights assigned <strong>will close the channel<\/strong> using the command <code>Channel.Close<\/code> and the client will receive an exception <noindex><a rel=\"nofollow\" href=\"https:\/\/www.rabbitmq.com\/releases\/rabbitmq-dotnet-client\/v3.6.10\/rabbitmq-dotnet-client-3.6.10-client-htmldoc\/html\/type-RabbitMQ.Client.Exceptions.OperationInterruptedException.html\">OperationInterruptedException<\/a><\/noindex>, which will contain an error code <noindex><a rel=\"nofollow\" href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/HTTP\/Status\/403\">403<\/a><\/noindex> and its description.<\/p>\n<p><\/p>\n<p>After the queue remains idle for &gt;= 10 seconds, it <strong>enters sleep mode<\/strong>, invoking GC in the queue, which leads to a significant reduction in memory required for this queue.<\/p>\n<p><\/p>\n<h4 id=\"sozdanie-queue-cherez-graficheskiy-interfeys\"><em>Creating a Queue through the graphical interface<\/em><\/h4>\n<p><\/p>\n<p>Log into the admin panel <code>RabbitMQ<\/code> under the user <code>guest<\/code> (username: <code>guest<\/code> and password: <code>guest<\/code>). Note that the user <code>guest<\/code> can connect only from the local host. Now let's go to the <code>Queues<\/code> tab and click on <code>Add a new queue<\/code>. Fill in the properties:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Part 3. Understanding Queues and Bindings\" src=\"\/wp-content\/uploads\/2020\/03\/ea77a406ad16f0871c7197e96a66818f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Once we enter all required information and click on <code>Add queues<\/code>, the queue will appear in the main list.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Part 3. Understanding Queues and Bindings\" src=\"\/wp-content\/uploads\/2020\/03\/8342e044a0d6c0a035a2c9f646035cad.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Clicking on the queue name will show its detailed information. Here you can configure the binding between the exchange and the queue, view the list <code>consumers<\/code>, publish\/receive messages, delete the queue, and view statistics.<\/p>\n<p><\/p>\n<h4 id=\"sozdanie-binding\"><em>Creating a Binding<\/em><\/h4>\n<p><\/p>\n<p>Creating a binding occurs using synchronous <code>RPC<\/code> request to the server. The request is made using the method <code>Queue.Bind<\/code>, called with the parameters:<\/p>\n<p><\/p>\n<ul>\n<li>the name of the queue<\/li>\n<li>exchange point name<\/li>\n<li>other parameters<\/li>\n<\/ul>\n<p><\/p>\n<p>Example of creating a binding using <noindex><a rel=\"nofollow\" href=\"https:\/\/www.rabbitmq.com\/dotnet.html\">RabbitMQ.Client<\/a><\/noindex>:<\/p>\n<p><\/p>\n<pre><code class=\"cs\">\/\/...\nchannel.QueueBind(\n    queue: queueName,\n    exchange: &quot;my_exchange&quot;,\n    routingKey: &quot;my_key&quot;,\n    arguments: null\n);\n\/\/...<\/code><\/pre>\n<p><\/p>\n<ul>\n<li><code>queue<\/code> \u2014 queue name<\/li>\n<li><code>exchange<\/code> \u2014 exchange name<\/li>\n<li><code>routingKey<\/code> \u2014 routing key<\/li>\n<li><code>arguments<\/code> \u2014 optional arguments<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Part 3. Understanding Queues and Bindings\" src=\"\/wp-content\/uploads\/2020\/03\/9123186c94a822309b679f26c2e511ea.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>If creating a binding <strong>is possible<\/strong>, the server will send an synchronous <code>RPC<\/code> response <code>Queue.BindOk<\/code>.<\/p>\n<p><\/p>\n<h4 id=\"sozdanie-binding-cherez-graficheskiy-interfeys\"><em>Creating a Binding through the graphical interface<\/em><\/h4>\n<p><\/p>\n<p>Log into the admin panel <code>RabbitMQ<\/code> under the user <code>guest<\/code> (username: <code>guest<\/code> and password: <code>guest<\/code>). Note that the user <code>guest<\/code> can connect only from the local host. Now let's go to the <code>Queues<\/code> and click on the queue <code>my_queue<\/code>. Fill in the fields of the section <code>bindings<\/code>:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Part 3. Understanding Queues and Bindings\" src=\"\/wp-content\/uploads\/2020\/03\/7db6b42a4f29a1860aabe54ade0b6833.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Once we enter all required information and click on <code>Bind<\/code>, the binding will appear in the main list:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Part 3. Understanding Queues and Bindings\" src=\"\/wp-content\/uploads\/2020\/03\/499eda8e8cb061e6feb75c471eb64b92.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h3 id=\"code\">Code<\/h3>\n<p><\/p>\n<p>In this section, we will describe the queue and binding in C# code, as if we needed to develop a library. This may be useful for understanding.<\/p>\n<p><\/p>\n<pre><code class=\"cs\">public interface IQueue\n    {        \n        string Name { get; }\n\n        \/\/ &lt;summary&gt;\n        \/\/     If set to true, the queue will be persistent. \n        \/\/     It will be stored on disk and can \n        \/\/     survive a server\/broker restart. \n        \/\/     If false, the queue is temporary and will be deleted, \n        \/\/     when the server\/broker is restarted\n        \/\/ &lt;\/summary&gt;\n        bool IsDurable { get; }\n\n        \/\/ &lt;summary&gt;\n        \/\/     If set to true, \n        \/\/     such a queue will allow connection \n        \/\/     only to one consumer\n        \/\/ &lt;\/summary&gt;\n        bool IsExclusive { get; }\n\n        \/\/ &lt;summary&gt;\n        \/\/     Auto-delete. \n        \/\/     The queue will be deleted when all clients disconnect.\n        \/\/ &lt;\/summary&gt;\n        bool IsAutoDelete { get; }\n\n        \/\/ &lt;summary&gt;\n        \/\/     Optional arguments\n        \/\/ &lt;\/summary&gt;\n        IDictionary&lt;string, object&gt; Arguments { get; }\n    }<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"cs\">public class Queue : IQueue\n    {\n        public Queue(\n             string name, \n             bool isDurable = true, \n             bool isExclusive = false, \n             bool isAutoDelete = false, \n             IDictionary arguments = null)\n        {\n            Name = name ??\n                throw new ArgumentNullException(name, $\"{name} must not be null\");\n\n            IsDurable = isDurable;\n            IsExclusive = isExclusive;\n            IsAutoDelete = isAutoDelete;\n            Arguments = arguments ?? new Dictionary();\n        }\n\n        public string Name { get; }\n        public bool IsDurable { get; }\n        public bool IsExclusive { get; }\n        public bool IsAutoDelete { get; }\n        public IDictionary Arguments { get; }\n    }<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"cs\">public static class QueueMode\n    {       \n        public const string Default = \"default\";\n        \/\/ <summary>\n        \/\/     Lazy mode. The lazy mode will make\n        \/\/     as many messages as possible be saved\n        \/\/     to disk to reduce\n        \/\/     memory usage\n        \/\/ <\/summary>\n        public const string Lazy = \"lazy\";\n    }<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"cs\">public interface IBinding\n    {\n        \/\/ &lt;summary&gt;\n        \/\/     The exchange that will be bound by the binding\n        \/\/ &lt;\/summary&gt;\n        IExchange Exchange { get; }\n\n        \/\/ &lt;summary&gt;\n        \/\/     Routing key\n        \/\/ &lt;\/summary&gt;\n        string RoutingKey { get; }\n\n        \/\/ &lt;summary&gt;\n        \/\/     Optional arguments\n        \/\/ &lt;\/summary&gt;\n        IDictionary&lt;string, object&gt; Arguments { get; }\n    }<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"cs\">public class Binding : IBinding\n    {\n        public Binding(\n             IExchange exchange, \n             string routingKey, \n             IDictionary&lt;string, object&gt; arguments)\n        {\n            Exchange = exchange;\n            RoutingKey = routingKey;\n            Arguments = arguments;\n        }\n\n        public IExchange Exchange { get; }\n        public string RoutingKey { get; }\n        public IDictionary&lt;string, object&gt; Arguments { get; }\n    }<\/code><\/pre>\n<p>Source: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/490960\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>Queue (\u043e\u0447\u0435\u0440\u0435\u0434\u044c) \u2014 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435 \u0438\u043b\u0438 \u0432 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u043e\u0442\u0434\u0430\u0435\u0442 \u0438\u0445 \u043a\u043e\u043f\u0438\u0438 consumers (\u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f\u043c). Queue \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 Erlang-\u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c (\u0433\u0434\u0435 \u043c\u043e\u0433\u0443\u0442 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u0441\u0430\u043c\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f). 1 \u0442\u044b\u0441\u044f\u0447\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u043e\u0440\u044f\u0434\u043a\u0430 80Mb. Binding (\u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430) \u2014 \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442 \u043e\u0431\u043c\u0435\u043d\u043d\u0438\u043a\u0443 \u0432 \u043a\u0430\u043a\u0443\u044e \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u043f\u0430\u0434\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f. [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":73066,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-73065","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"Queue (\u043e\u0447\u0435\u0440\u0435\u0434\u044c) \u2014 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435 \u0438\u043b\u0438 \u0432 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u043e\u0442\u0434\u0430\u0435\u0442 \u0438\u0445 \u043a\u043e\u043f\u0438\u0438 consumers (\u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f\u043c).\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47RabbitMQ. \u0427\u0430\u0441\u0442\u044c 3. \u0420\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u0441 Queues \u0438 Bindings | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"Queue (\u043e\u0447\u0435\u0440\u0435\u0434\u044c) \u2014 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435 \u0438\u043b\u0438 \u0432 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u043e\u0442\u0434\u0430\u0435\u0442 \u0438\u0445 \u043a\u043e\u043f\u0438\u0438 consumers (\u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f\u043c).\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-03-06T17:42:13+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-03-06T17:42:13+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47RabbitMQ. Part 3. Understanding Queues and Bindings | ProHoster","description":"Queue \u2014 a data structure on disk or in RAM that stores references to messages and delivers their copies to consumers.","canonical_url":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"en_US","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47RabbitMQ. \u0427\u0430\u0441\u0442\u044c 3. \u0420\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u0441 Queues \u0438 Bindings | ProHoster","og:description":"Queue (\u043e\u0447\u0435\u0440\u0435\u0434\u044c) \u2014 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435 \u0438\u043b\u0438 \u0432 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u043e\u0442\u0434\u0430\u0435\u0442 \u0438\u0445 \u043a\u043e\u043f\u0438\u0438 consumers (\u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f\u043c).","og:url":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-03-06T17:42:13+00:00","article:modified_time":"2020-03-06T17:42:13+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"73065","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 18:41:06","updated":"2022-09-30 05:07:23","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts\/73065","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/comments?post=73065"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts\/73065\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/media\/73066"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/media?parent=73065"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/categories?post=73065"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/tags?post=73065"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}