{"id":488251,"date":"2026-07-23T05:55:42","date_gmt":"2026-07-23T05:55:42","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=488251"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=488251","title":{"rendered":"\u041d\u0430\u0434\u0451\u0436\u043d\u0430\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u043a\u043e\u043c\u043c\u0443\u043d\u0438\u043a\u0430\u0446\u0438\u044f: \u043f\u043e\u0432\u0442\u043e\u0440\u044b, \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u044b \u0438 dead letter queues"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c \u043e\u0431\u044b\u0447\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0437\u0430\u043a\u0430\u0437\u0430. \u0421\u0435\u0440\u0432\u0438\u0441 \u0437\u0430\u043a\u0430\u0437\u043e\u0432 \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <code>order.created<\/code>. \u0421\u0435\u0440\u0432\u0438\u0441 \u0441\u043a\u043b\u0430\u0434\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0435\u0433\u043e \u0438 \u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u0443\u0435\u0442 \u0442\u043e\u0432\u0430\u0440 \u0432 PostgreSQL. \u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c RabbitMQ \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 (<code>Ack<\/code>), \u0447\u0442\u043e\u0431\u044b broker \u0443\u0434\u0430\u043b\u0438\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438\u0437 queue.<\/p>\n<p>\u041d\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043c\u043e\u0436\u0435\u0442 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 PostgreSQL \u0438 \u0434\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 <code>Ack<\/code>. RabbitMQ \u043d\u0435 \u0437\u043d\u0430\u0435\u0442, \u0443\u0441\u043f\u0435\u043b \u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441 \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0432\u0430\u0440. Broker \u0432\u0438\u0434\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0451\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0433\u043e \u0435\u0449\u0451 \u0440\u0430\u0437. \u0421 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u044d\u0442\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435. \u0421 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0431\u0438\u0437\u043d\u0435\u0441\u0430 \u043e\u0434\u0438\u043d \u0437\u0430\u043a\u0430\u0437 \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0432\u0430\u0440 \u0434\u0432\u0430\u0436\u0434\u044b.<\/p>\n<p>\u0414\u0440\u0443\u0433\u043e\u0439 \u0441\u0431\u043e\u0439 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0440\u0430\u043d\u044c\u0448\u0435: PostgreSQL \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d, \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u0447\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443. \u0415\u0441\u043b\u0438 \u0441\u0440\u0430\u0437\u0443 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 queue \u0447\u0435\u0440\u0435\u0437 \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 <code>Nack(requeue=true)<\/code>, RabbitMQ \u043f\u043e\u0447\u0442\u0438 \u043d\u0435\u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442 \u0435\u0433\u043e \u0441\u043d\u043e\u0432\u0430. \u041f\u043e\u043a\u0430 \u0431\u0430\u0437\u0430 \u043d\u0435 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0430\u0441\u044c, \u0432\u0441\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c\u0438. \u041d\u0443\u0436\u043d\u044b \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0447\u0438\u0441\u043b\u0430 \u043f\u043e\u0432\u0442\u043e\u0440\u043e\u0432. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u043f\u0435\u0440\u0451\u0434 \u0431\u043e\u043b\u0435\u0435 \u043d\u043e\u0432\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0440\u0435\u0448\u0438\u0442\u044c \u0432\u043e\u043f\u0440\u043e\u0441 \u043f\u043e\u0440\u044f\u0434\u043a\u0430.<\/p>\n<p>\u0422\u0430\u043a \u043e\u0434\u043d\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 \u0443\u0447\u0430\u0441\u0442\u043a\u043e\u0432: \u0437\u0430\u043f\u0438\u0441\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f, \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0432 broker, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435. \u041c\u0435\u0436\u0434\u0443 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u043c\u0438 \u0443\u0447\u0430\u0441\u0442\u043a\u0430\u043c\u0438 \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u043c\u043e\u043c\u0435\u043d\u0442\u044b, \u043a\u043e\u0433\u0434\u0430 \u043e\u0434\u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0430 \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u0430 \u0434\u0440\u0443\u0433\u0430\u044f \u0435\u0449\u0451 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u044d\u0442\u0438 \u043c\u043e\u043c\u0435\u043d\u0442\u044b \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u043f\u0443\u0442\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f. \u0417\u0430\u0442\u0435\u043c \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043c \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0441\u0445\u0435\u043c\u0443 \u0434\u043b\u044f RabbitMQ \u0438 Go: \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u044b \u0447\u0435\u0440\u0435\u0437 retry queues, \u0432\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f (<code>TTL<\/code>) \u0438 dead letter exchange, \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u044b\u043c \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c, \u043a\u0443\u0434\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438. \u0412 \u043a\u043e\u043d\u0446\u0435 \u0441\u0440\u0430\u0432\u043d\u0438\u043c \u044d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434 \u0441 Kafka, NATS JetStream \u0438 Amazon SQS.<\/p>\n<p><strong>\u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u0432\u044b\u0432\u043e\u0434:<\/strong> \u043d\u0430\u0434\u0451\u0436\u043d\u043e\u0441\u0442\u044c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u043a\u043e\u043c\u043c\u0443\u043d\u0438\u043a\u0430\u0446\u0438\u0438 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043d\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u043e\u0432, \u0430 \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0441\u0431\u043e\u0435. Producer \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0442\u0435\u0440\u044f\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u0435, \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c \u0431\u0438\u0437\u043d\u0435\u0441-\u044d\u0444\u0444\u0435\u043a\u0442, \u0430 retry \u0432\u0441\u0435\u0433\u0434\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u043c\u0435\u0442\u044c \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443, \u043f\u0440\u0435\u0434\u0435\u043b \u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442.<\/p>\n<h2>\u0413\u0434\u0435 \u043b\u043e\u043c\u0430\u0435\u0442\u0441\u044f \u043f\u0443\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<\/h2>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0443\u0442\u044c <code>order.created<\/code>:<\/p>\n<pre><code>orders DB -&gt; outbox -&gt; publisher -&gt; exchange -&gt; queue -&gt; consumer -&gt; inventory DB                              |                    |                         confirm\/return          Ack\/Nack<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u043f\u0443\u0442\u0438 \u043d\u0435\u0442 \u043e\u0434\u043d\u043e\u0433\u043e \u043e\u0431\u0449\u0435\u0433\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f. \u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0444\u0430\u043a\u0442\u043e\u0432:<\/p>\n<ol>\n<li>\n<p>PostgreSQL \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u043b \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e \u0437\u0430\u043a\u0430\u0437\u0430.<\/p>\n<\/li>\n<li>\n<p>RabbitMQ \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u043b, \u0447\u0442\u043e \u043f\u0440\u0438\u043d\u044f\u043b \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044e.<\/p>\n<\/li>\n<li>\n<p>Exchange \u043d\u0430\u0448\u0451\u043b \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0443\u044e queue.<\/p>\n<\/li>\n<li>\n<p>Consumer \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u043b \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0443 \u0447\u0435\u0440\u0435\u0437 <code>Ack<\/code>.<\/p>\n<\/li>\n<li>\n<p>PostgreSQL \u0441\u043a\u043b\u0430\u0434\u0430 \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043b \u0440\u0435\u0437\u0435\u0440\u0432.<\/p>\n<\/li>\n<\/ol>\n<p>\u0421\u0431\u043e\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u0435\u043d \u043c\u0435\u0436\u0434\u0443 \u043b\u044e\u0431\u044b\u043c\u0438 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u043c\u0438 \u043f\u0443\u043d\u043a\u0442\u0430\u043c\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u043b\u0435\u0437\u043d\u0435\u0435 \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043d\u0435 \u00ab\u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u043b\u0438 RabbitMQ \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0443\u00bb, \u0430 \u00ab\u043a\u0442\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u0432\u043b\u0430\u0434\u0435\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c \u0438 \u043a\u0430\u043a\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c\u00bb.<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041a\u0430\u043a \u043f\u0440\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0427\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Dual write<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0417\u0430\u043a\u0430\u0437 \u0437\u0430\u043f\u0438\u0441\u0430\u043d, \u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043d\u0435 \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u043e, \u0438\u043b\u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442<\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"https:\/\/ubiklab.net\/posts\/pattern-transactional-outbox\/\" rel=\"noopener noreferrer nofollow\">Transactional Outbox<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041d\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">Broker \u043f\u0440\u0438\u043d\u044f\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043d\u043e confirm \u043f\u043e\u0442\u0435\u0440\u044f\u043b\u0441\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u0432\u0442\u043e\u0440 \u0441 \u0442\u0435\u043c \u0436\u0435 <code>message_id<\/code>, \u0438\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u044b\u0439 consumer<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">Consumer \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0438 \u0443\u043f\u0430\u043b \u0434\u043e <code>Ack<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Inbox \u0438\u043b\u0438 \u0438\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u0430\u044f \u0431\u0438\u0437\u043d\u0435\u0441-\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0413\u043e\u0440\u044f\u0447\u0438\u0439 \u0446\u0438\u043a\u043b \u043f\u043e\u0432\u0442\u043e\u0440\u043e\u0432<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0435\u0438\u0441\u043f\u0440\u0430\u0432\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 queue<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0417\u0430\u0434\u0435\u0440\u0436\u043a\u0430, backoff, \u043b\u0438\u043c\u0438\u0442 \u043f\u043e\u043f\u044b\u0442\u043e\u043a<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Poison message<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u0432\u0442\u043e\u0440 \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442: JSON \u043f\u043e\u0432\u0440\u0435\u0436\u0434\u0451\u043d \u0438\u043b\u0438 \u0441\u0445\u0435\u043c\u0430 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">Parking lot, \u0438\u043b\u0438 dead letter queue (DLQ), \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430 \u0438 \u0440\u0443\u0447\u043d\u043e\u0439 redrive &#8212; \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u043f\u043e\u0441\u043b\u0435 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u0435 \u043f\u043e\u0440\u044f\u0434\u043a\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0411\u043e\u043b\u0435\u0435 \u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043e \u0440\u0430\u043d\u044c\u0448\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u043c\u043e\u0433\u043e \u0441\u0442\u0430\u0440\u043e\u0433\u043e<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0430\u0440\u0442\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e \u043a\u043b\u044e\u0447\u0443, \u0432\u0435\u0440\u0441\u0438\u044f \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430, \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u043a\u0430 consumer<\/p>\n<\/td>\n<td>\n<p align=\"left\">Queue \u0438 \u0432\u043e\u0437\u0440\u0430\u0441\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0440\u0430\u0441\u0442\u0443\u0442 \u0431\u044b\u0441\u0442\u0440\u0435\u0435, \u0447\u0435\u043c \u0441\u0435\u0440\u0432\u0438\u0441 \u0443\u0441\u043f\u0435\u0432\u0430\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c<\/p>\n<\/td>\n<td>\n<p align=\"left\">Prefetch, \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0446\u0438\u0438, backpressure, \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041d\u0435\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u0442\u0430\u0440\u044b\u0439 consumer \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u0435 \u0438\u043b\u0438 \u0441\u043c\u044b\u0441\u043b \u0441\u043e\u0431\u044b\u0442\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u0435\u0440\u0441\u0438\u044f \u0441\u0445\u0435\u043c\u044b, \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u0430\u044f \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u043e\u0442\u0435\u0440\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0435\u043b\u044c\u0437\u044f \u0441\u0432\u044f\u0437\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c \u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u043c\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0430\u043c\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0439 ID, correlation ID, trace context, \u043c\u0435\u0442\u0440\u0438\u043a\u0438<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041e\u0434\u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 broker \u043d\u0435 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0432\u0441\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, quorum queue \u0437\u0430\u0449\u0438\u0449\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 RabbitMQ, \u043d\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 \u043e \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 PostgreSQL \u0432\u043d\u0443\u0442\u0440\u0438 consumer.<\/p>\n<h2>At most once, at least once \u0438 exactly once<\/h2>\n<p>\u0423 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0435\u0441\u0442\u044c \u0442\u0440\u0438 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f.<\/p>\n<p><strong>At most once<\/strong>, \u0438\u043b\u0438 \u043d\u0435 \u0431\u043e\u043b\u0435\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u0430. Consumer \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043b\u0438\u0431\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c <code>Ack<\/code>. \u041f\u043e\u0432\u0442\u043e\u0440\u043e\u0432 \u043d\u0435\u0442, \u043d\u043e \u043f\u0440\u0438 \u043f\u0430\u0434\u0435\u043d\u0438\u0438 consumer \u0440\u0430\u0431\u043e\u0442\u0430 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0435\u0440\u044f\u0442\u044c\u0441\u044f.<\/p>\n<p><strong>At least once<\/strong>, \u0438\u043b\u0438 \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u043e\u0434\u0438\u043d \u0440\u0430\u0437. Consumer \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 <code>Ack<\/code>. \u0420\u0430\u0431\u043e\u0442\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u043f\u043e\u0442\u0435\u0440\u044f\u0442\u044c\u0441\u044f, \u0437\u0430\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0439\u0442\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e.<\/p>\n<p><strong>Exactly once<\/strong>, \u0438\u043b\u0438 \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437. \u0422\u0435\u0440\u043c\u0438\u043d \u043f\u043e\u043b\u0435\u0437\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0433\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0438. Kafka \u0443\u043c\u0435\u0435\u0442 \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438 consumer offset \u0432 Kafka-\u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0447\u0438\u0442\u0430\u0435\u0442 \u0438\u0437 Kafka \u0438 \u043f\u0438\u0448\u0435\u0442 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 Kafka. \u041d\u043e \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u0443\u044e \u0431\u0430\u0437\u0443 \u0438\u043b\u0438 \u0432\u044b\u0437\u043e\u0432 \u043f\u043b\u0430\u0442\u0451\u0436\u043d\u043e\u0433\u043e API \u0441\u043d\u043e\u0432\u0430 \u0441\u043e\u0437\u0434\u0430\u044e\u0442 \u0432\u043d\u0435\u0448\u043d\u044e\u044e \u0433\u0440\u0430\u043d\u0438\u0446\u0443. \u042d\u0442\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u044f\u043c\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0432 <a href=\"https:\/\/kafka.apache.org\/43\/design\/design\/#message-delivery-semantics\" rel=\"noopener noreferrer nofollow\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 Kafka \u043e delivery semantics<\/a>.<\/p>\n<p>RabbitMQ \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442 publisher confirms \u0438 consumer acknowledgements \u0441 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435\u0439 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0437\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435. \u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430\u0434\u0451\u0436\u043d\u043e\u0441\u0442\u044c <a href=\"https:\/\/www.rabbitmq.com\/docs\/reliability\" rel=\"noopener noreferrer nofollow\">\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e\u0439 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e broker, producer \u0438 consumer<\/a>. \u042d\u0442\u0438 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u043d\u0435 \u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u0443\u044e \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e \u0441 \u0431\u0430\u0437\u043e\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0440\u0430\u0431\u043e\u0447\u0430\u044f \u0446\u0435\u043b\u044c \u0437\u0432\u0443\u0447\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code>at least once delivery + idempotent business effect<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437, \u043d\u043e \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u044b\u0439 \u0431\u0438\u0437\u043d\u0435\u0441-\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f \u043e\u0434\u0438\u043d \u0440\u0430\u0437. \u0412\u0430\u0436\u043d\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435. \u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0441 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u043c\u0438 ID \u043d\u0435 \u043f\u043e\u043c\u043e\u0436\u0435\u0442, \u0435\u0441\u043b\u0438 consumer \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u0432\u0430\u0436\u0434\u044b \u0432\u044b\u0437\u043e\u0432\u0435\u0442 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 API, \u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443.<\/p>\n<h2>\u041f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 dual write<\/h2>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0441\u0435\u0440\u0432\u0438\u0441 \u0437\u0430\u043a\u0430\u0437\u043e\u0432 \u0434\u0435\u043b\u0430\u0435\u0442 \u0434\u0432\u0435 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438:<\/p>\n<pre><code class=\"go\">if err := orders.Insert(ctx, order); err != nil {return err}if err := publisher.Publish(ctx, orderCreated); err != nil {return err}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041c\u0435\u0436\u0434\u0443 \u0432\u044b\u0437\u043e\u0432\u0430\u043c\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043c\u043e\u0436\u0435\u0442 \u0443\u043f\u0430\u0441\u0442\u044c. \u041f\u0435\u0440\u0435\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0441\u0442\u0440\u043e\u043a \u043d\u0435 \u0440\u0435\u0448\u0430\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443: \u0442\u043e\u0433\u0434\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e \u0443\u0439\u0442\u0438 \u0434\u043e \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u043a\u0430\u0437\u0430.<\/p>\n<p><a href=\"https:\/\/ubiklab.net\/posts\/pattern-transactional-outbox\/\" rel=\"noopener noreferrer nofollow\">Transactional Outbox<\/a> \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0432 \u0442\u0443 \u0436\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e, \u0433\u0434\u0435 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u0437\u0430\u043a\u0430\u0437:<\/p>\n<pre><code class=\"sql\">BEGIN;INSERT INTO orders (id, status)VALUES ('42', 'created');INSERT INTO outbox (id, event_type, payload, created_at)VALUES (    '01K0ORDERCREATED',    'order.created',    '{\"order_id\":\"42\"}',    now());COMMIT;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 relay \u0447\u0438\u0442\u0430\u0435\u0442 <code>outbox<\/code>, \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0438 \u043f\u043e\u0441\u043b\u0435 publisher confirm \u043e\u0442\u043c\u0435\u0447\u0430\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439. \u0415\u0441\u043b\u0438 relay \u0443\u043f\u0430\u0434\u0451\u0442 \u043f\u043e\u0441\u043b\u0435 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438, \u043d\u043e \u0434\u043e \u043e\u0442\u043c\u0435\u0442\u043a\u0438 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435, \u043e\u043d \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 ID \u0441\u043e\u0437\u0434\u0430\u044e\u0442 \u043f\u0440\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 <code>outbox<\/code> \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442 \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u043f\u043e\u0432\u0442\u043e\u0440\u0435. \u041d\u043e\u0432\u044b\u0439 ID \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b \u0431\u044b \u0442\u043e\u0442 \u0436\u0435 \u0444\u0430\u043a\u0442 \u0432 \u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0438 \u0441\u0434\u0435\u043b\u0430\u043b \u0434\u0435\u0434\u0443\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u044e \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0439.<\/p>\n<p>Publisher confirm \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442, \u0447\u0442\u043e RabbitMQ \u043f\u0440\u0438\u043d\u044f\u043b \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0437\u0430 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044e. \u0414\u043b\u044f persistent-\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043f\u043e\u043f\u0430\u0432\u0448\u0435\u0433\u043e \u0432 durable queue, \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435. Quorum queue \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044e \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u043d\u044f\u043b\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0440\u0435\u043f\u043b\u0438\u043a. \u0415\u0441\u043b\u0438 exchange \u043d\u0430\u043f\u0440\u0430\u0432\u0438\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e queues, confirm \u043f\u0440\u0438\u0434\u0451\u0442 \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0435\u0433\u043e \u043f\u0440\u0438\u043c\u0443\u0442 \u0432\u0441\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 queues. \u041d\u043e \u043f\u043e\u0442\u0435\u0440\u044f\u043d\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 \u0441\u043d\u043e\u0432\u0430 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 producer \u0432 \u043d\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0441\u0442\u0438: broker \u043c\u043e\u0433 \u043f\u0440\u0438\u043d\u044f\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u0430 confirm \u043c\u043e\u0433 \u043d\u0435 \u0434\u043e\u0439\u0442\u0438. RabbitMQ \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442 <a href=\"https:\/\/www.rabbitmq.com\/docs\/reliability#data-safety-on-the-publisher-side\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0451\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<\/a> \u0438 \u0431\u044b\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u043c \u043a \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u0430\u043c.<\/p>\n<p>\u0415\u0441\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u043d\u0430 \u0434\u0435\u0442\u0430\u043b\u044c. Confirm \u043d\u0435 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e exchange \u043d\u0430\u0448\u0451\u043b queue. \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0431\u0435\u0437 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430, \u0438\u043b\u0438 unroutable message, RabbitMQ \u0442\u043e\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c. \u0414\u043b\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 producer \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u0442 \u0441 <code>mandatory=true<\/code> \u0438 \u0447\u0438\u0442\u0430\u0435\u0442 <code>basic.return<\/code>. \u0415\u0441\u043b\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u0447\u0438\u043a\u043e\u0432 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e \u043f\u043e \u0441\u043c\u044b\u0441\u043b\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u043f\u043e\u0442\u0435\u0440\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u043e\u0439.<\/p>\n<h2>\u041a\u043e\u0433\u0434\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c Ack<\/h2>\n<p>Consumer \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c <code>Ack<\/code> \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441\u0442\u0430\u043b\u043e \u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u043c \u043a \u043f\u0430\u0434\u0435\u043d\u0438\u044e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430. \u0414\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 PostgreSQL \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u0439 <code>COMMIT<\/code>.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0447\u0435\u0442\u044b\u0440\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041c\u043e\u043c\u0435\u043d\u0442 \u043f\u0430\u0434\u0435\u043d\u0438\u044f<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0427\u0442\u043e \u0443\u0432\u0438\u0434\u0438\u0442 RabbitMQ<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0427\u0442\u043e \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u0434\u0435\u043b\u0430\u0442\u044c consumer \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0414\u043e \u043d\u0430\u0447\u0430\u043b\u0430 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>Ack<\/code> \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d, \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432\u0435\u0440\u043d\u0451\u0442\u0441\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0422\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u043e\u0442\u043a\u0430\u0442\u0438\u0442\u0441\u044f, \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432\u0435\u0440\u043d\u0451\u0442\u0441\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u043e\u0441\u043b\u0435 <code>COMMIT<\/code>, \u0434\u043e <code>Ack<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432\u0435\u0440\u043d\u0451\u0442\u0441\u044f, \u0445\u043e\u0442\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0443\u0436\u0435 \u0437\u0430\u043f\u0438\u0441\u0430\u043d<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0420\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0442\u044c \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442 \u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043c\u0435\u043d\u044f\u0442\u044c<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u043e\u0441\u043b\u0435 <code>Ack<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">RabbitMQ \u0443\u0434\u0430\u043b\u0438\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0443\u0436\u0435 \u043e\u0431\u044f\u0437\u0430\u043d \u0431\u044b\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 <code>Ack<\/code> \u0441\u0434\u0432\u0438\u0433\u0430\u0435\u0442 \u0433\u0440\u0430\u043d\u0438\u0446\u0443 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0440\u0430\u043d\u043e. <code>Ack<\/code> \u0434\u043e <code>COMMIT<\/code> \u0434\u0435\u043b\u0430\u0435\u0442 \u043e\u043a\u043d\u043e \u043f\u043e\u0442\u0435\u0440\u0438. <code>Ack<\/code> \u043f\u043e\u0441\u043b\u0435 <code>COMMIT<\/code> \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u043a\u043d\u043e \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u0442\u044c \u0438\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c\u044e.<\/p>\n<p>\u0424\u043b\u0430\u0433 <code>Redelivered<\/code> \u043f\u043e\u043b\u0435\u0437\u0435\u043d \u0434\u043b\u044f \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0438, \u043d\u043e \u043d\u0435 \u0434\u043b\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u0438. \u041e\u043d \u0433\u043e\u0432\u043e\u0440\u0438\u0442, \u0447\u0442\u043e RabbitMQ \u0443\u0436\u0435 \u043f\u044b\u0442\u0430\u043b\u0441\u044f \u0432\u044b\u0434\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u0430 \u043d\u0435 \u0447\u0442\u043e \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 consumer \u0443\u0441\u043f\u0435\u043b \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435. Consumer \u043c\u043e\u0436\u0435\u0442 \u0432\u043f\u0435\u0440\u0432\u044b\u0435 \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 <code>Redelivered=true<\/code>, \u0435\u0441\u043b\u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0430 \u043d\u0435 \u0434\u043e\u0448\u043b\u0430 \u0434\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0434 \u0440\u0430\u0437\u0440\u044b\u0432\u043e\u043c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f. <a href=\"https:\/\/www.rabbitmq.com\/docs\/reliability#data-safety-on-the-consumer-side\" rel=\"noopener noreferrer nofollow\">RabbitMQ \u043f\u0440\u044f\u043c\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u044d\u0442\u043e\u0442 \u0444\u043b\u0430\u0433 \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u043e\u0439<\/a>, \u0430 \u043d\u0435 \u0434\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b.<\/p>\n<h2>\u0418\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u044b\u0439 consumer \u0447\u0435\u0440\u0435\u0437 Inbox<\/h2>\n<p>\u0418\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u0430\u0451\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u0438 \u043e\u0434\u043d\u043e\u043c \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u0430\u0445. \u041f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u043d\u0438\u0435 <code>status = 'paid'<\/code> \u0447\u0430\u0441\u0442\u043e \u0438\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u043e. \u041a\u043e\u043c\u0430\u043d\u0434\u0430 <code>balance = balance - 100<\/code> \u0438\u043b\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u043f\u0438\u0441\u044c\u043c\u0430 &#8212; \u043d\u0435\u0442.<\/p>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0443\u0434\u043e\u0431\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Inbox. Consumer \u0445\u0440\u0430\u043d\u0438\u0442 ID \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0432 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0431\u0430\u0437\u0435. \u0423\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0432\u0445\u043e\u0434\u044f\u0442 \u0432 \u043e\u0434\u043d\u0443 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e:<\/p>\n<pre><code class=\"sql\">CREATE TABLE processed_messages (    consumer_name text        NOT NULL,    message_id    text        NOT NULL,    processed_at  timestamptz NOT NULL DEFAULT now(),    PRIMARY KEY (consumer_name, message_id));<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0438\u0436\u0435 \u0443\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u043e\u0432\u0430\u0440\u0430. \u0415\u0441\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0443\u0436\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043e \u044d\u0442\u0438\u043c consumer, <code>INSERT ... ON CONFLICT<\/code> \u043d\u0435 \u0432\u0435\u0440\u043d\u0451\u0442 \u0441\u0442\u0440\u043e\u043a\u0443 \u0438 \u043f\u043e\u0432\u0442\u043e\u0440 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f \u0431\u0435\u0437 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0440\u0435\u0437\u0435\u0440\u0432\u0430.<\/p>\n<pre><code class=\"go\">type OrderCreated struct {OrderID string `json:\"order_id\"`SKU     string `json:\"sku\"`Count   int    `json:\"count\"`}func reserve(ctx context.Context,db *sql.DB,messageID string,event OrderCreated,) error {tx, err := db.BeginTx(ctx, nil)if err != nil {return fmt.Errorf(\"begin transaction: %w\", err)}defer func() {\/\/ \u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e Commit \u0432\u0435\u0440\u043d\u0451\u0442\u0441\u044f sql.ErrTxDone._ = tx.Rollback()}()var inserted interr = tx.QueryRowContext(ctx, `INSERT INTO processed_messages (consumer_name, message_id)VALUES ('inventory.reserve', $1)ON CONFLICT DO NOTHINGRETURNING 1`, messageID).Scan(&amp;inserted)switch {case errors.Is(err, sql.ErrNoRows):return nil \/\/ \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0443\u0436\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043b\u0438, defer \u0437\u0430\u043a\u0440\u043e\u0435\u0442 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044ecase err != nil:return fmt.Errorf(\"claim message: %w\", err)}result, err := tx.ExecContext(ctx, `UPDATE stockSET reserved = reserved + $1WHERE sku = $2  AND available - reserved &gt;= $1`, event.Count, event.SKU)if err != nil {return fmt.Errorf(\"reserve stock: %w\", err)}rows, err := result.RowsAffected()if err != nil {return fmt.Errorf(\"read affected rows: %w\", err)}if rows == 0 {\/\/ \u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0442\u043e\u0432\u0430\u0440\u0430 - \u0431\u0438\u0437\u043d\u0435\u0441-\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u0430 \u043d\u0435 \u0441\u0431\u043e\u0439 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.\/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0432 \u0442\u043e\u0439 \u0436\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438._, err := tx.ExecContext(ctx, `INSERT INTO inventory_outbox (id, event_type, payload)VALUES ($1,'inventory.reservation_rejected',jsonb_build_object('order_id', $2, 'sku', $3))ON CONFLICT DO NOTHING`, messageID+\":reservation-rejected\", event.OrderID, event.SKU)if err != nil {return fmt.Errorf(\"save reservation rejection: %w\", err)}}if err := tx.Commit(); err != nil {return fmt.Errorf(\"commit reservation: %w\", err)}return nil}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0440\u044f\u0434\u043e\u043a \u0432\u0430\u0436\u0435\u043d: \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 ID \u0438 \u0440\u0435\u0437\u0435\u0440\u0432 \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043e\u0434\u043d\u0438\u043c <code>COMMIT<\/code>. \u0415\u0441\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0432\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438, \u043f\u0430\u0434\u0435\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u043b\u0438\u0431\u043e \u043f\u043e\u0442\u0435\u0440\u044f\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443, \u043b\u0438\u0431\u043e \u0441\u043d\u043e\u0432\u0430 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u0442 \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442. \u041e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0439 <code>Rollback<\/code> \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u0435\u043d \u0438 \u043f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e <code>Commit<\/code>: \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u0430\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u0432\u0435\u0440\u043d\u0451\u0442 <code>sql.ErrTxDone<\/code>, \u0430 \u043a\u043e\u0434 \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u043d\u043e \u043f\u0440\u043e\u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442 \u044d\u0442\u0443 \u043e\u0448\u0438\u0431\u043a\u0443.<\/p>\n<p>\u041e\u0448\u0438\u0431\u043a\u0443 <code>Commit<\/code> \u043d\u0435\u043b\u044c\u0437\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0430\u0437\u0432\u0430\u0442\u044c \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439. \u041e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u0440\u0438 \u043e\u0431\u0440\u044b\u0432\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u043d\u043e\u0433\u0434\u0430 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, PostgreSQL \u0443\u0441\u043f\u0435\u043b \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e, \u0430 \u043e\u0442\u0432\u0435\u0442 \u043d\u0435 \u0434\u043e\u0448\u0451\u043b \u0434\u043e consumer. \u0412 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u0442\u0430\u043a\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u043e\u0439\u0434\u0451\u0442 \u043f\u043e \u0432\u0435\u0442\u043a\u0435 retry. RabbitMQ \u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0435\u0449\u0451 \u0440\u0430\u0437, \u0430 \u0437\u0430\u043f\u0438\u0441\u044c \u0432 Inbox \u043d\u0435 \u0434\u0430\u0441\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u0443\u0436\u0435 \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435.<\/p>\n<p>Inbox \u0440\u0430\u0441\u0442\u0451\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u043d\u0443\u0436\u043d\u0430 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f. \u0423\u0434\u0430\u043b\u044f\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0438 \u043c\u043e\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u0440\u043e\u043a\u0430, \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u0442\u0430\u0440\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u0438\u0437 broker, \u0430\u0440\u0445\u0438\u0432\u0430 \u0438\u043b\u0438 \u0440\u0443\u0447\u043d\u043e\u0433\u043e redrive. \u0415\u0441\u043b\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043e \u043f\u0435\u0440\u0435\u0438\u0433\u0440\u044b\u0432\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0433\u043e\u0434, \u043e\u0447\u0438\u0441\u0442\u043a\u0430 Inbox \u0447\u0435\u0440\u0435\u0437 \u043d\u0435\u0434\u0435\u043b\u044e \u0432\u0435\u0440\u043d\u0451\u0442 \u043f\u043e\u0431\u043e\u0447\u043d\u044b\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u044b \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 replay.<\/p>\n<p>\u0412\u0435\u0442\u043a\u0430 \u0441 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u0442\u043e\u0432\u0430\u0440\u043e\u043c \u0437\u0430\u043e\u0434\u043d\u043e \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e consumer \u0447\u0430\u0441\u0442\u043e \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f producer. \u0417\u0430\u043f\u0438\u0441\u044c \u0432 <code>inventory_outbox<\/code> \u0432\u0445\u043e\u0434\u0438\u0442 \u0432 \u0442\u0443 \u0436\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e, \u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 relay \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u0442 <code>inventory.reservation_rejected<\/code>. \u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0438\u043c\u0435\u0442\u044c \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 <code>id<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0432\u0442\u043e\u0440 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u0434\u0432\u0430 \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0445.<\/p>\n<p>\u0414\u043b\u044f \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e HTTP API \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u043e\u0441\u0442\u044c. \u041f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0439\u0442\u0435 <code>message_id<\/code> \u043a\u0430\u043a idempotency key, \u0435\u0441\u043b\u0438 API \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442. \u0415\u0441\u043b\u0438 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0439\u0442\u0435 \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u0438\u0435 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0439\u0442\u0435 \u0432\u044b\u0437\u043e\u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u043c \u043b\u0438\u0431\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u0443\u0439\u0442\u0435 \u043a\u043e\u043c\u043f\u0435\u043d\u0441\u0438\u0440\u0443\u044e\u0449\u0443\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e. \u0412\u043e\u043b\u0448\u0435\u0431\u043d\u043e\u0433\u043e <code>Ack<\/code> \u0434\u043b\u044f \u0447\u0443\u0436\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0437\u0434\u0435\u0441\u044c \u043d\u0435 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f.<\/p>\n<h2>\u041a\u0430\u043a\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c<\/h2>\n<p>\u041d\u0435 \u043a\u0430\u0436\u0434\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0430. Retry policy \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u0430 \u043d\u0435 \u0441 \u0444\u043e\u0440\u043c\u0443\u043b\u044b backoff.<\/p>\n<p><strong>\u0412\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430:<\/strong> connection reset, \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430\u044f \u0431\u0430\u0437\u0430, <code>429 Too Many Requests<\/code>, deadlock \u0438\u043b\u0438 \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 timeout. \u041f\u043e\u0432\u0442\u043e\u0440 \u043c\u043e\u0436\u0435\u0442 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u043a\u043e\u0434\u0430.<\/p>\n<p><strong>\u041f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430:<\/strong> \u043f\u043e\u0432\u0440\u0435\u0436\u0434\u0451\u043d\u043d\u044b\u0439 JSON, \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0441\u0445\u0435\u043c\u044b, \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u043b\u0435, \u0437\u0430\u043f\u0440\u0435\u0449\u0451\u043d\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. \u041f\u043e\u0432\u0442\u043e\u0440 \u0442\u0435\u0445 \u0436\u0435 \u0431\u0430\u0439\u0442\u043e\u0432 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442.<\/p>\n<p><strong>\u0411\u0438\u0437\u043d\u0435\u0441-\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/strong> \u0442\u043e\u0432\u0430\u0440\u0430 \u043d\u0435\u0442 \u043d\u0430 \u0441\u043a\u043b\u0430\u0434\u0435 \u0438\u043b\u0438 \u043f\u043b\u0430\u0442\u0451\u0436 \u043e\u0442\u043a\u043b\u043e\u043d\u0451\u043d. \u042d\u0442\u043e \u0447\u0430\u0441\u0442\u043e \u043d\u0435 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430 \u0432\u043e\u043e\u0431\u0449\u0435. \u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u0440\u043e\u0434\u0435 <code>inventory.reservation_rejected<\/code>, \u0430 \u043d\u0435 \u043f\u0440\u044f\u0442\u0430\u0442\u044c \u0435\u0433\u043e \u0432 DLQ.<\/p>\n<p><strong>\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430:<\/strong> \u043d\u043e\u0432\u044b\u0439 \u0434\u0435\u0444\u0435\u043a\u0442 \u043a\u043e\u0434\u0430 \u0438\u043b\u0438 \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438. \u0411\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0435\u0451 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043e\u043f\u0430\u0441\u043d\u043e. \u0420\u0430\u0437\u0443\u043c\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 &#8212; \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u0432\u0442\u043e\u0440\u043e\u0432, \u0437\u0430\u0442\u0435\u043c parking lot \u0438 \u0441\u0438\u0433\u043d\u0430\u043b \u0434\u0435\u0436\u0443\u0440\u043d\u043e\u043c\u0443.<\/p>\n<p>\u0418\u043d\u043e\u0433\u0434\u0430 \u043a\u043b\u0430\u0441\u0441 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438. <code>customer not found<\/code> \u043c\u043e\u0436\u0435\u0442 \u043e\u0437\u043d\u0430\u0447\u0430\u0442\u044c \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443, \u0430 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f \u0438\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0435\u0449\u0451 \u043d\u0435 \u0434\u043e\u0448\u043b\u043e \u0434\u043e \u043f\u0440\u043e\u0435\u043a\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f, \u0438\u043b\u0438 read model. \u0422\u043e\u0433\u0434\u0430 retry policy \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0438\u0441\u043b\u043e \u043f\u043e\u043f\u044b\u0442\u043e\u043a, \u043d\u043e \u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u0434\u0435\u0434\u043b\u0430\u0439\u043d: \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0436\u0434\u0430\u0442\u044c \u043d\u0435 \u0431\u043e\u043b\u0435\u0435 15 \u043c\u0438\u043d\u0443\u0442 \u043f\u043e\u0441\u043b\u0435 <code>occurred_at<\/code>.<\/p>\n<p>\u0425\u043e\u0440\u043e\u0448\u0438\u0439 retry budget \u0437\u0430\u0434\u0430\u0451\u0442:<\/p>\n<ul>\n<li>\n<p>\u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043f\u043e\u043f\u044b\u0442\u043e\u043a;<\/p>\n<\/li>\n<li>\n<p>\u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u043e\u0437\u0440\u0430\u0441\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u043f\u044b\u0442\u043a\u0430\u043c\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0439 \u0440\u0430\u0437\u0431\u0440\u043e\u0441, \u0438\u043b\u0438 jitter, \u0447\u0442\u043e\u0431\u044b consumers \u043d\u0435 \u043f\u0440\u043e\u0441\u043d\u0443\u043b\u0438\u0441\u044c \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e;<\/p>\n<\/li>\n<li>\n<p>\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u043f\u043e\u0441\u043b\u0435 \u0438\u0441\u0447\u0435\u0440\u043f\u0430\u043d\u0438\u044f \u0431\u044e\u0434\u0436\u0435\u0442\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c <code>5 \u0441\u0435\u043a\u0443\u043d\u0434 -&gt; 30 \u0441\u0435\u043a\u0443\u043d\u0434 -&gt; 5 \u043c\u0438\u043d\u0443\u0442<\/code> \u043f\u043e\u043d\u044f\u0442\u043d\u0435\u0435 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u044d\u043a\u0441\u043f\u043e\u043d\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u0430. \u041a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0447\u0438\u0441\u043b\u0430 \u0437\u0430\u0432\u0438\u0441\u044f\u0442 \u043e\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0438 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0439 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u0431\u0438\u0437\u043d\u0435\u0441\u0430. \u0415\u0441\u043b\u0438 \u0431\u0430\u0437\u0430 \u043e\u0431\u044b\u0447\u043d\u043e \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0437\u0430 20 \u043c\u0438\u043d\u0443\u0442, \u0442\u0440\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u0430 \u0437\u0430 5 \u043c\u0438\u043d\u0443\u0442 35 \u0441\u0435\u043a\u0443\u043d\u0434 \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043b\u0438\u0448\u044c \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0434\u043e\u0441\u0442\u0430\u0432\u044f\u0442 \u0432\u0435\u0441\u044c \u043f\u043e\u0442\u043e\u043a \u0432 DLQ.<\/p>\n<h2>\u041f\u043e\u0447\u0435\u043c\u0443 Nack(requeue=true) \u043e\u043f\u0430\u0441\u0435\u043d<\/h2>\n<p>\u041f\u0440\u0438 <code>requeue=true<\/code> \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441\u043d\u043e\u0432\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438. \u0415\u0441\u043b\u0438 \u0432\u0441\u0435 consumers \u043f\u043e\u043b\u0443\u0447\u0430\u044e\u0442 \u043e\u0434\u043d\u0443 \u0438 \u0442\u0443 \u0436\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443, \u043e\u043d\u0438 \u0441\u043e\u0437\u0434\u0430\u044e\u0442 requeue\/redelivery loop. <a href=\"https:\/\/www.rabbitmq.com\/docs\/confirms#negative-acknowledgement-and-requeuing-of-deliveries\" rel=\"noopener noreferrer nofollow\">\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f RabbitMQ<\/a> \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0430\u0435\u0442, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0439 \u0446\u0438\u043a\u043b \u0440\u0430\u0441\u0445\u043e\u0434\u0443\u0435\u0442 CPU \u0438 \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u0442\u0440\u0430\u0444\u0438\u043a.<\/p>\n<pre><code class=\"go\">if err := handle(delivery.Body); err != nil {\/\/ \u041f\u043b\u043e\u0445\u0430\u044f \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430: \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u0438 \u043b\u0438\u043c\u0438\u0442\u0430 \u043d\u0435\u0442.return delivery.Nack(false, true)}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0437\u0430\u043c\u0435\u043d\u044f\u0442\u044c broker \u043e\u0431\u044b\u0447\u043d\u044b\u043c <code>time.Sleep<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 consumer:<\/p>\n<pre><code class=\"go\">time.Sleep(5 * time.Minute)return delivery.Nack(false, true)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u044f\u0442\u044c \u043c\u0438\u043d\u0443\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f unacked, \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u043a\u043d\u043e prefetch \u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0436\u0438\u0437\u043d\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430. \u041f\u0440\u0438 \u043f\u0430\u0434\u0435\u043d\u0438\u0438 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u043e\u0431\u043d\u0443\u043b\u0438\u0442\u0441\u044f. \u0422\u044b\u0441\u044f\u0447\u0430 \u0442\u0430\u043a\u0438\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0442\u044b\u0441\u044f\u0447\u0443 \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0438\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0438\u043b\u0438 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b.<\/p>\n<p>\u0417\u0430\u0434\u0435\u0440\u0436\u043a\u0443 \u043b\u0443\u0447\u0448\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 broker. \u0422\u043e\u0433\u0434\u0430 consumer \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0435\u0442 \u0441\u0432\u043e\u0439 \u0441\u043b\u043e\u0442, \u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<h2>Retry queues, TTL \u0438 dead letter exchange \u0432 RabbitMQ<\/h2>\n<p>\u0412 AMQP (Advanced Message Queuing Protocol) 0-9-1 \u043d\u0435\u0442 \u043e\u0431\u044b\u0447\u043d\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u00ab\u0434\u043e\u0441\u0442\u0430\u0432\u044c \u044d\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 30 \u0441\u0435\u043a\u0443\u043d\u0434\u00bb. \u041f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u043c\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u0438\u0437 retry queues. \u0423 \u044d\u0442\u0438\u0445 queues \u043d\u0435\u0442 consumers. \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0436\u0434\u0451\u0442 \u0441\u0432\u043e\u0439 TTL, \u0438\u0441\u0442\u0435\u043a\u0430\u0435\u0442 \u0438 \u0447\u0435\u0440\u0435\u0437 dead letter exchange \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u0440\u0430\u0431\u043e\u0447\u0443\u044e queue.<\/p>\n<p>\u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0442\u0440\u0438 \u043a\u043e\u0440\u0437\u0438\u043d\u044b \u0437\u0430\u0434\u0435\u0440\u0436\u0435\u043a:<\/p>\n<pre><code>                                  transient error                                       |                                       vorders -&gt; inventory.orders -&gt; consumer -&gt; inventory.orders.retry (direct)              ^                         | 5s  -&gt; retry.5s  -- TTL 5s  --+              |                         | 30s -&gt; retry.30s -- TTL 30s --+-&gt; orders              |                         | 5m  -&gt; retry.5m  -- TTL 5m  --+              |              +---------------------- expiredpermanent\/exhausted        |        vinventory.orders.dlx -&gt; inventory.orders.parking<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0435\u0441\u0442\u044c \u0442\u0440\u0438 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u043e\u043d\u044f\u0442\u0438\u044f.<\/p>\n<p><strong>TTL<\/strong>, \u0438\u043b\u0438 time to live, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 queue. \u041f\u043e\u0441\u043b\u0435 \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u044f <code>message-ttl<\/code> RabbitMQ \u043d\u0435 \u043e\u0442\u0434\u0430\u0451\u0442 \u0435\u0433\u043e consumer \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 dead letter exchange (DLX) \u043b\u0438\u0431\u043e \u0443\u0434\u0430\u043b\u044f\u0435\u0442.<\/p>\n<p><strong>Dead letter exchange<\/strong> &#8212; \u044d\u0442\u043e exchange, \u0430 \u043d\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435. RabbitMQ \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u0442 \u0442\u0443\u0434\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435 <code>basic.reject<\/code> \u0438\u043b\u0438 <code>basic.nack<\/code> \u0441 <code>requeue=false<\/code>, \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u044f TTL, \u043f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u0434\u043b\u0438\u043d\u044b queue \u0438\u043b\u0438 delivery limit quorum queue. \u041f\u043e\u043b\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0440\u0438\u0447\u0438\u043d \u0435\u0441\u0442\u044c \u0432 <a href=\"https:\/\/www.rabbitmq.com\/docs\/dlx\" rel=\"noopener noreferrer nofollow\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 DLX<\/a>. \u0427\u0442\u043e\u0431\u044b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0433\u0434\u0435-\u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0441\u044c, \u043a exchange \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u0442\u044c queue.<\/p>\n<p><strong>Parking lot<\/strong>, \u0447\u0430\u0441\u0442\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 DLQ, &#8212; \u043e\u0431\u044b\u0447\u043d\u0430\u044f queue \u0434\u043b\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u0440\u0435\u043a\u0440\u0430\u0442\u0438\u043b\u0430. \u0414\u043b\u044f \u043d\u0435\u0451 \u0437\u0430\u0434\u0430\u044e\u0442 \u0441\u0440\u043e\u043a \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f, \u0438\u043b\u0438 retention, \u0430\u043b\u0435\u0440\u0442 \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u0443\u0435\u043c\u044b\u0439 redrive &#8212; \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u0440\u0430\u0431\u043e\u0447\u0443\u044e queue \u043f\u043e\u0441\u043b\u0435 \u0443\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u0447\u0438\u043d\u044b \u043e\u0448\u0438\u0431\u043a\u0438.<\/p>\n<h3>\u041f\u043e\u0447\u0435\u043c\u0443 \u043d\u0443\u0436\u043d\u044b \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 queues \u0434\u043b\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u0435\u043a<\/h3>\n<p>\u041c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0439 <code>Expiration<\/code> \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044e \u0438 \u0441\u043b\u043e\u0436\u0438\u0442\u044c \u0432\u0441\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u044b \u0432 \u043e\u0434\u043d\u0443 queue. \u041d\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u043c TTL \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0437\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c \u0441 \u0434\u043b\u0438\u043d\u043d\u044b\u043c TTL. RabbitMQ \u0443\u0434\u0430\u043b\u0438\u0442 \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d\u043e \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0435\u0442 \u0433\u043e\u043b\u043e\u0432\u044b queue. \u0414\u043e \u044d\u0442\u043e\u0433\u043e \u0443\u0436\u0435 \u0438\u0441\u0442\u0451\u043a\u0448\u0435\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u043c\u0435\u0441\u0442\u043e \u0438 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0435. \u042d\u0442\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0432 <a href=\"https:\/\/www.rabbitmq.com\/docs\/ttl#per-message-ttl-caveats\" rel=\"noopener noreferrer nofollow\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 message TTL<\/a>.<\/p>\n<p>\u041d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043d\u0430\u0431\u043e\u0440 queues \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c TTL \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0437\u0431\u0435\u0433\u0430\u0435\u0442 \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. \u0417\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439: <code>retry.30s<\/code> \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u00ab\u043d\u0435 \u0440\u0430\u043d\u044c\u0448\u0435 \u0447\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0447\u0435\u0440\u0435\u0437 30 \u0441\u0435\u043a\u0443\u043d\u0434\u00bb, \u0430 \u043d\u0435 \u0442\u043e\u0447\u043d\u044b\u0439 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a. \u0414\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u043a\u0430\u0437\u0430 \u0442\u0430\u043a\u0430\u044f \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0430 \u043e\u0431\u044b\u0447\u043d\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442.<\/p>\n<h3>\u041e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u0442\u043e\u043f\u043e\u043b\u043e\u0433\u0438\u044e \u0438\u0437 Go<\/h3>\n<p>\u0422\u0438\u043f queue \u0437\u0430\u0434\u0430\u0451\u0442\u0441\u044f \u043f\u0440\u0438 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0438. \u0414\u043b\u044f \u0432\u0430\u0436\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c quorum queues. \u041e\u043d\u0438 \u0440\u0435\u043f\u043b\u0438\u0446\u0438\u0440\u0443\u044e\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u043a\u043e\u043d\u0441\u0435\u043d\u0441\u0443\u0441\u0430 Raft \u0438 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u044e\u0442 persistent-\u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044e \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e\u043c \u0440\u0435\u043f\u043b\u0438\u043a. \u0412 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043e\u0434\u0438\u043d \u0443\u0437\u0435\u043b, \u043d\u043e production-\u0441\u043c\u044b\u0441\u043b quorum queue \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u043d\u0435\u0447\u0451\u0442\u043d\u044b\u043c \u0447\u0438\u0441\u043b\u043e\u043c \u0440\u0435\u043f\u043b\u0438\u043a, \u043e\u0431\u044b\u0447\u043d\u043e \u0441 \u0442\u0440\u0435\u043c\u044f.<\/p>\n<pre><code class=\"go\">func declareTopology(ch *amqp.Channel) error {for _, exchange := range []struct {name stringkind string}{{\"orders\", \"topic\"},{\"inventory.orders.retry\", \"direct\"},{\"inventory.orders.dlx\", \"direct\"},} {if err := ch.ExchangeDeclare(exchange.name,exchange.kind,true,  \/\/ durablefalse, \/\/ auto-deletefalse, \/\/ internalfalse, \/\/ no-waitnil,); err != nil {return fmt.Errorf(\"declare exchange %s: %w\", exchange.name, err)}}queueArgs := amqp.Table{amqp.QueueTypeArg: amqp.QueueTypeQuorum,}queues := []string{\"inventory.orders\",\"inventory.orders.retry.5s\",\"inventory.orders.retry.30s\",\"inventory.orders.retry.5m\",\"inventory.orders.parking\",}for _, name := range queues {if _, err := ch.QueueDeclare(name,true,  \/\/ durablefalse, \/\/ auto-deletefalse, \/\/ exclusivefalse, \/\/ no-waitqueueArgs,); err != nil {return fmt.Errorf(\"declare queue %s: %w\", name, err)}}bindings := []struct {queue, key, exchange string}{{\"inventory.orders\", \"order.created\", \"orders\"},{\"inventory.orders.retry.5s\", \"5s\", \"inventory.orders.retry\"},{\"inventory.orders.retry.30s\", \"30s\", \"inventory.orders.retry\"},{\"inventory.orders.retry.5m\", \"5m\", \"inventory.orders.retry\"},{\"inventory.orders.parking\", \"inventory.orders.failed\", \"inventory.orders.dlx\"},}for _, binding := range bindings {if err := ch.QueueBind(binding.queue,binding.key,binding.exchange,false,nil,); err != nil {return fmt.Errorf(\"bind queue %s: %w\", binding.queue, err)}}return nil}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>TTL \u0438 dead lettering \u043b\u0443\u0447\u0448\u0435 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c RabbitMQ policies, \u0430 \u043d\u0435 \u0436\u0451\u0441\u0442\u043a\u0438\u043c\u0438 <code>x-arguments<\/code> \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. Policy \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0431\u0435\u0437 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f queue \u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u0440\u0430\u0437\u0432\u0451\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430. RabbitMQ <a href=\"https:\/\/www.rabbitmq.com\/docs\/dlx#configuring-a-dead-letter-exchange-using-optional-queue-arguments\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u044f\u043c\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442 policies \u0434\u043b\u044f DLX<\/a>.<\/p>\n<p>\u0414\u043b\u044f \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 queue \u0437\u0430\u0434\u0430\u0434\u0438\u043c parking lot \u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0445 \u0434\u043e\u0441\u0442\u0430\u0432\u043e\u043a. \u0414\u043b\u044f retry queues \u0437\u0430\u0434\u0430\u0434\u0438\u043c TTL \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0432 exchange <code>orders<\/code>:<\/p>\n<pre><code>rabbitmqctl set_policy inventory-orders-main \\  '^inventory\\.orders$' \\  '{\"dead-letter-exchange\":\"inventory.orders.dlx\",\"dead-letter-routing-key\":\"inventory.orders.failed\",\"dead-letter-strategy\":\"at-least-once\",\"overflow\":\"reject-publish\",\"delivery-limit\":8}' \\  --apply-to quorum_queuesrabbitmqctl set_policy inventory-orders-retry-5s \\  '^inventory\\.orders\\.retry\\.5s$' \\  '{\"message-ttl\":5000,\"dead-letter-exchange\":\"orders\",\"dead-letter-routing-key\":\"order.created\",\"dead-letter-strategy\":\"at-least-once\",\"overflow\":\"reject-publish\"}' \\  --apply-to quorum_queuesrabbitmqctl set_policy inventory-orders-retry-30s \\  '^inventory\\.orders\\.retry\\.30s$' \\  '{\"message-ttl\":30000,\"dead-letter-exchange\":\"orders\",\"dead-letter-routing-key\":\"order.created\",\"dead-letter-strategy\":\"at-least-once\",\"overflow\":\"reject-publish\"}' \\  --apply-to quorum_queuesrabbitmqctl set_policy inventory-orders-retry-5m \\  '^inventory\\.orders\\.retry\\.5m$' \\  '{\"message-ttl\":300000,\"dead-letter-exchange\":\"orders\",\"dead-letter-routing-key\":\"order.created\",\"dead-letter-strategy\":\"at-least-once\",\"overflow\":\"reject-publish\"}' \\  --apply-to quorum_queues<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0430\u0447\u0435\u043c \u0437\u0434\u0435\u0441\u044c <code>dead-letter-strategy=at-least-once<\/code>? \u041e\u0431\u044b\u0447\u043d\u044b\u0439 DLX \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0435\u0439 \u0431\u0435\u0437 publisher confirms \u0438 \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u0435\u0433\u043e \u0438\u0437 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 queue. \u0415\u0441\u043b\u0438 \u0446\u0435\u043b\u0435\u0432\u0430\u044f queue \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430, \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0442\u0435\u0440\u044f\u0442\u044c. Quorum queues \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 <a href=\"https:\/\/www.rabbitmq.com\/docs\/quorum-queues#activating-at-least-once-dead-lettering\" rel=\"noopener noreferrer nofollow\">at-least-once dead lettering<\/a>: \u0438\u0441\u0445\u043e\u0434\u043d\u0430\u044f queue \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043f\u043e\u043a\u0430 \u0446\u0435\u043b\u0435\u0432\u0430\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u0430 \u043d\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442 \u043f\u0440\u0438\u0451\u043c. \u0415\u0441\u043b\u0438 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u043e\u0442\u0435\u0440\u044f\u0435\u0442\u0441\u044f, \u0446\u0435\u043b\u0435\u0432\u0430\u044f queue \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c \u0432\u0441\u0451 \u0435\u0449\u0451 \u043d\u0443\u0436\u043d\u0430. \u0422\u0430\u043a\u043e\u0439 \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0435 CPU \u0438 \u043f\u0430\u043c\u044f\u0442\u0438, \u0430 \u0442\u0430\u043a\u0436\u0435 <code>overflow=reject-publish<\/code>. \u041d\u0430 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430\u0445, \u043e\u0431\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u044b\u0445 \u0441\u043e \u0441\u0442\u0430\u0440\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u0439 RabbitMQ, \u0442\u0430\u043a\u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c feature flag <code>stream_queue<\/code>.<\/p>\n<p>RabbitMQ \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0435 queues \u0447\u0435\u0440\u0435\u0437 <code>max-length<\/code> \u0438\u043b\u0438 <code>max-length-bytes<\/code>. \u0415\u0441\u043b\u0438 parking queue \u0438\u043b\u0438 \u0440\u0430\u0431\u043e\u0447\u0430\u044f queue \u0434\u043e\u043b\u0433\u043e \u043d\u0435 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439 DLX \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0445 \u0432 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435. \u041a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043b\u0438\u043c\u0438\u0442 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0433\u043e \u0434\u0438\u0441\u043a\u0430 \u0438 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0433\u043e backlog, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043e\u043d \u043d\u0435 \u0437\u0430\u0434\u0430\u043d \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043e\u0439.<\/p>\n<p>\u041d\u0430 classic queues \u0438 \u043f\u0440\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 DLX \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f at most once. \u042d\u0442\u043e \u0432\u0430\u0436\u043d\u0430\u044f \u043e\u0433\u043e\u0432\u043e\u0440\u043a\u0430: \u043d\u0430\u043b\u0438\u0447\u0438\u0435 DLX \u0441\u0430\u043c\u043e \u043f\u043e \u0441\u0435\u0431\u0435 \u0435\u0449\u0451 \u043d\u0435 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043d\u0430\u0434\u0451\u0436\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u043d\u043e\u0441.<\/p>\n<h2>\u041f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u043f\u043e\u0432\u0442\u043e\u0440 \u0434\u043e Ack \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<\/h2>\n<p>Consumer \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 header <code>x-retry-attempt<\/code>. \u041d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e <code>x-death<\/code>: \u044d\u0442\u043e\u0442 header \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 dead lettering, \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 queue \u0438 \u043f\u0440\u0438\u0447\u0438\u043d\u044b, \u0430 \u043e\u0431\u044b\u0447\u043d\u0430\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0434\u0440\u0443\u0433\u0443\u044e \u0438\u0441\u0442\u043e\u0440\u0438\u044e.<\/p>\n<p>\u041f\u043e\u0440\u044f\u0434\u043e\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u043f\u043e\u0441\u043b\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043e\u0448\u0438\u0431\u043a\u0438 \u0442\u0430\u043a\u043e\u0439:<\/p>\n<ol>\n<li>\n<p>\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u0442\u0435\u043c \u0436\u0435 <code>MessageId<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c <code>x-retry-attempt<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u041e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043f\u0438\u044e \u0432 \u043d\u0443\u0436\u043d\u0443\u044e retry queue.<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f publisher confirm \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c <code>basic.return<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0422\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c <code>Ack<\/code> \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0435.<\/p>\n<\/li>\n<\/ol>\n<p>\u0415\u0441\u043b\u0438 consumer \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442 <code>Ack<\/code> \u0440\u0430\u043d\u044c\u0448\u0435 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438, \u0441\u0431\u043e\u0439 \u043f\u043e\u0442\u0435\u0440\u044f\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435. \u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0443\u043f\u0430\u0434\u0451\u0442 \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0451\u043d\u043d\u043e\u0439 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438, \u043d\u043e \u0434\u043e <code>Ack<\/code>, \u043f\u043e\u044f\u0432\u044f\u0442\u0441\u044f \u0434\u0432\u0435 \u043a\u043e\u043f\u0438\u0438. \u0423\u0431\u0440\u0430\u0442\u044c \u043e\u0431\u0435 \u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u043e\u0434\u043d\u043e\u0439 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0435\u0439 \u043d\u0435\u043b\u044c\u0437\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442 \u0438 \u043f\u043e\u043b\u0430\u0433\u0430\u0435\u043c\u0441\u044f \u043d\u0430 Inbox.<\/p>\n<p>\u041d\u0438\u0436\u0435 publisher \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0432\u044b\u0437\u043e\u0432\u044b \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c AMQP channel. \u042d\u0442\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0441\u0432\u044f\u0437\u044c <code>basic.return<\/code> \u0441 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0435\u0439 \u0432 \u043f\u043e\u043b\u0451\u0442\u0435.<\/p>\n<pre><code class=\"go\">type ConfirmingPublisher struct {mu      sync.Mutexch      *amqp.Channelreturns &lt;-chan amqp.Return}func NewConfirmingPublisher(ch *amqp.Channel) (*ConfirmingPublisher, error) {if err := ch.Confirm(false); err != nil {return nil, fmt.Errorf(\"enable publisher confirms: %w\", err)}returns := ch.NotifyReturn(make(chan amqp.Return, 1))return &amp;ConfirmingPublisher{ch: ch, returns: returns}, nil}func (p *ConfirmingPublisher) Close() error {p.mu.Lock()defer p.mu.Unlock()return p.ch.Close()}func (p *ConfirmingPublisher) Publish(ctx context.Context,exchange string,key string,msg amqp.Publishing,) error {p.mu.Lock()defer p.mu.Unlock()confirmation, err := p.ch.PublishWithDeferredConfirmWithContext(ctx,exchange,key,true,  \/\/ mandatoryfalse, \/\/ immediate RabbitMQ \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442msg,)if err != nil {return fmt.Errorf(\"publish: %w\", err)}acked, err := confirmation.WaitContext(ctx)if err != nil {return fmt.Errorf(\"wait for confirm: %w\", err)}if !acked {return errors.New(\"broker nacked publication\")}\/\/ RabbitMQ \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 basic.return \u0434\u043e confirm. Channel \u0432\u044b\u0434\u0435\u043b\u0435\u043d \u044d\u0442\u043e\u043c\u0443\/\/ publisher, \u0430 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 return \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a msg.select {case returned, ok := &lt;-p.returns:if !ok {return errors.New(\"return notifications channel closed\")}return fmt.Errorf(\"unroutable message %s: %s\",returned.MessageId,returned.ReplyText,)default:return nil}}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>Production-\u043e\u0431\u0451\u0440\u0442\u043a\u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0442\u044c \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0438\u0435 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u0440\u0438 <code>NotifyClose<\/code>, \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c channel \u0438 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u043d\u0435\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0451\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043d \u0432 \u043f\u043e\u0441\u0442\u0435 <a href=\"https:\/\/ubiklab.net\/posts\/rabbitmq-go\/\" rel=\"noopener noreferrer nofollow\">\u00abRabbitMQ \u0438 Go\u00bb<\/a>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u044b\u0431\u0435\u0440\u0435\u043c retry queue \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0435 headers:<\/p>\n<pre><code class=\"go\">var retryPlan = []string{\"5s\", \"30s\", \"5m\"}func scheduleRetry(ctx context.Context,publisher *ConfirmingPublisher,delivery amqp.Delivery,cause error,) (scheduled bool, err error) {attempt := headerInt(delivery.Headers[\"x-retry-attempt\"])if attempt &gt;= len(retryPlan) {return false, nil}headers := cloneHeaders(delivery.Headers)headers[\"x-retry-attempt\"] = int32(attempt + 1)headers[\"x-last-error\"] = truncate(cause.Error(), 512)err = publisher.Publish(ctx, \"inventory.orders.retry\", retryPlan[attempt], amqp.Publishing{Headers:         headers,ContentType:     delivery.ContentType,ContentEncoding: delivery.ContentEncoding,DeliveryMode:    amqp.Persistent,CorrelationId:   delivery.CorrelationId,MessageId:       delivery.MessageId, \/\/ ID \u043d\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 retryTimestamp:       delivery.Timestamp,Type:            delivery.Type,Body:            delivery.Body,})if err != nil {return false, err}return true, nil}func cloneHeaders(src amqp.Table) amqp.Table {dst := make(amqp.Table, len(src)+2)for key, value := range src {dst[key] = value}return dst}func headerInt(value any) int {var result intswitch value := value.(type) {case int8:result = int(value)case int16:result = int(value)case int32:result = int(value)case int64:result = int(value)default:return 0}if result &lt; 0 {return 0}return result}func truncate(value string, limit int) string {runes := []rune(value)if len(runes) &lt;= limit {return value}return string(runes[:limit])}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041c\u044b \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u043d\u043e \u043d\u0435 \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c <code>Expiration<\/code>. \u0415\u0441\u043b\u0438 producer \u0437\u0430\u0434\u0430\u043b \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u044e TTL, \u0435\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0442\u0440\u0430\u043a\u0442\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u0431\u0438\u0437\u043d\u0435\u0441-\u0434\u0435\u0434\u043b\u0430\u0439\u043d \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e. \u0421\u043b\u0435\u043f\u043e\u0435 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043f\u043e\u0432\u0442\u043e\u0440 \u0438\u0441\u0442\u0435\u0447\u0451\u0442 \u0440\u0430\u043d\u044c\u0448\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0447\u0438\u0441\u043b\u043e \u043f\u043e\u043f\u044b\u0442\u043e\u043a, \u043d\u043e \u043d\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u043e\u0437\u0440\u0430\u0441\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u0431\u0435\u0437 jitter. \u0412 production consumer \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c <code>occurred_at<\/code> \u0438\u0437 envelope, \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c \u0435\u0433\u043e \u0441 \u0431\u0438\u0437\u043d\u0435\u0441-\u0434\u0435\u0434\u043b\u0430\u0439\u043d\u043e\u043c \u0438 \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0441\u0440\u0430\u0437\u0443 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c retry. Jitter \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432\u044b\u0431\u043e\u0440\u043e\u043c \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0445 \u043a\u043e\u0440\u0437\u0438\u043d \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0439 per-message TTL \u0432 \u043e\u0431\u0449\u0435\u0439 retry queue \u043e\u043f\u0430\u0441\u043d\u043e \u0438\u0437-\u0437\u0430 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 \u0432\u044b\u0448\u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u0432 \u0433\u043e\u043b\u043e\u0432\u0435 queue.<\/p>\n<h2>Consumer \u0441 \u0442\u0440\u0435\u043c\u044f \u0438\u0441\u0445\u043e\u0434\u0430\u043c\u0438<\/h2>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u0437 \u0442\u0440\u0451\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432: \u0443\u0441\u043f\u0435\u0445, \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430 \u0438\u043b\u0438 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430. \u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0442\u0438\u043f\u044b \u043e\u0448\u0438\u0431\u043e\u043a:<\/p>\n<pre><code class=\"go\">type PermanentError struct {Err error}func (e *PermanentError) Error() string { return e.Err.Error() }func (e *PermanentError) Unwrap() error { return e.Err }func process(ctx context.Context,db *sql.DB,delivery amqp.Delivery,) error {if delivery.MessageId == \"\" {return &amp;PermanentError{Err: errors.New(\"message_id is required\")}}var event OrderCreatedif err := json.Unmarshal(delivery.Body, &amp;event); err != nil {return &amp;PermanentError{Err: fmt.Errorf(\"decode order.created: %w\", err)}}if event.OrderID == \"\" || event.SKU == \"\" || event.Count &lt;= 0 {return &amp;PermanentError{Err: errors.New(\"invalid order.created\")}}return reserve(ctx, db, delivery.MessageId, event)}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f \u043a\u0440\u0430\u0442\u043a\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u0447\u0438\u0442\u0430\u0435\u0442 \u0432\u0441\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 <code>reserve<\/code> \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438. \u0412 production \u043d\u0443\u0436\u043d\u043e \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u043e\u0448\u0438\u0431\u043a\u0438 \u0431\u0430\u0437\u044b: deadlock, serialization failure \u0438 \u043e\u0431\u0440\u044b\u0432 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u043e\u0431\u044b\u0447\u043d\u043e \u0442\u0440\u0435\u0431\u0443\u044e\u0442 retry, \u0430 \u043d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u0435 constraint \u043c\u043e\u0436\u0435\u0442 \u043e\u0437\u043d\u0430\u0447\u0430\u0442\u044c \u0434\u0435\u0444\u0435\u043a\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u043b\u0438 \u043a\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0432\u0442\u043e\u0440 \u043d\u0435 \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442.<\/p>\n<p>\u0426\u0438\u043a\u043b \u0447\u0442\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0443:<\/p>\n<pre><code class=\"go\">func consume(ctx context.Context,consumerChannel *amqp.Channel,db *sql.DB,retryPublisher *ConfirmingPublisher,) error {\/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u043b\u0430\u0434\u0435\u0435\u0442 consumerChannel. \u041f\u0440\u0438 \u043b\u044e\u0431\u043e\u043c \u0432\u044b\u0445\u043e\u0434\u0435 \u043d\u0435\u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u044b\u0435\/\/ \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u0441\u044f \u0432 queue.defer func() {_ = consumerChannel.Close()}()if err := consumerChannel.Qos(16, 0, false); err != nil {return fmt.Errorf(\"set qos: %w\", err)}deliveries, err := consumerChannel.Consume(\"inventory.orders\",\"inventory-worker\",false, \/\/ auto-ackfalse, \/\/ exclusivefalse, \/\/ no-localfalse, \/\/ no-waitnil,)if err != nil {return fmt.Errorf(\"consume: %w\", err)}for {select {case &lt;-ctx.Done():return ctx.Err()case delivery, ok := &lt;-deliveries:if !ok {return errors.New(\"delivery channel closed\")}handleCtx, cancel := context.WithTimeout(ctx, 10*time.Second)err := process(handleCtx, db, delivery)cancel()if err == nil {if err := delivery.Ack(false); err != nil {return fmt.Errorf(\"ack: %w\", err)}continue}var permanent *PermanentErrorif errors.As(err, &amp;permanent) {\/\/ requeue=false \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 inventory.orders.dlx.if nackErr := delivery.Nack(false, false); nackErr != nil {return fmt.Errorf(\"park message: %w\", nackErr)}continue}retryCtx, retryCancel := context.WithTimeout(ctx, 5*time.Second)scheduled, retryErr := scheduleRetry(retryCtx,retryPublisher,delivery,err,)retryCancel()if retryErr != nil {\/\/ \u041d\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0443 \u0438 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\/\/ publisher channel \u0441 \u043d\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c._ = retryPublisher.Close()return fmt.Errorf(\"schedule retry: %w\", retryErr)}if !scheduled {if nackErr := delivery.Nack(false, false); nackErr != nil {return fmt.Errorf(\"park exhausted message: %w\", nackErr)}continue}if err := delivery.Ack(false); err != nil {return fmt.Errorf(\"ack scheduled retry: %w\", err)}}}}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u043e\u0434 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438, \u043d\u043e \u043d\u0435 \u0432\u0435\u0441\u044c production runtime. \u041d\u0443\u0436\u043d\u044b reconnect \u0441 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u043c backoff, \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u043e\u043f\u043e\u043b\u043e\u0433\u0438\u0438, graceful shutdown \u0438 \u043c\u0435\u0442\u0440\u0438\u043a\u0438. \u041f\u0440\u0438 \u043e\u0448\u0438\u0431\u043a\u0435 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 supervisor \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0437\u0430\u043d\u043e\u0432\u043e \u0438 consumer channel, \u0438 publisher channel. \u041e\u0434\u0438\u043d <a href=\"http:\/\/amqp.Channel\" rel=\"noopener noreferrer nofollow\"><code>amqp.Channel<\/code><\/a> \u043d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 goroutines \u0431\u0435\u0437 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>\u0414\u043b\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0440\u043e\u0449\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e workers, \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u043e \u0441\u0432\u043e\u0438\u043c consumer channel, \u0447\u0435\u043c \u0440\u0430\u0437\u0434\u0430\u0442\u044c <a href=\"http:\/\/amqp.Delivery\" rel=\"noopener noreferrer nofollow\"><code>amqp.Delivery<\/code><\/a> \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u043c goroutines \u0438 \u0437\u0430\u0442\u0435\u043c \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u0447\u0435\u0440\u0435\u0437 \u043e\u0431\u0449\u0438\u0439 channel. Prefetch \u0437\u0430\u0434\u0430\u0451\u0442 \u0432\u0435\u0440\u0445\u043d\u044e\u044e \u0433\u0440\u0430\u043d\u0438\u0446\u0443 unacked-\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>0<\/code> \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043b\u0438\u043c\u0438\u0442\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u0441 \u043d\u0435\u0433\u043e \u0440\u0438\u0441\u043a\u043e\u0432\u0430\u043d\u043d\u043e. RabbitMQ \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0435\u0442 \u0441\u0432\u044f\u0437\u044c prefetch, \u043f\u0430\u043c\u044f\u0442\u0438 \u0438 throughput \u0432 <a href=\"https:\/\/www.rabbitmq.com\/docs\/confirms#channel-prefetch-setting-qos\" rel=\"noopener noreferrer nofollow\">\u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0435 \u043f\u043e acknowledgements<\/a>.<\/p>\n<h2>\u0427\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u043e\u0441\u044c \u0432 RabbitMQ 4.3<\/h2>\n<p>\u041d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 RabbitMQ 4.3, quorum queues \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 <a href=\"https:\/\/www.rabbitmq.com\/docs\/quorum-queues#delayed-retry\" rel=\"noopener noreferrer nofollow\">\u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 delayed retry<\/a>. Broker \u0443\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0451\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0438 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u043b\u0438\u043d\u0435\u0439\u043d\u0443\u044e \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443:<\/p>\n<pre><code>delay = min(min_delay * delivery_count, max_delay)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>RabbitMQ \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 \u043a queue <a href=\"https:\/\/www.rabbitmq.com\/docs\/policies#policy-priorities\" rel=\"noopener noreferrer nofollow\">\u043d\u0435 \u0431\u043e\u043b\u0435\u0435 \u043e\u0434\u043d\u043e\u0439 \u043e\u0431\u044b\u0447\u043d\u043e\u0439 policy<\/a>. \u0415\u0441\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0432\u0442\u043e\u0440\u0443\u044e policy \u0441 \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c, \u043e\u043d\u0430 \u043d\u0435 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u0441\u044f \u0441 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439, \u0430 \u0432\u044b\u0442\u0435\u0441\u043d\u0438\u0442 \u0435\u0451. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0431\u043d\u043e\u0432\u0438\u043c \u0443\u0436\u0435 \u0437\u0430\u0434\u0430\u043d\u043d\u0443\u044e <code>inventory-orders-main<\/code> \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u0432 \u043e\u0434\u043d\u043e\u043c JSON \u0432\u0441\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b:<\/p>\n<pre><code>rabbitmqctl set_policy inventory-orders-main \\  '^inventory\\.orders$' \\  '{\"dead-letter-exchange\":\"inventory.orders.dlx\",\"dead-letter-routing-key\":\"inventory.orders.failed\",\"dead-letter-strategy\":\"at-least-once\",\"overflow\":\"reject-publish\",\"delivery-limit\":8,\"delayed-retry-type\":\"all\",\"delayed-retry-min\":1000,\"delayed-retry-max\":30000}' \\  --apply-to quorum_queues<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e consumer \u043c\u043e\u0436\u0435\u0442 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u0442\u0443 \u0436\u0435 queue, \u0430 broker \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443. \u0415\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u044b \u0440\u0430\u0441\u0442\u0443\u0449\u0430\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u0438 \u0443\u0447\u0451\u0442 delivery limit, \u0432 <code>amqp091-go<\/code> \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>Reject(true)<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 <code>basic.reject<\/code>:<\/p>\n<pre><code class=\"go\">if err := delivery.Reject(true); err != nil {return fmt.Errorf(\"reject for delayed retry: %w\", err)}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 retry queues \u0432 \u044d\u0442\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435 \u043d\u0435 \u043d\u0443\u0436\u043d\u044b. \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0449\u0435, \u0435\u0441\u043b\u0438 \u043b\u0438\u043d\u0435\u0439\u043d\u044b\u0439 backoff \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0438 \u0432\u0441\u044f \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0443\u0436\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 4.3.<\/p>\n<p>\u0415\u0441\u0442\u044c \u0432\u0430\u0436\u043d\u0430\u044f \u0434\u0435\u0442\u0430\u043b\u044c \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430. \u0412 RabbitMQ 4.3 <code>basic.nack<\/code> \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 <code>x-acquired-count<\/code>, \u043d\u043e \u043d\u0435 <code>x-delivery-count<\/code>. <code>basic.reject<\/code> \u0438 \u043f\u043e\u0442\u0435\u0440\u044f connection \u0441\u0447\u0438\u0442\u0430\u044e\u0442\u0441\u044f \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u043e\u0439 \u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u044e\u0442 \u043e\u0431\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 <code>Nack(requeue=true)<\/code> \u043f\u0440\u0438 \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u043c \u0440\u0430\u0441\u0447\u0451\u0442\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u0435\u043d \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443. \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 \u043e\u043f\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043d\u0430 delivery count \u0438 \u043b\u0438\u043c\u0438\u0442 \u043f\u043e\u043f\u044b\u0442\u043e\u043a, \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0432 <a href=\"https:\/\/www.rabbitmq.com\/docs\/quorum-queues#when-is-delivery-count-incremented\" rel=\"noopener noreferrer nofollow\">\u0442\u0430\u0431\u043b\u0438\u0446\u0435 poison message handling<\/a>.<\/p>\n<p>\u0423 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430 \u0438 TTL buckets \u0440\u0430\u0437\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0438\u0441\u0441\u044b:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041f\u043e\u0434\u0445\u043e\u0434<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u043b\u044e\u0441\u044b<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Retry queues + TTL + DLX<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445, \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u0443\u043f\u0435\u043d\u0438 \u0437\u0430\u0434\u0435\u0440\u0436\u0435\u043a, \u044f\u0432\u043d\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0411\u043e\u043b\u044c\u0448\u0435 queues \u0438 bindings, \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u0447\u0435\u0440\u0435\u0437 DLX, application republish \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043e\u043a\u043d\u043e \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">RabbitMQ 4.3 delayed retry<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 queues \u0438 \u043f\u0435\u0440\u0435\u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438, broker \u0432\u0438\u0434\u0438\u0442 delayed messages<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0422\u043e\u043b\u044c\u043a\u043e quorum queues 4.3+, \u043b\u0438\u043d\u0435\u0439\u043d\u044b\u0439 backoff, \u0442\u043e\u043d\u043a\u043e\u0441\u0442\u0438 <code>nack<\/code> \u0438 <code>reject<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>rabbitmq_delayed_message_exchange<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u0430\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u0432 header<\/p>\n<\/td>\n<td>\n<p align=\"left\">Community plugin \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0438 \u043d\u0435 \u0432\u0445\u043e\u0434\u0438\u0442 \u0432 RabbitMQ<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0434\u043e\u043b\u0433\u043e \u0431\u044b\u043b \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u0435\u043d, \u043d\u043e RabbitMQ \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u043e\u043c\u0435\u0447\u0430\u0435\u0442 delayed message exchange \u043a\u0430\u043a <a href=\"https:\/\/www.rabbitmq.com\/community-plugins\" rel=\"noopener noreferrer nofollow\">\u043d\u0435\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0439 community plugin<\/a>.<\/p>\n<p>\u041d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 RabbitMQ 4.0, delivery limit \u0434\u043b\u044f quorum queues \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0440\u0430\u0432\u0435\u043d 20. \u041f\u043e\u0441\u043b\u0435 \u043f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u043b\u0438 \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u0432 DLX, \u0435\u0441\u043b\u0438 \u043e\u043d \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d. \u042d\u0442\u043e \u0437\u0430\u0449\u0438\u0442\u0430 \u043e\u0442 poison messages, \u0430 \u043d\u0435 \u0437\u0430\u043c\u0435\u043d\u0430 retry policy: \u0432\u0435\u0440\u0441\u0438\u044f 4.3 \u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u0435\u0442 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 <code>basic.nack<\/code> \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u043e\u0439. \u042f\u0432\u043d\u044b\u0439 application header \u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0431\u044e\u0434\u0436\u0435\u0442 \u0432\u0441\u0451 \u0435\u0449\u0451 \u043f\u0440\u043e\u0449\u0435 \u0441\u0432\u044f\u0437\u0430\u0442\u044c \u0441 \u0431\u0438\u0437\u043d\u0435\u0441-\u0434\u0435\u0434\u043b\u0430\u0439\u043d\u043e\u043c.<\/p>\n<h2>Dead letter queue \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430, \u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e binding<\/h2>\n<p>Parking lot \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u0435\u043d, \u0435\u0441\u043b\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0443\u0437\u043d\u0430\u0451\u0442 \u043e \u043d\u0451\u043c \u0447\u0435\u0440\u0435\u0437 \u043c\u0435\u0441\u044f\u0446. \u0414\u043b\u044f \u043d\u0435\u0433\u043e \u043d\u0443\u0436\u0435\u043d \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441.<\/p>\n<p>\u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0439\u0442\u0435 \u0440\u044f\u0434\u043e\u043c \u0441 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c:<\/p>\n<ul>\n<li>\n<p>\u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 <code>message_id<\/code>, \u0442\u0438\u043f \u0438 \u0432\u0435\u0440\u0441\u0438\u044e \u0441\u0445\u0435\u043c\u044b;<\/p>\n<\/li>\n<li>\n<p>\u0447\u0438\u0441\u043b\u043e \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u0438 \u0432\u0440\u0435\u043c\u044f \u043f\u0435\u0440\u0432\u043e\u0439 \u043e\u0448\u0438\u0431\u043a\u0438;<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0438 \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438;<\/p>\n<\/li>\n<li>\n<p>correlation ID \u0438 trace ID;<\/p>\n<\/li>\n<li>\n<p>\u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0435 routing key \u0438 producer;<\/p>\n<\/li>\n<li>\n<p>\u0432\u0435\u0440\u0441\u0438\u044e consumer, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u0451\u043b \u043e\u0442\u043a\u0430\u0437.<\/p>\n<\/li>\n<\/ul>\n<p>RabbitMQ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 header <code>x-death<\/code> \u043f\u0440\u0438 dead lettering. \u0412 \u043d\u0451\u043c \u0435\u0441\u0442\u044c queue, \u043f\u0440\u0438\u0447\u0438\u043d\u0430, \u0447\u0438\u0441\u043b\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438 \u0432\u0440\u0435\u043c\u044f. \u0418\u0441\u0442\u043e\u0440\u0438\u044f \u0441\u0436\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043f\u043e \u043f\u0430\u0440\u0435 <code>{queue, reason}<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 header \u043d\u0435 \u0440\u0430\u0441\u0442\u0451\u0442 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0446\u0438\u043a\u043b. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u043f\u0440\u0438\u0447\u0438\u043d\u044b \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0442 <code>rejected<\/code>, <code>expired<\/code>, <code>maxlen<\/code> \u0438 <code>delivery_limit<\/code>. \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u0432 <a href=\"https:\/\/www.rabbitmq.com\/docs\/dlx#dead-lettered-effects-on-messages\" rel=\"noopener noreferrer nofollow\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 dead-lettered effects<\/a>.<\/p>\n<p>\u041d\u0443\u0436\u043d\u044b \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0434\u0432\u0430 \u0430\u043b\u0435\u0440\u0442\u0430:<\/p>\n<ol>\n<li>\n<p>\u0412 parking lot \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435.<\/p>\n<\/li>\n<li>\n<p>\u0421\u0430\u043c\u043e dead lettering \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438\u043b\u0438 \u0446\u0435\u043b\u0435\u0432\u0430\u044f queue \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430.<\/p>\n<\/li>\n<\/ol>\n<p>Redrive \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043f\u0435\u0442\u043b\u0451\u0439 <code>parking -&gt; main -&gt; parking<\/code>. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442 \u0434\u0430\u043d\u043d\u044b\u0435, \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0438\u043b\u0438 \u043a\u043e\u0434. \u0417\u0430\u0442\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u043c\u0443 \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044e, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0438\u0445 ID \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e. \u0418\u043d\u0430\u0447\u0435 \u043e\u0434\u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 redrive \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u0430 \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0438\u043d\u0446\u0438\u0434\u0435\u043d\u0442 \u043d\u0430 \u0432\u0441\u0451\u043c backlog.<\/p>\n<p>\u0414\u043b\u044f parking lot \u0437\u0430\u0434\u0430\u044e\u0442 retention \u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e. \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043d\u0435\u0440\u0435\u0434\u043a\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0442\u043e\u043a\u0435\u043d\u044b \u0438\u043b\u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e. DLQ \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u0431\u0435\u0441\u0441\u0440\u043e\u0447\u043d\u044b\u043c \u0430\u0440\u0445\u0438\u0432\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0447\u0438\u0442\u0430\u0435\u0442 \u043b\u044e\u0431\u043e\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c management UI.<\/p>\n<h2>\u041f\u043e\u0432\u0442\u043e\u0440\u044b \u043d\u0430\u0440\u0443\u0448\u0430\u044e\u0442 \u043f\u043e\u0440\u044f\u0434\u043e\u043a<\/h2>\n<p>\u041f\u0443\u0441\u0442\u044c \u0434\u043b\u044f \u0437\u0430\u043a\u0430\u0437\u0430 <code>42<\/code> \u043f\u0440\u0438\u0448\u043b\u0438 \u0434\u0432\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f:<\/p>\n<pre><code>v7: order.createdv8: order.cancelled<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u043d\u0430\u0447\u0430 consumer \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043d\u0435 \u0441\u043c\u043e\u0433 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c <code>v7<\/code> \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b \u0435\u0433\u043e \u0432 <code>retry.30s<\/code>. \u0417\u0430\u0442\u0435\u043c consumer \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043b \u043e\u0441\u0442\u0430\u0432\u0448\u0435\u0435\u0441\u044f \u0432 \u0440\u0430\u0431\u043e\u0447\u0435\u0439 queue \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <code>v8<\/code>. \u0427\u0435\u0440\u0435\u0437 30 \u0441\u0435\u043a\u0443\u043d\u0434 \u0432\u0435\u0440\u043d\u0443\u043b\u043e\u0441\u044c <code>v7<\/code>. FIFO (first in, first out &#8212; \u00ab\u043f\u0435\u0440\u0432\u044b\u043c \u043f\u0440\u0438\u0448\u0451\u043b, \u043f\u0435\u0440\u0432\u044b\u043c \u0432\u044b\u0448\u0435\u043b\u00bb) \u043d\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 queue \u043d\u0435 \u0441\u043f\u0430\u0441\u0430\u0435\u0442, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043f\u043e\u043a\u0438\u043d\u0443\u043b\u043e \u0435\u0451 \u0438 \u0437\u0430\u0442\u0435\u043c \u0431\u044b\u043b\u043e \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u043e \u0437\u0430\u043d\u043e\u0432\u043e.<\/p>\n<p>\u041d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e consumers, redelivery \u0438 priorities \u0442\u0430\u043a\u0436\u0435 \u043c\u0435\u043d\u044f\u044e\u0442 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u044b\u0439 \u043f\u043e\u0440\u044f\u0434\u043e\u043a. RabbitMQ \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u044d\u0442\u0438 \u0441\u043b\u0443\u0447\u0430\u0438 \u0432 <a href=\"https:\/\/www.rabbitmq.com\/docs\/queues#message-ordering\" rel=\"noopener noreferrer nofollow\">\u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0435 \u043f\u043e ordering<\/a>.<\/p>\n<p>\u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0439, \u0438 \u043d\u0438 \u043e\u0434\u043d\u0430 \u043d\u0435 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u0430.<\/p>\n<h3>\u0412\u0435\u0440\u0441\u0438\u044f \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430<\/h3>\n<p>Producer \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 <code>aggregate_id=42<\/code> \u0438 <code>aggregate_version=7<\/code>. Consumer \u0445\u0440\u0430\u043d\u0438\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u043f\u0440\u0438\u043c\u0435\u043d\u0451\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e.<\/p>\n<ul>\n<li>\n<p>\u0432\u0435\u0440\u0441\u0438\u044f \u0440\u0430\u0432\u043d\u0430 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0439 &#8212; \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c;<\/p>\n<\/li>\n<li>\n<p>\u0432\u0435\u0440\u0441\u0438\u044f \u0443\u0436\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0430 &#8212; \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c \u043a\u0430\u043a \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442;<\/p>\n<\/li>\n<li>\n<p>\u0432\u0435\u0440\u0441\u0438\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0439 &#8212; \u043e\u0442\u043b\u043e\u0436\u0438\u0442\u044c \u0438 \u0434\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430;<\/p>\n<\/li>\n<li>\n<p>\u0432\u0435\u0440\u0441\u0438\u044f \u043c\u0435\u043d\u044c\u0448\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 &#8212; \u043d\u0435 \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430\u0437\u0430\u0434.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u0434\u0445\u043e\u0434 \u0445\u043e\u0440\u043e\u0448\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0434\u043b\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u043d\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f.<\/p>\n<h3>\u041f\u0430\u0440\u0442\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e \u0431\u0438\u0437\u043d\u0435\u0441-\u043a\u043b\u044e\u0447\u0443<\/h3>\n<p>\u0412\u0441\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0437\u0430\u043a\u0430\u0437\u0430 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432 \u043e\u0434\u043d\u0443 \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 queues \u043f\u043e \u0445\u0435\u0448\u0443 <code>order_id<\/code>, \u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b, \u0438\u043b\u0438 shard, \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043e\u0434\u0438\u043d \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0439 consumer. RabbitMQ \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e <a href=\"https:\/\/www.rabbitmq.com\/docs\/modulus-hash-exchange\" rel=\"noopener noreferrer nofollow\">modulus hash exchange<\/a> \u0438 Single Active Consumer. \u041f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u0437\u0430\u043a\u0430\u0437\u0430\u043c\u0438, \u043d\u043e \u0434\u043e\u043b\u0433\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0434\u043d\u043e\u0433\u043e \u0437\u0430\u043a\u0430\u0437\u0430 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u0430 \u0437\u0430\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432\u0435\u0441\u044c \u0435\u0433\u043e shard.<\/p>\n<h3>\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u044e<\/h3>\n<p>\u0412 Kafka \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 partition. Consumer \u043c\u043e\u0436\u0435\u0442 \u043d\u0435 \u043f\u0440\u043e\u0434\u0432\u0438\u0433\u0430\u0442\u044c offset, \u043f\u043e\u043a\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430. \u041f\u043e\u0440\u044f\u0434\u043e\u043a \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f, \u043d\u043e \u043e\u0434\u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 \u0432\u0441\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 partition. Retry topic \u0441\u043d\u0438\u043c\u0430\u0435\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u0438 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043d\u0430\u0440\u0443\u0448\u0430\u0435\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043f\u043e\u0440\u044f\u0434\u043e\u043a. \u0412\u044b\u0431\u043e\u0440 \u043c\u0435\u0436\u0434\u0443 latency \u0432\u0441\u0435\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430 \u0438 \u043f\u043e\u0440\u044f\u0434\u043a\u043e\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044f\u0432\u043d\u043e.<\/p>\n<p>\u041f\u0440\u0430\u0432\u0438\u043b\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0435: retry &#8212; \u044d\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u0440\u044f\u0434\u043a\u0430, \u043f\u043e\u043a\u0430 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043d\u0435 \u0434\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0435.<\/p>\n<h2>Backpressure: queue \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u043d\u0443\u044e \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c<\/h2>\n<p>Queue \u0445\u043e\u0440\u043e\u0448\u043e \u043f\u043e\u0433\u043b\u043e\u0449\u0430\u0435\u0442 \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 \u0432\u0441\u043f\u043b\u0435\u0441\u043a. \u0415\u0441\u043b\u0438 producer \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0451\u0442 10 000 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443, \u0430 consumers \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442 8 000, backlog \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0442\u0438 \u043d\u0430 2 000 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443. Broker \u043b\u0438\u0448\u044c \u043e\u0442\u0441\u0440\u043e\u0447\u0438\u0442 \u043c\u043e\u043c\u0435\u043d\u0442, \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u0441\u044f \u0434\u0438\u0441\u043a \u0438\u043b\u0438 \u043d\u0430\u0440\u0443\u0448\u0438\u0442\u0441\u044f \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438.<\/p>\n<p>\u041d\u0430\u0431\u043b\u044e\u0434\u0430\u0439\u0442\u0435 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u0438\u043d\u0443 queue. \u0421\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u043e 10 \u043c\u0438\u043d\u0443\u0442 \u0432\u0430\u0436\u043d\u0435\u0435 \u0434\u0435\u0441\u044f\u0442\u0438 \u0442\u044b\u0441\u044f\u0447 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, \u043f\u043e\u044f\u0432\u0438\u0432\u0448\u0438\u0445\u0441\u044f \u0441\u0435\u043a\u0443\u043d\u0434\u0443 \u043d\u0430\u0437\u0430\u0434. \u041f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u0438\u0433\u043d\u0430\u043b\u044b:<\/p>\n<ul>\n<li>\n<p>\u0432\u043e\u0437\u0440\u0430\u0441\u0442 \u0441\u0430\u043c\u043e\u0433\u043e \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p>\u0432\u0445\u043e\u0434\u044f\u0449\u0430\u044f \u0438 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u043c\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c;<\/p>\n<\/li>\n<li>\n<p>\u0447\u0438\u0441\u043b\u043e ready \u0438 unacked messages;<\/p>\n<\/li>\n<li>\n<p>\u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0434\u043e\u043b\u044f \u043e\u0448\u0438\u0431\u043e\u043a;<\/p>\n<\/li>\n<li>\n<p>\u0447\u0438\u0441\u043b\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 retry queue;<\/p>\n<\/li>\n<li>\n<p>\u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u043e\u0432 \u043d\u0430 \u043e\u0434\u043d\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435;<\/p>\n<\/li>\n<li>\n<p>\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f \u0432 parking lot;<\/p>\n<\/li>\n<li>\n<p>publisher confirm latency \u0438 unroutable returns;<\/p>\n<\/li>\n<li>\n<p>reconnect \u0438 consumer cancellations.<\/p>\n<\/li>\n<\/ul>\n<p>Prefetch \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0447\u0438\u0441\u043b\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u0440\u0430\u0431\u043e\u0442\u0435 \u0443 consumer. \u041e\u043d \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043d\u0438 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u043c, \u043d\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0440\u0430\u0432\u043d\u044b\u043c \u0447\u0438\u0441\u043b\u0443 goroutines. \u0414\u043b\u044f \u0442\u044f\u0436\u0451\u043b\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0440\u0430\u0437\u0443\u043c\u043d\u043e \u043d\u0430\u0447\u0430\u0442\u044c \u0441 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043e\u043a\u043e\u043b\u043e \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0446\u0438\u0438, \u0438\u0437\u043c\u0435\u0440\u0438\u0442\u044c throughput \u0438 \u043f\u0430\u043c\u044f\u0442\u044c, \u0430 \u0437\u0430\u0442\u0435\u043c \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0442\u044c.<\/p>\n<p>\u0410\u0432\u0442\u043e\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e \u0433\u043b\u0443\u0431\u0438\u043d\u0435 queue \u0431\u0435\u0437 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0442\u043e\u0436\u0435 \u043e\u043f\u0430\u0441\u043d\u043e. \u0415\u0441\u043b\u0438 downstream database \u0443\u0436\u0435 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0436\u0435\u043d\u0430, \u0437\u0430\u043f\u0443\u0441\u043a \u0435\u0449\u0451 \u0441\u0442\u0430 consumers \u0443\u0441\u043a\u043e\u0440\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0451 \u043f\u0430\u0434\u0435\u043d\u0438\u0435. \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0446\u0438\u0438, circuit breaker \u0434\u043b\u044f \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0438 rate limit \u0434\u043b\u044f \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0438\u0445 \u0447\u0430\u0441\u0442\u043e\u0442\u044b \u0438\u043d\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u0435\u0437\u043d\u0435\u0435, \u0447\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a \u043d\u043e\u0432\u043e\u0439 replica.<\/p>\n<p>\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u043d\u0443\u0436\u043d\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443. \u041f\u043e\u0441\u043b\u0435 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0442\u044b\u0441\u044f\u0447\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043c\u043e\u0433\u0443\u0442 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u0438\u0437 \u043e\u0434\u043d\u043e\u0439 TTL queue. \u041d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0443\u043f\u0435\u043d\u0435\u0439, jitter \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u0443\u0435\u043c\u044b\u0439 redrive \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u044e\u0442 \u0442\u0430\u043a\u043e\u0439 retry storm.<\/p>\n<h2>\u041a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0442\u043e\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u043b\u043e\u043c\u0430\u0442\u044c\u0441\u044f<\/h2>\n<p>Producer \u0438 consumer \u0440\u0430\u0437\u0432\u0451\u0440\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0435\u0440\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u043c\u0435\u0448\u0430\u043d\u043d\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438.<\/p>\n<p>\u041f\u043e\u043b\u0435\u0437\u043d\u044b\u0439 envelope \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"json\">{  \"id\": \"01K0ORDERCREATED\",  \"type\": \"order.created\",  \"schema_version\": 2,  \"occurred_at\": \"2026-07-21T09:00:00Z\",  \"producer\": \"orders\",  \"correlation_id\": \"01K0REQUEST\",  \"causation_id\": \"01K0COMMAND\",  \"aggregate\": {    \"type\": \"order\",    \"id\": \"42\",    \"version\": 7  },  \"data\": {    \"sku\": \"book-17\",    \"count\": 1  }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>id<\/code> \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442 \u0444\u0430\u043a\u0442 \u0438 \u043d\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u0435. <code>correlation_id<\/code> \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430. <code>causation_id<\/code> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u043a\u0430\u043a\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0432\u044b\u0437\u0432\u0430\u043b\u0438 \u044d\u0442\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435. \u0412\u0435\u0440\u0441\u0438\u044f \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0441 \u043f\u043e\u0440\u044f\u0434\u043a\u043e\u043c, \u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u0441\u0445\u0435\u043c\u044b &#8212; \u0441 \u044d\u0432\u043e\u043b\u044e\u0446\u0438\u0435\u0439 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430.<\/p>\n<p>\u0421\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043e\u0431\u044b\u0447\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u043b\u0435, \u0435\u0441\u043b\u0438 \u0441\u0442\u0430\u0440\u044b\u0435 consumers \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u044e\u0442 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0435 \u043f\u043e\u043b\u044f, \u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e. \u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044f, \u0441\u043c\u0435\u043d\u0430 \u0435\u0433\u043e \u0441\u043c\u044b\u0441\u043b\u0430 \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u0440\u043e\u0433\u043e event type \u043f\u043e\u0434 \u043d\u043e\u0432\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u043b\u043e\u043c\u0430\u044e\u0442 consumers. \u041f\u0440\u0438 \u043d\u0435\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0439 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0435\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e, \u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438 consumers \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0442\u0430\u0440\u0443\u044e.<\/p>\n<p>\u041d\u0435 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0439\u0442\u0435 \u043a\u0430\u0436\u0434\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 retry. \u041f\u043e\u043a\u0430 \u043a\u043e\u0434 \u043d\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u043b\u0441\u044f, \u0442\u0435 \u0436\u0435 \u0431\u0430\u0439\u0442\u044b \u043e\u0441\u0442\u0430\u043d\u0443\u0442\u0441\u044f \u0442\u0435\u043c\u0438 \u0436\u0435 \u0431\u0430\u0439\u0442\u0430\u043c\u0438. \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u043e\u043f\u0430\u0441\u0442\u044c \u0432 parking lot \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 \u0441\u0445\u0435\u043c\u044b \u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u0439 \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u043e\u0439.<\/p>\n<h2>\u041a\u0430\u043a \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0445\u0435\u043c\u0443 \u0441\u0431\u043e\u044f\u043c\u0438<\/h2>\n<p>Happy path \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e happy path. Retry topology \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0432 \u0442\u0435\u0445 \u043c\u0435\u0441\u0442\u0430\u0445, \u0440\u0430\u0434\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043e\u043d\u0430 \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c.<\/p>\n<h3>Consumer \u0443\u043f\u0430\u043b \u043f\u043e\u0441\u043b\u0435 COMMIT, \u043d\u043e \u0434\u043e Ack<\/h3>\n<p>\u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0442\u0435\u0441\u0442\u043e\u0432\u0443\u044e \u0442\u043e\u0447\u043a\u0443 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 <code>reserve<\/code> \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0447\u0435\u0440\u0435\u0437 <code>SIGKILL<\/code>. \u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 RabbitMQ \u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441\u043d\u043e\u0432\u0430. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>stock.reserved<\/code> \u0434\u043e\u043b\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c\u0441\u044f \u043e\u0434\u0438\u043d \u0440\u0430\u0437, \u0430 Inbox \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043e\u0434\u0438\u043d <code>message_id<\/code>.<\/p>\n<h3>PostgreSQL \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d<\/h3>\n<p>\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u0431\u0430\u0437\u0443 \u0434\u043e\u043b\u044c\u0448\u0435 \u043f\u043e\u043b\u043d\u043e\u0433\u043e retry budget. \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0439\u0442\u0438 <code>retry.5s<\/code>, <code>retry.30s<\/code> \u0438 <code>retry.5m<\/code>, \u0430 consumer \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0433\u043e\u0440\u044f\u0447\u0438\u0439 <code>requeue<\/code>-\u0446\u0438\u043a\u043b. \u0412 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u0431\u0430\u0437\u0443 \u0434\u043e \u0438\u0441\u0447\u0435\u0440\u043f\u0430\u043d\u0438\u044f \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u0438 \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e\u0441\u044c.<\/p>\n<h3>\u041f\u043e\u0432\u0440\u0435\u0436\u0434\u0451\u043d\u043d\u044b\u0439 JSON<\/h3>\n<p>\u041e\u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0439\u0442\u0435 <code>{not-json}<\/code> \u0441 \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u043c <code>MessageId<\/code>. \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u043f\u0430\u0441\u0442\u044c \u0432 <code>inventory.orders.parking<\/code>, \u0431\u0435\u0437 \u0442\u0440\u0451\u0445 \u0431\u0435\u0441\u0441\u043c\u044b\u0441\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u043f\u044b\u0442\u043e\u043a.<\/p>\n<h3>Retry \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d, \u043d\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 Ack \u043f\u043e\u0442\u0435\u0440\u044f\u043d<\/h3>\n<p>\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 consumer \u043f\u043e\u0441\u043b\u0435 publisher confirm \u0438 \u0434\u043e <code>delivery.Ack<\/code>. \u0412 \u0440\u0430\u0431\u043e\u0447\u0435\u0439 queue \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u0430 \u0432 retry queue \u0443\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u043f\u0438\u044f. \u041e\u0431\u0435 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043e\u0434\u043d\u043e\u043c\u0443 \u0440\u0435\u0437\u0435\u0440\u0432\u0443.<\/p>\n<h3>Binding \u0443\u0434\u0430\u043b\u0451\u043d<\/h3>\n<p>\u0423\u0434\u0430\u043b\u0438\u0442\u0435 binding retry exchange. \u041f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u0441 <code>mandatory=true<\/code> \u0434\u043e\u043b\u0436\u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c <code>basic.return<\/code>. Consumer \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435. \u0417\u0430\u043e\u0434\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435, \u0447\u0442\u043e supervisor \u043d\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 consumer \u0431\u0435\u0437 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u0438 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 reconnect storm.<\/p>\n<h3>\u041d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u0435 \u043f\u043e\u0440\u044f\u0434\u043a\u0430<\/h3>\n<p>\u0417\u0430\u0441\u0442\u0430\u0432\u044c\u0442\u0435 <code>v7<\/code> \u0443\u0439\u0442\u0438 \u0432 retry, \u0430 <code>v8<\/code> \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0439\u0442\u0435 \u0441\u0440\u0430\u0437\u0443. \u0422\u0435\u0441\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u0443\u044e \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0443: \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 shard, \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0438\u043b\u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0435 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0435\u0433\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f. \u0415\u0441\u043b\u0438 \u0442\u0435\u0441\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u00ab\u0438\u043d\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u00bb, \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 \u043f\u043e\u043a\u0430 \u043d\u0435\u0442.<\/p>\n<h3>Parking lot \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d<\/h3>\n<p>\u0423\u0434\u0430\u043b\u0438\u0442\u0435 binding \u0438\u043b\u0438 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 quorum \u0446\u0435\u043b\u0435\u0432\u043e\u0439 queue. \u041f\u0440\u0438 at-least-once dead lettering \u0438\u0441\u0445\u043e\u0434\u043d\u0430\u044f quorum queue \u0434\u043e\u043b\u0436\u043d\u0430 \u0443\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044e\u044e \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044e. \u0421\u043b\u0435\u0434\u0438\u0442\u0435 \u0437\u0430 \u0440\u043e\u0441\u0442\u043e\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 queue: \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439 DLX \u0441\u043f\u043e\u0441\u043e\u0431\u0435\u043d \u0441\u043e\u0437\u0434\u0430\u0442\u044c backpressure, \u0435\u0441\u043b\u0438 \u0446\u0435\u043b\u044c \u0434\u043e\u043b\u0433\u043e \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430.<\/p>\n<h2>\u041a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442 \u0442\u0435 \u0436\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 brokers<\/h2>\n<p>\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u043e\u0432 \u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f, \u043d\u043e \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f.<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">Broker<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u043e\u0432\u0442\u043e\u0440 \u0438 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435<\/p>\n<\/th>\n<th>\n<p align=\"left\">Poison message<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u043e\u0440\u044f\u0434\u043e\u043a \u0438 replay<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">RabbitMQ<\/p>\n<\/td>\n<td>\n<p align=\"left\">Manual <code>Ack\/Nack<\/code>, delayed retry \u0432 quorum queues 4.3 \u0438\u043b\u0438 retry queues \u0441 TTL \u0438 DLX<\/p>\n<\/td>\n<td>\n<p align=\"left\">Delivery limit \u0438 DLX, \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f parking queue<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u0440\u044f\u0434\u043e\u043a queue \u043e\u0441\u043b\u0430\u0431\u043b\u044f\u044e\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e consumers \u0438 retries; Streams \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0442 \u0434\u043b\u044f replay<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Kafka<\/p>\n<\/td>\n<td>\n<p align=\"left\">Consumer \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 offset; retry \u043e\u0431\u044b\u0447\u043d\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 partition \u0438\u043b\u0438 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044e \u0432 retry topic<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 dead-letter topic \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 framework<\/p>\n<\/td>\n<td>\n<p align=\"left\">Replay \u0432\u0441\u0442\u0440\u043e\u0435\u043d \u0432 \u043c\u043e\u0434\u0435\u043b\u044c log; \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043d\u0443\u0442\u0440\u0438 partition<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">NATS JetStream<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>AckWait<\/code>, <code>BackOff<\/code>, <code>NakWithDelay<\/code>, <code>MaxDeliver<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u0441\u043b\u0435 <code>MaxDeliver<\/code> \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0432 stream, advisory \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c DLQ<\/p>\n<\/td>\n<td>\n<p align=\"left\">Consumer \u0437\u0430\u0434\u0430\u0451\u0442 \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0432 stream; \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 consumer \u0438 subjects<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Amazon SQS<\/p>\n<\/td>\n<td>\n<p align=\"left\">Visibility timeout, \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0435\u0443\u0434\u0430\u043b\u0451\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432\u0438\u0434\u043d\u043e \u0441\u043d\u043e\u0432\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">Redrive policy \u0441 <code>maxReceiveCount<\/code> \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 DLQ<\/p>\n<\/td>\n<td>\n<p align=\"left\">Standard queue \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u044b \u0438 best-effort ordering; FIFO \u0443\u043f\u043e\u0440\u044f\u0434\u043e\u0447\u0438\u0432\u0430\u0435\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 <code>MessageGroupId<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>NATS JetStream \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0437\u0430\u0434\u0430\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c <code>BackOff<\/code> \u0438 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0434\u043e\u0441\u0442\u0430\u0432\u043e\u043a \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 consumer. \u041e\u0431\u044b\u0447\u043d\u044b\u0439 <code>Nak()<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0435\u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0443\u044e \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0443, \u0430 \u0434\u043b\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u043d\u0443\u0436\u0435\u043d <code>NakWithDelay()<\/code>. \u041f\u043e\u0441\u043b\u0435 <code>MaxDeliver<\/code> \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043d\u0435 \u0438\u0441\u0447\u0435\u0437\u0430\u0435\u0442 \u0438\u0437 stream; server \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u0442 advisory, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c DLQ. \u042d\u0442\u0438 \u0434\u0435\u0442\u0430\u043b\u0438 \u0441\u043e\u0431\u0440\u0430\u043d\u044b \u0432 <a href=\"https:\/\/docs.nats.io\/nats-concepts\/jetstream\/consumers\" rel=\"noopener noreferrer nofollow\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 JetStream consumers<\/a>.<\/p>\n<p>\u0412 Amazon SQS consumer \u043d\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 <code>Ack<\/code>, \u0430 \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435. \u0414\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u043e\u043d\u043e \u0441\u043a\u0440\u044b\u0442\u043e \u043d\u0430 \u0432\u0440\u0435\u043c\u044f visibility timeout. \u0415\u0441\u043b\u0438 timeout \u043a\u043e\u0440\u043e\u0447\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0432\u0442\u043e\u0440\u043e\u0439 consumer \u0441\u043f\u043e\u0441\u043e\u0431\u0435\u043d \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u0443 \u0436\u0435 \u0440\u0430\u0431\u043e\u0442\u0443; \u0435\u0441\u043b\u0438 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0434\u043b\u0438\u043d\u043d\u044b\u0439, \u043f\u043e\u0432\u0442\u043e\u0440 \u043f\u043e\u0441\u043b\u0435 \u043f\u0430\u0434\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f. AWS \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0434\u0447\u0451\u0440\u043a\u0438\u0432\u0430\u0435\u0442, \u0447\u0442\u043e <a href=\"https:\/\/docs.aws.amazon.com\/AWSSimpleQueueService\/latest\/SQSDeveloperGuide\/sqs-visibility-timeout.html\" rel=\"noopener noreferrer nofollow\">visibility timeout \u043d\u0435 \u043e\u0442\u043c\u0435\u043d\u044f\u0435\u0442 at-least-once delivery<\/a>. Redrive policy \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 DLQ \u043f\u043e\u0441\u043b\u0435 <code>maxReceiveCount<\/code>.<\/p>\n<p>Kafka \u0431\u043b\u0438\u0436\u0435 \u043a \u0436\u0443\u0440\u043d\u0430\u043b\u0443, \u0447\u0435\u043c \u043a \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0437\u0430\u0434\u0430\u043d\u0438\u0439. Consumer \u043c\u043e\u0436\u0435\u0442 \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u043a \u0441\u0442\u0430\u0440\u043e\u043c\u0443 offset \u0438 \u043f\u0435\u0440\u0435\u0438\u0433\u0440\u0430\u0442\u044c \u0438\u0441\u0442\u043e\u0440\u0438\u044e. \u042d\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u0434\u043b\u044f \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430, \u043d\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0434\u043e\u043b\u0433\u043e\u0432\u0435\u0447\u043d\u043e\u0439 \u0438\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u0438. \u0421\u043e\u0431\u044b\u0442\u0438\u044f \u0441 \u043e\u0434\u043d\u0438\u043c \u043a\u043b\u044e\u0447\u043e\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442 \u0432 \u043e\u0434\u043d\u0443 partition, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0445 \u043f\u043e\u0440\u044f\u0434\u043e\u043a. \u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u0432 retry topic, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443, \u043d\u043e \u0441\u0442\u0440\u043e\u0433\u0438\u0439 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043f\u043e \u043a\u043b\u044e\u0447\u0443 \u0438\u0441\u0447\u0435\u0437\u043d\u0435\u0442.<\/p>\n<p>\u0412\u044b\u0431\u043e\u0440 broker \u043c\u0435\u043d\u044f\u0435\u0442 \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430. \u041e\u043d \u043d\u0435 \u043e\u0442\u043c\u0435\u043d\u044f\u0435\u0442 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0435 ID, dual write, \u043d\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0433\u0440\u0430\u043d\u0438\u0446\u0443 \u0431\u0438\u0437\u043d\u0435\u0441-\u044d\u0444\u0444\u0435\u043a\u0442\u0430.<\/p>\n<h2>\u0418\u0442\u043e\u0433<\/h2>\n<p>\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u043a\u043e\u043c\u043c\u0443\u043d\u0438\u043a\u0430\u0446\u0438\u044f \u043d\u0435 \u0443\u0441\u0442\u0440\u0430\u043d\u044f\u0435\u0442 \u0441\u0431\u043e\u0438, \u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043c\u0435\u0436\u0434\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 \u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0439 \u0431\u0443\u0444\u0435\u0440 \u0438 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0440\u0435\u0430\u043a\u0446\u0438\u044e \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u0431\u043e\u0439. \u0417\u0430 \u044d\u0442\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u044f\u0432\u043d\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u043b\u0430\u0434\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c.<\/p>\n<p>\u041d\u0430\u0434\u0451\u0436\u043d\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0437\u0430\u0438\u0447\u043d\u043e:<\/p>\n<ul>\n<li>\n<p>producer \u043f\u0438\u0448\u0435\u0442 \u0431\u0438\u0437\u043d\u0435\u0441-\u0434\u0430\u043d\u043d\u044b\u0435 \u0438 Outbox \u043e\u0434\u043d\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0435\u0439;<\/p>\n<\/li>\n<li>\n<p>relay \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0441\u043e \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u043c ID \u0438 \u0436\u0434\u0451\u0442 confirm;<\/p>\n<\/li>\n<li>\n<p>consumer \u043c\u0435\u043d\u044f\u0435\u0442 \u0441\u0432\u043e\u044e \u0431\u0430\u0437\u0443 \u0438 Inbox \u043e\u0434\u043d\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0435\u0439;<\/p>\n<\/li>\n<li>\n<p><code>Ack<\/code> \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 <code>COMMIT<\/code>;<\/p>\n<\/li>\n<li>\n<p>\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u044e\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u044b \u0441 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u043e\u0439;<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u0432 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u044b\u0439 parking lot;<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0437\u0430\u0434\u0430\u0451\u0442\u0441\u044f \u043f\u043e \u0431\u0438\u0437\u043d\u0435\u0441-\u043a\u043b\u044e\u0447\u0443, \u0430 \u043d\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0438\u0437 \u0441\u043b\u043e\u0432\u0430 FIFO;<\/p>\n<\/li>\n<li>\n<p>backlog, \u0432\u043e\u0437\u0440\u0430\u0441\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 redrive \u0438\u043c\u0435\u044e\u0442 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<\/ul>\n<p>Broker \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0432\u0430\u0436\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0443\u0442\u0438. \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u043d\u0430\u0434\u0451\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0437 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430 \u043c\u0435\u0436\u0434\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c, broker \u0438 \u0431\u0430\u0437\u043e\u0439. \u041e\u0431\u044b\u0447\u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u043e\u0434\u043d\u0430 \u044d\u0444\u0444\u0435\u043a\u0442\u043d\u0430\u044f \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u044f, \u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043a\u0443\u0447\u043d\u044b\u0445 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u0430\u0432\u0438\u043b. \u0412 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445 \u0441\u043a\u0443\u0447\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0438\u043c\u0435\u044e\u0442 \u043f\u0440\u0438\u044f\u0442\u043d\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e: \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c.<\/p>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1062002\/\">https:\/\/habr.com\/ru\/articles\/1062002\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c \u043e\u0431\u044b\u0447\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0437\u0430\u043a\u0430\u0437\u0430. \u0421\u0435\u0440\u0432\u0438\u0441 \u0437\u0430\u043a\u0430\u0437\u043e\u0432 \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 order.created. \u0421\u0435\u0440\u0432\u0438\u0441 \u0441\u043a\u043b\u0430\u0434\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0435\u0433\u043e \u0438 \u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u0443\u0435\u0442 \u0442\u043e\u0432\u0430\u0440 \u0432 PostgreSQL. \u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c RabbitMQ \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 (Ack), \u0447\u0442\u043e\u0431\u044b broker \u0443\u0434\u0430\u043b\u0438\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438\u0437 queue.\u041d\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043c\u043e\u0436\u0435\u0442 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 PostgreSQL \u0438 \u0434\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 Ack. RabbitMQ \u043d\u0435 \u0437\u043d\u0430\u0435\u0442, \u0443\u0441\u043f\u0435\u043b \u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441 \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0432\u0430\u0440. Broker \u0432\u0438\u0434\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0451\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0433\u043e \u0435\u0449\u0451 \u0440\u0430\u0437. \u0421 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u044d\u0442\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435. \u0421 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0431\u0438\u0437\u043d\u0435\u0441\u0430 \u043e\u0434\u0438\u043d \u0437\u0430\u043a\u0430\u0437 \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0432\u0430\u0440 \u0434\u0432\u0430\u0436\u0434\u044b.\u0414\u0440\u0443\u0433\u043e\u0439 \u0441\u0431\u043e\u0439 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0440\u0430\u043d\u044c\u0448\u0435: PostgreSQL \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d, \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u0447\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443. \u0415\u0441\u043b\u0438 \u0441\u0440\u0430\u0437\u0443 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 queue \u0447\u0435\u0440\u0435\u0437 \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 Nack(requeue=true), RabbitMQ \u043f\u043e\u0447\u0442\u0438 \u043d\u0435\u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442 \u0435\u0433\u043e \u0441\u043d\u043e\u0432\u0430. \u041f\u043e\u043a\u0430 \u0431\u0430\u0437\u0430 \u043d\u0435 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0430\u0441\u044c, \u0432\u0441\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c\u0438. \u041d\u0443\u0436\u043d\u044b \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0447\u0438\u0441\u043b\u0430 \u043f\u043e\u0432\u0442\u043e\u0440\u043e\u0432. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u043f\u0435\u0440\u0451\u0434 \u0431\u043e\u043b\u0435\u0435 \u043d\u043e\u0432\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0440\u0435\u0448\u0438\u0442\u044c \u0432\u043e\u043f\u0440\u043e\u0441 \u043f\u043e\u0440\u044f\u0434\u043a\u0430.\u0422\u0430\u043a \u043e\u0434\u043d\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 \u0443\u0447\u0430\u0441\u0442\u043a\u043e\u0432: \u0437\u0430\u043f\u0438\u0441\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f, \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0432 broker, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435. \u041c\u0435\u0436\u0434\u0443 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u043c\u0438 \u0443\u0447\u0430\u0441\u0442\u043a\u0430\u043c\u0438 \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u043c\u043e\u043c\u0435\u043d\u0442\u044b, \u043a\u043e\u0433\u0434\u0430 \u043e\u0434\u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0430 \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u0430 \u0434\u0440\u0443\u0433\u0430\u044f \u0435\u0449\u0451 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435.\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u044d\u0442\u0438 \u043c\u043e\u043c\u0435\u043d\u0442\u044b \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u043f\u0443\u0442\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f. \u0417\u0430\u0442\u0435\u043c \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043c \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0441\u0445\u0435\u043c\u0443 \u0434\u043b\u044f RabbitMQ \u0438 Go: \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u044b \u0447\u0435\u0440\u0435\u0437 retry queues, \u0432\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f (TTL) \u0438 dead letter exchange, \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u044b\u043c \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c, \u043a\u0443\u0434\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438. \u0412 \u043a\u043e\u043d\u0446\u0435 \u0441\u0440\u0430\u0432\u043d\u0438\u043c \u044d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434 \u0441 Kafka, NATS JetStream \u0438 Amazon SQS.\u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u0432\u044b\u0432\u043e\u0434: \u043d\u0430\u0434\u0451\u0436\u043d\u043e\u0441\u0442\u044c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u043a\u043e\u043c\u043c\u0443\u043d\u0438\u043a\u0430\u0446\u0438\u0438 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043d\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u043e\u0432, \u0430 \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0441\u0431\u043e\u0435. Producer \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0442\u0435\u0440\u044f\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u0435, \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c \u0431\u0438\u0437\u043d\u0435\u0441-\u044d\u0444\u0444\u0435\u043a\u0442, \u0430 retry \u0432\u0441\u0435\u0433\u0434\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u043c\u0435\u0442\u044c \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443, \u043f\u0440\u0435\u0434\u0435\u043b \u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442.\u0413\u0434\u0435 \u043b\u043e\u043c\u0430\u0435\u0442\u0441\u044f \u043f\u0443\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0443\u0442\u044c order.created:orders DB -&gt; outbox -&gt; publisher -&gt; exchange -&gt; queue -&gt; consumer -&gt; inventory DB                              |                    |                         confirm\/return          Ack\/Nack\u041d\u0430 \u044d\u0442\u043e\u043c \u043f\u0443\u0442\u0438 \u043d\u0435\u0442 \u043e\u0434\u043d\u043e\u0433\u043e \u043e\u0431\u0449\u0435\u0433\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f. \u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0444\u0430\u043a\u0442\u043e\u0432:PostgreSQL \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u043b \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e \u0437\u0430\u043a\u0430\u0437\u0430.RabbitMQ \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u043b, \u0447\u0442\u043e \u043f\u0440\u0438\u043d\u044f\u043b \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044e.Exchange \u043d\u0430\u0448\u0451\u043b \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0443\u044e queue.Consumer \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u043b \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0443 \u0447\u0435\u0440\u0435\u0437 Ack.PostgreSQL \u0441\u043a\u043b\u0430\u0434\u0430 \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043b \u0440\u0435\u0437\u0435\u0440\u0432.\u0421\u0431\u043e\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u0435\u043d \u043c\u0435\u0436\u0434\u0443 \u043b\u044e\u0431\u044b\u043c\u0438 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u043c\u0438 \u043f\u0443\u043d\u043a\u0442\u0430\u043c\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u043b\u0435\u0437\u043d\u0435\u0435 \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043d\u0435 \u00ab\u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u043b\u0438 RabbitMQ \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0443\u00bb, \u0430 \u00ab\u043a\u0442\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u0432\u043b\u0430\u0434\u0435\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c \u0438 \u043a\u0430\u043a\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c\u00bb.\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u041a\u0430\u043a \u043f\u0440\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f\u0427\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442Dual write\u0417\u0430\u043a\u0430\u0437 \u0437\u0430\u043f\u0438\u0441\u0430\u043d, \u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043d\u0435 \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u043e, \u0438\u043b\u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442Transactional Outbox\u041d\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438Broker \u043f\u0440\u0438\u043d\u044f\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043d\u043e confirm \u043f\u043e\u0442\u0435\u0440\u044f\u043b\u0441\u044f\u041f\u043e\u0432\u0442\u043e\u0440 \u0441 \u0442\u0435\u043c \u0436\u0435 message_id, \u0438\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u044b\u0439 consumer\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0430Consumer \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0438 \u0443\u043f\u0430\u043b \u0434\u043e AckInbox \u0438\u043b\u0438 \u0438\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u0430\u044f \u0431\u0438\u0437\u043d\u0435\u0441-\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u0413\u043e\u0440\u044f\u0447\u0438\u0439 \u0446\u0438\u043a\u043b \u043f\u043e\u0432\u0442\u043e\u0440\u043e\u0432\u041d\u0435\u0438\u0441\u043f\u0440\u0430\u0432\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 queue\u0417\u0430\u0434\u0435\u0440\u0436\u043a\u0430, backoff, \u043b\u0438\u043c\u0438\u0442 \u043f\u043e\u043f\u044b\u0442\u043e\u043aPoison message\u041f\u043e\u0432\u0442\u043e\u0440 \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442: JSON \u043f\u043e\u0432\u0440\u0435\u0436\u0434\u0451\u043d \u0438\u043b\u0438 \u0441\u0445\u0435\u043c\u0430 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430Parking lot, \u0438\u043b\u0438 dead letter queue (DLQ), \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430 \u0438 \u0440\u0443\u0447\u043d\u043e\u0439 redrive &#8212; \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u043f\u043e\u0441\u043b\u0435 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u041d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u0435 \u043f\u043e\u0440\u044f\u0434\u043a\u0430\u0411\u043e\u043b\u0435\u0435 \u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043e \u0440\u0430\u043d\u044c\u0448\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u043c\u043e\u0433\u043e \u0441\u0442\u0430\u0440\u043e\u0433\u043e\u041f\u0430\u0440\u0442\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e \u043a\u043b\u044e\u0447\u0443, \u0432\u0435\u0440\u0441\u0438\u044f \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430, \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430\u041f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u043a\u0430 consumerQueue \u0438 \u0432\u043e\u0437\u0440\u0430\u0441\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0440\u0430\u0441\u0442\u0443\u0442 \u0431\u044b\u0441\u0442\u0440\u0435\u0435, \u0447\u0435\u043c \u0441\u0435\u0440\u0432\u0438\u0441 \u0443\u0441\u043f\u0435\u0432\u0430\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044cPrefetch, \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0446\u0438\u0438, backpressure, \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u041d\u0435\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0421\u0442\u0430\u0440\u044b\u0439 consumer \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u0435 \u0438\u043b\u0438 \u0441\u043c\u044b\u0441\u043b \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0412\u0435\u0440\u0441\u0438\u044f \u0441\u0445\u0435\u043c\u044b, \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u0430\u044f \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u044f\u041f\u043e\u0442\u0435\u0440\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430\u041d\u0435\u043b\u044c\u0437\u044f \u0441\u0432\u044f\u0437\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c \u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u043c\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0430\u043c\u0438\u0421\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0439 ID, correlation ID, trace context, \u043c\u0435\u0442\u0440\u0438\u043a\u0438\u041e\u0434\u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 broker \u043d\u0435 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0432\u0441\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, quorum queue \u0437\u0430\u0449\u0438\u0449\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 RabbitMQ, \u043d\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 \u043e \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 PostgreSQL \u0432\u043d\u0443\u0442\u0440\u0438 consumer.At most once, at least once \u0438 exactly once\u0423 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0435\u0441\u0442\u044c \u0442\u0440\u0438 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f.At most once, \u0438\u043b\u0438 \u043d\u0435 \u0431\u043e\u043b\u0435\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u0430. Consumer \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043b\u0438\u0431\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c Ack. \u041f\u043e\u0432\u0442\u043e\u0440\u043e\u0432 \u043d\u0435\u0442, \u043d\u043e \u043f\u0440\u0438 \u043f\u0430\u0434\u0435\u043d\u0438\u0438 consumer \u0440\u0430\u0431\u043e\u0442\u0430 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0435\u0440\u044f\u0442\u044c\u0441\u044f.At least once, \u0438\u043b\u0438 \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u043e\u0434\u0438\u043d \u0440\u0430\u0437. Consumer \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 Ack. \u0420\u0430\u0431\u043e\u0442\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u043f\u043e\u0442\u0435\u0440\u044f\u0442\u044c\u0441\u044f, \u0437\u0430\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0439\u0442\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e.Exactly once, \u0438\u043b\u0438 \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437. \u0422\u0435\u0440\u043c\u0438\u043d \u043f\u043e\u043b\u0435\u0437\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0433\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0438. Kafka \u0443\u043c\u0435\u0435\u0442 \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438 consumer offset \u0432 Kafka-\u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0447\u0438\u0442\u0430\u0435\u0442 \u0438\u0437 Kafka \u0438 \u043f\u0438\u0448\u0435\u0442 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 Kafka. \u041d\u043e \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u0443\u044e \u0431\u0430\u0437\u0443 \u0438\u043b\u0438 \u0432\u044b\u0437\u043e\u0432 \u043f\u043b\u0430\u0442\u0451\u0436\u043d\u043e\u0433\u043e API \u0441\u043d\u043e\u0432\u0430 \u0441\u043e\u0437\u0434\u0430\u044e\u0442 \u0432\u043d\u0435\u0448\u043d\u044e\u044e \u0433\u0440\u0430\u043d\u0438\u0446\u0443. \u042d\u0442\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u044f\u043c\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 Kafka \u043e delivery semantics.RabbitMQ \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442 publisher confirms \u0438 consumer acknowledgements \u0441 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435\u0439 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0437\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435. \u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430\u0434\u0451\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e\u0439 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e broker, producer \u0438 consumer. \u042d\u0442\u0438 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u043d\u0435 \u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u0443\u044e \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e \u0441 \u0431\u0430\u0437\u043e\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.\u041d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0440\u0430\u0431\u043e\u0447\u0430\u044f \u0446\u0435\u043b\u044c \u0437\u0432\u0443\u0447\u0438\u0442 \u0442\u0430\u043a:at least once delivery + idempotent business effect\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437, \u043d\u043e \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u044b\u0439 \u0431\u0438\u0437\u043d\u0435\u0441-\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f \u043e\u0434\u0438\u043d \u0440\u0430\u0437. \u0412\u0430\u0436\u043d\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435. \u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0441 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u043c\u0438 ID \u043d\u0435 \u043f\u043e\u043c\u043e\u0436\u0435\u0442, \u0435\u0441\u043b\u0438 consumer \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u0432\u0430\u0436\u0434\u044b \u0432\u044b\u0437\u043e\u0432\u0435\u0442 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 API, \u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443.\u041f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 dual write\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0441\u0435\u0440\u0432\u0438\u0441 \u0437\u0430\u043a\u0430\u0437\u043e\u0432 \u0434\u0435\u043b\u0430\u0435\u0442 \u0434\u0432\u0435 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438:if err := orders.Insert(ctx, order); err != nil {return err}if err := publisher.Publish(ctx, orderCreated); err != nil {return err}\u041c\u0435\u0436\u0434\u0443 \u0432\u044b\u0437\u043e\u0432\u0430\u043c\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043c\u043e\u0436\u0435\u0442 \u0443\u043f\u0430\u0441\u0442\u044c. \u041f\u0435\u0440\u0435\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0441\u0442\u0440\u043e\u043a \u043d\u0435 \u0440\u0435\u0448\u0430\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443: \u0442\u043e\u0433\u0434\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e \u0443\u0439\u0442\u0438 \u0434\u043e \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u043a\u0430\u0437\u0430.Transactional Outbox \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0432 \u0442\u0443 \u0436\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e, \u0433\u0434\u0435 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u0437\u0430\u043a\u0430\u0437:BEGIN;INSERT INTO orders (id, status)VALUES (&#8217;42&#8217;, &#8216;created&#8217;);INSERT INTO outbox (id, event_type, payload, created_at)VALUES (    &#8217;01K0ORDERCREATED&#8217;,    &#8216;order.created&#8217;,    &#8216;{&#171;order_id&#187;:&#187;42&#8243;}&#8217;,    now());COMMIT;\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 relay \u0447\u0438\u0442\u0430\u0435\u0442 outbox, \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0438 \u043f\u043e\u0441\u043b\u0435 publisher confirm \u043e\u0442\u043c\u0435\u0447\u0430\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439. \u0415\u0441\u043b\u0438 relay \u0443\u043f\u0430\u0434\u0451\u0442 \u043f\u043e\u0441\u043b\u0435 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438, \u043d\u043e \u0434\u043e \u043e\u0442\u043c\u0435\u0442\u043a\u0438 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435, \u043e\u043d \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 ID \u0441\u043e\u0437\u0434\u0430\u044e\u0442 \u043f\u0440\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 outbox \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442 \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u043f\u043e\u0432\u0442\u043e\u0440\u0435. \u041d\u043e\u0432\u044b\u0439 ID \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b \u0431\u044b \u0442\u043e\u0442 \u0436\u0435 \u0444\u0430\u043a\u0442 \u0432 \u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0438 \u0441\u0434\u0435\u043b\u0430\u043b \u0434\u0435\u0434\u0443\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u044e \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0439.Publisher confirm \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442, \u0447\u0442\u043e RabbitMQ \u043f\u0440\u0438\u043d\u044f\u043b \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0437\u0430 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044e. \u0414\u043b\u044f persistent-\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043f\u043e\u043f\u0430\u0432\u0448\u0435\u0433\u043e \u0432 durable queue, \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435. Quorum queue \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044e \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u043d\u044f\u043b\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0440\u0435\u043f\u043b\u0438\u043a. \u0415\u0441\u043b\u0438 exchange \u043d\u0430\u043f\u0440\u0430\u0432\u0438\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e queues, confirm \u043f\u0440\u0438\u0434\u0451\u0442 \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0435\u0433\u043e \u043f\u0440\u0438\u043c\u0443\u0442 \u0432\u0441\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 queues. \u041d\u043e \u043f\u043e\u0442\u0435\u0440\u044f\u043d\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 \u0441\u043d\u043e\u0432\u0430 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 producer \u0432 \u043d\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0441\u0442\u0438: broker \u043c\u043e\u0433 \u043f\u0440\u0438\u043d\u044f\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u0430 confirm \u043c\u043e\u0433 \u043d\u0435 \u0434\u043e\u0439\u0442\u0438. RabbitMQ \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0451\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u0431\u044b\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u043c \u043a \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u0430\u043c.\u0415\u0441\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u043d\u0430 \u0434\u0435\u0442\u0430\u043b\u044c. Confirm \u043d\u0435 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e exchange \u043d\u0430\u0448\u0451\u043b queue. \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0431\u0435\u0437 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430, \u0438\u043b\u0438 unroutable message, RabbitMQ \u0442\u043e\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c. \u0414\u043b\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 producer \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u0442 \u0441 mandatory=true \u0438 \u0447\u0438\u0442\u0430\u0435\u0442 basic.return. \u0415\u0441\u043b\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u0447\u0438\u043a\u043e\u0432 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e \u043f\u043e \u0441\u043c\u044b\u0441\u043b\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u043f\u043e\u0442\u0435\u0440\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u043e\u0439.\u041a\u043e\u0433\u0434\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c AckConsumer \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c Ack \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441\u0442\u0430\u043b\u043e \u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u043c \u043a \u043f\u0430\u0434\u0435\u043d\u0438\u044e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430. \u0414\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 PostgreSQL \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u0439 COMMIT.\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0447\u0435\u0442\u044b\u0440\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430:\u041c\u043e\u043c\u0435\u043d\u0442 \u043f\u0430\u0434\u0435\u043d\u0438\u044f\u0427\u0442\u043e \u0443\u0432\u0438\u0434\u0438\u0442 RabbitMQ\u0427\u0442\u043e \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u0434\u0435\u043b\u0430\u0442\u044c consumer \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0414\u043e \u043d\u0430\u0447\u0430\u043b\u0430 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438Ack \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d, \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432\u0435\u0440\u043d\u0451\u0442\u0441\u044f\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438\u0422\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u043e\u0442\u043a\u0430\u0442\u0438\u0442\u0441\u044f, \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432\u0435\u0440\u043d\u0451\u0442\u0441\u044f\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443\u041f\u043e\u0441\u043b\u0435 COMMIT, \u0434\u043e Ack\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432\u0435\u0440\u043d\u0451\u0442\u0441\u044f, \u0445\u043e\u0442\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0443\u0436\u0435 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u0420\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0442\u044c \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442 \u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043c\u0435\u043d\u044f\u0442\u044c\u041f\u043e\u0441\u043b\u0435 AckRabbitMQ \u0443\u0434\u0430\u043b\u0438\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0443\u0436\u0435 \u043e\u0431\u044f\u0437\u0430\u043d \u0431\u044b\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 Ack \u0441\u0434\u0432\u0438\u0433\u0430\u0435\u0442 \u0433\u0440\u0430\u043d\u0438\u0446\u0443 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0440\u0430\u043d\u043e. Ack \u0434\u043e COMMIT \u0434\u0435\u043b\u0430\u0435\u0442 \u043e\u043a\u043d\u043e \u043f\u043e\u0442\u0435\u0440\u0438. Ack \u043f\u043e\u0441\u043b\u0435 COMMIT \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u043a\u043d\u043e \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u0442\u044c \u0438\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c\u044e.\u0424\u043b\u0430\u0433 Redelivered \u043f\u043e\u043b\u0435\u0437\u0435\u043d \u0434\u043b\u044f \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0438, \u043d\u043e \u043d\u0435 \u0434\u043b\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u0438. \u041e\u043d \u0433\u043e\u0432\u043e\u0440\u0438\u0442, \u0447\u0442\u043e RabbitMQ \u0443\u0436\u0435 \u043f\u044b\u0442\u0430\u043b\u0441\u044f \u0432\u044b\u0434\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u0430 \u043d\u0435 \u0447\u0442\u043e \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 consumer \u0443\u0441\u043f\u0435\u043b \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435. Consumer \u043c\u043e\u0436\u0435\u0442 \u0432\u043f\u0435\u0440\u0432\u044b\u0435 \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 Redelivered=true, \u0435\u0441\u043b\u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0430 \u043d\u0435 \u0434\u043e\u0448\u043b\u0430 \u0434\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0434 \u0440\u0430\u0437\u0440\u044b\u0432\u043e\u043c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f. RabbitMQ \u043f\u0440\u044f\u043c\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u044d\u0442\u043e\u0442 \u0444\u043b\u0430\u0433 \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u043e\u0439, \u0430 \u043d\u0435 \u0434\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b.\u0418\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u044b\u0439 consumer \u0447\u0435\u0440\u0435\u0437 Inbox\u0418\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u0430\u0451\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u0438 \u043e\u0434\u043d\u043e\u043c \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u0430\u0445. \u041f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u043d\u0438\u0435 status = &#8216;paid&#8217; \u0447\u0430\u0441\u0442\u043e \u0438\u0434\u0435\u043c\u043f\u043e\u0442\u0435\u043d\u0442\u043d\u043e. \u041a\u043e\u043c\u0430\u043d\u0434\u0430 balance = balance &#8212; 100 \u0438\u043b\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u043f\u0438\u0441\u044c\u043c\u0430 &#8212; \u043d\u0435\u0442.\u0414\u043b\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0443\u0434\u043e\u0431\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Inbox. Consumer \u0445\u0440\u0430\u043d\u0438\u0442 ID \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0432 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0431\u0430\u0437\u0435. \u0423\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0432\u0445\u043e\u0434\u044f\u0442 \u0432 \u043e\u0434\u043d\u0443 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e:CREATE TABLE processed_messages (    consumer_name text        NOT NULL,    message_id    text        NOT NULL,    processed_at  timestamptz NOT NULL DEFAULT now(),    PRIMARY KEY (consumer_name, message_id));\u041d\u0438\u0436\u0435 \u0443\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u043e\u0432\u0430\u0440\u0430. \u0415\u0441\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0443\u0436\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043e \u044d\u0442\u0438\u043c consumer, INSERT &#8230; ON CONFLICT \u043d\u0435 \u0432\u0435\u0440\u043d\u0451\u0442 \u0441\u0442\u0440\u043e\u043a\u0443 \u0438 \u043f\u043e\u0432\u0442\u043e\u0440 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f \u0431\u0435\u0437 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0440\u0435\u0437\u0435\u0440\u0432\u0430.type OrderCreated struct {OrderID string `json:&#187;order_id&#187;`SKU     string `json:&#187;sku&#187;`Count   int    `json:&#187;count&#187;`}func reserve(ctx context.Context,db *sql.DB,messageID string,event OrderCreated,) error {tx, err := db.BeginTx(ctx, nil)if err != nil {return fmt.Errorf(&#171;begin transaction: %w&#187;, err)}defer func() {\/\/ \u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e Commit \u0432\u0435\u0440\u043d\u0451\u0442\u0441\u044f sql.ErrTxDone._ = tx.Rollback()}()var inserted interr = tx.QueryRowContext(ctx, `INSERT INTO processed_messages (consumer_name, message_id)VALUES (&#8216;inventory.reserve&#8217;, $1)ON CONFLICT DO NOTHINGRETURNING 1`,&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-488251","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/488251","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=488251"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/488251\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=488251"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=488251"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=488251"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}