惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Secure Thoughts
V
Visual Studio Blog
C
Check Point Blog
S
SegmentFault 最新的问题
GbyAI
GbyAI
WordPress大学
WordPress大学
Microsoft Security Blog
Microsoft Security Blog
S
Schneier on Security
The Cloudflare Blog
Microsoft Azure Blog
Microsoft Azure Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园_首页
Know Your Adversary
Know Your Adversary
The Hacker News
The Hacker News
Engineering at Meta
Engineering at Meta
Project Zero
Project Zero
U
Unit 42
小众软件
小众软件
Simon Willison's Weblog
Simon Willison's Weblog
Stack Overflow Blog
Stack Overflow Blog
P
Palo Alto Networks Blog
云风的 BLOG
云风的 BLOG
B
Blog
人人都是产品经理
人人都是产品经理
P
Proofpoint News Feed
A
About on SuperTechFans
Scott Helme
Scott Helme
C
Cyber Attacks, Cyber Crime and Cyber Security
宝玉的分享
宝玉的分享
E
Exploit-DB.com RSS Feed
L
Lohrmann on Cybersecurity
S
Security @ Cisco Blogs
C
CXSECURITY Database RSS Feed - CXSecurity.com
I
InfoQ
IT之家
IT之家
S
Securelist
Hacker News: Ask HN
Hacker News: Ask HN
博客园 - 叶小钗
MyScale Blog
MyScale Blog
博客园 - 聂微东
罗磊的独立博客
H
Heimdal Security Blog
T
Tor Project blog
Security Latest
Security Latest
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
G
GRAHAM CLULEY
O
OpenAI News
博客园 - Franky
T
Threat Research - Cisco Blogs
C
Cybersecurity and Infrastructure Security Agency CISA

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Простой API, умный сервер: третий класс брокеров, который пропускают между Kafka и RabbitMQ
Андрей Серебрянский · 2026-06-15 · via Все публикации подряд на Хабре

Привет, Хабр! Меня зовут Андрей Серебрянский. Раньше я строил платформы потоковой обработки данных в банках, а теперь вместе с командой разрабатываю YDB Topics и YMQ. После своих докладов на конференциях мы с коллегами по индустрии часто обсуждаем брокеры сообщений. И меня, как разработчика таких решений, огорчает упрощённый подход: «RabbitMQ не нужен, всё можно собрать на Kafka».

Вспоминая известную шутку: да, с помощью буханки бородинского и двух спиц можно собрать модель троллейбуса. Но зачем? Да, я люблю Kafka и с удовольствием про неё рассказываю на Хабре и Хайлоаде. Но, кроме Kafka и RabbitMQ, есть и третий класс брокеров сообщений: SQS-совместимые очереди в облачных платформах (и не только), которые для многих продакшн-задач подходят лучше, чем Kafka.

Опытные разработчики, проводя system design interview, любят спрашивать друг друга о разнице между брокерами сообщений. А мне каждый раз хочется ответить: «Зависит от контекста». В статье под катом я начну с такого контекста: напомню, для чего изначально создавались SQS, RabbitMQ, Kafka. После этого расскажу про принцип «простой API, умный сервер» и про задачи, которые в эпоху микросервисов решаются с помощью брокеров. А в завершение — про реализацию SQS, над которой сейчас работаю: Yandex Message Queue.

Кто и зачем разработал SQS, RabbitMQ и Kafka

RabbitMQ, а позднее Kafka не возникли на пустом месте. В начале 2000-х разрабатываемый софт становился всё сложнее, заказчики хотели отказоустойчивости, и разработчики раз за разом переизобретали то, что мы сейчас называем микросервисной архитектурой. Софт разделялся на части-сервисы, которые обменивались сообщениями. Эти сообщения надёжно сохранялись, и в случае отказа одного из сервисов можно было продолжить работу с того места, где она была прервана.

Транзакционные СУБД тех лет, такие как PostgreSQL и MySQL, не очень подходили на роль брокеров сообщений. В первую очередь потому, что не было простого и эффективного способа уведомлять клиентов о поступлении новых сообщений. Крупные компании, такие как IBM или Microsoft, предоставляли свои закрытые решения для работы с сообщениями и старались привязать пользователей к своим протоколам.

RabbitMQ

Релиз RabbitMQ в 2007 году стал ответом на молчаливое недовольство разработчиков сложившейся ситуацией. Брокер сообщений использовал push-модель: клиенты устанавливали долгоживущие TCP-подключения к серверу RabbitMQ, подписывались на очереди сообщений и получали нужные сообщения быстро и с минимальной нагрузкой на инфраструктуру.

Кроме непосредственно доставки сообщений, RabbitMQ из коробки решал множество сопутствующих задач — всё то, что раньше предлагали проприетарные платформы или приходилось разрабатывать самому: маршрутизацию сообщений, их надёжное хранение и кеширование в памяти, гарантии доставки at least once и многое другое. Брокер хорошо решал задачи равномерного распределения сообщений по большому количеству подписчиков и удаления полученных сообщений.

Kafka

Разработчики Kafka из компании LinkedIn делали огромную социальную сеть. Они решали ту же задачу надёжного хранения промежуточного состояния в виде сообщений, но не так, как это сделали разработчики RabbitMQ, пришедшие из мира телекома и финтеха (привет, Erlang). Авторам Kafka нужно было не просто надёжно передавать сообщения между сервисами. Большая часть сообщений в их системе была информацией о действиях пользователей: кликах, просмотре страниц, показе рекламы.

Брокер сообщений, который разрабатывали в LinkedIn, создавался для решения их специфических проблем:

  • Линейное горизонтальное масштабирование: тысячи сервисов писали и читали миллиарды сообщений, брокер должен был эффективно справляться с такой нагрузкой.

  • Длительное хранение сообщений: у сервиса должна была быть возможность подключиться к брокеру и прочитать все накопленные сообщения, даже если серверы брокера и сервиса в процессе такого чтения несколько раз перезагрузились.

Kafka и RabbitMQ решали одну и ту же задачу — хранение сообщений. Но их подход к её решению отражал специфику компаний, которые стояли за двумя продуктами. RabbitMQ предлагал инструменты для удобного общения микросервисов с помощью сообщений, включая такую популярную задачу, как равномерное и быстрое распределение сообщений по подписчикам. Для разработчиков Kafka равномерность и скорость получения сообщений были не очень важны. Гораздо важнее им был масштаб и возможность отказоустойчиво вычитывать миллионы и миллиарды сообщений в строгом порядке.

Simple Queue Service

Сервис Simple Queue Service был представлен Amazon в 2004 году. Он был одним из проприетарных решений, альтернативой которым позднее стали RabbitMQ и Kafka. Но, в отличие от других брокеров сообщений тех лет, SQS позиционировался как эластичное решение, способное масштабироваться под нагрузкой вместе с количеством серверов.

Слово Simple в названии сервиса тоже выбрали не просто так: для полноценной работы с сообщениями достаточно было всего трёх методов API — отправки, получения и удаления сообщений.

Сейчас сервисом SQS пользуются десятки тысяч компаний. Простота API позволила ему повторить успех S3 и стать стандартным протоколом, который предлагают многие облачные провайдеры. Сервис очередей Yandex Message Queue (YMQ) в Yandex Cloud предлагает SQS-совместимый интерфейс, который можно использовать с популярными библиотеками, такими как boto3, Spring Cloud AWS или Celery.

Проводя аналогию, можно сказать, что разные брокеры сообщений отвечают на разные вопросы. RabbitMQ отвечает на вопрос, как роутить сообщения, Kafka — как масштабироваться по нагрузке и хранению исторических данных. А SQS-совместимые очереди показывают, как вообще не думать над ответами на предыдущие два вопроса. Выбор брокера зависит от того, какие вопросы стоят перед командой в первую очередь.

Кто кого?

Выступая на конференциях и рассказывая про Apache Kafka, я часто слышал в кулуарах утверждение, что для подавляющего большинства применений Kafka полностью заменяет RabbitMQ и SQS, за исключением нишевых историй вроде IoT, где важна скорость доставки индивидуальных сообщений. Сторонники Kafka утверждают, что надёжный лог сообщений — это фундамент, поверх которого можно собрать всё что угодно. А вот длительное хранение сообщений и неограниченное горизонтальное масштабирование поверх RabbitMQ не собрать, потому что архитектура брокера не рассчитана на такое использование.

Мне трудно согласиться с таким мнением. С одной стороны — да, гости конференций часто рассказывают, что используют transport-agnostic-фреймворки вроде FastStream, которым всё равно, какой брокер сообщений выступает в роли транспорта. С другой стороны, можно копнуть глубже и поговорить с разработчиками из бигтеха, где раз за разом в разговорах будут подниматься задачи, для решения которых коллеги не хотят использовать Kafka, а предпочитают именно очереди сообщений. В некоторых случаях даже не RabbitMQ, а именно легковесные SQS API.

Почему простые очереди называют умными

SQS-совместимые очереди, разработкой которых я сейчас занимаюсь, придерживаются принципа «простой API — умный сервер». Всё масштабирование спрятано под капотом, и программистам не нужно самим разрабатывать архитектуру работы с партициями, оффсетами и группами консьюмеров. Для большинства прикладных задач достаточно всего трёх методов: SendMessage, ReceiveMessage и DeleteMessage.

Такой подход отличает SQS (и RabbitMQ) от Kafka, которая в качестве очереди сообщений популярна во многом из-за хорошего масштабирования on-premises. Но ценой масштабирования становится необходимость собирать всю нужную функциональность поверх низкоуровневого распределённого лога.

Какая функциональность нужна при разработке продакшн-решений? Вот краткий список того, что обычно предоставляют SQS-совместимые очереди:

  • Дедупликация по идентификатору и содержимому, чтобы не нужно было реализовывать логику доставки exactly once на стороне приложения. Серверы SQS в облаке имеют низкоуровневый доступ к хранению и передаче сообщений, так что дедупликацию можно сделать максимально эффективной.

  • FIFO-очереди гарантируют обработку сообщений в рамках ключа в том порядке, в котором они были добавлены в очередь. Если порядок доставки не важен, то можно использовать стандартные очереди, которые обеспечивают максимальную пропускную способность.

  • DLQ-очереди для необработанных сообщений. Такие очереди используются для обработки ошибок без остановки читающих процессов.

  • Отложенная доставка позволяет отложить действие на время. Например, можно отложить проверку статуса операции.

  • Квоты и лимиты также играют важную роль в построении отказоустойчивых решений. С их помощью собираются механизмы плавной деградации, когда при возрастании нагрузки менее важные сервисы отключаются, чтобы ядро системы продолжало функционировать.

  • Настройки безопасности, интегрированные с системой авторизации облака, позволяют разделить управление доступами и полезный код разрабатываемых приложений.

Часть этих фич реализована и в прикладных фреймворках, например в FastStream или Dramatiq. Современные фреймворки умеют использовать дополнительные функции SQS-совместимых API, чтобы минимизировать нагрузку на процессор, память и сеть. Это ощутимая разница в RPS для высоконагруженных систем и сильный довод в пользу SQS-решений при выборе брокера сообщений.

Конечно, у таких очередей есть объективные минусы: необходимость использовать облако, меньше контроля над низкоуровневыми настройками и масштабированием. При экстремальных нагрузках Kafka покажет лучшие результаты по производительности (пока что лучшие, в будущем я вернусь к этому вопросу на страницах Хабра). Главное преимущество SQS-совместимых очередей, как его вижу я, — в скорости вывода продукта на рынок. Давайте посмотрим, как философия «простого API и умного сервера» всё больше и больше влияет на разрабатываемые нами системы по мере роста сложности решаемых задач.

Фоновая обработка

Степень влияния очередей на архитектуру зависит от того, сколько команда готова инвестировать в разработку. Если добавить очередь сообщений для фоновой обработки задач, то это почти никак не повлияет на архитектуру. Использование очереди для сглаживания пиков нагрузки потребует переработки того, как некоторые сервисы взаимодействуют друг с другом. Ну и, наконец, в случае асинхронной коммуникации микросервисов очереди становятся фундаментом архитектуры и начинают диктовать архитектурные решения.

Чтобы встретиться с необходимостью сохранять промежуточное состояние сервиса, не нужно работать в бигтехе и разрабатывать хайлоад-решения с сотнями тысяч RPS. Достаточно пет-проекта веб-сервиса с любой длительной операцией: например, генерацией текста, изображения или видео с помощью нейросети.

Если спросить начинающего Python-разработчика, как сделать такой сервис, то даже выпускник трёхмесячных курсов «войти в айти» расскажет о типовом решении:

  • Использовать любой веб-фреймворк, например Django (или что модно в этом сезоне).

  • Использовать фреймворк для фоновой обработки задачи — например, проверенный временем Celery. Или более современные альтернативы: Dramatiq и FastStream.

  • Использовать какой-нибудь транспорт, который поддерживает фреймворк фоновой обработки, — RabbitMQ, Redis, SQS.

Celery и Dramatiq из коробки позволяют использовать в роли транспорта для хранения сообщений RabbitMQ, Redis, SQS. Почему не Kafka? Потому что для такой задачи возможность равномерно распределять сообщения по подписчикам гораздо важнее, чем надёжное хранение терабайтов данных.

За неограниченное линейное масштабирование Kafka платит архитектурными ограничениями. Чтобы два сервиса не прочитали одно и то же сообщение, партицию в Kafka одновременно может читать только один консьюмер (подписчик). Сделать равномерное распределение сообщений по подписчикам в такой архитектуре можно, но сложно. А ещё сложнее сделать эластичное масштабирование по нагрузке, так как Kafka накладывает ограничения на изменение количества партиций (об этом я уже рассказывал на Хайлоаде).

Эластичное масштабирование — вторая важная причина того, что для фоновой обработки задач очереди сообщений предпочтительнее, чем лог. При росте нагрузки облако запускает больше серверов, при этом очередь сообщений не становится бутылочным горлышком и масштабируется пропорционально возрастающему количеству отправляемых сообщений.

На сайте Yandex Cloud есть статья, посвящённая обработке фоновых задач с помощью YMQ. В коде приложения вся работа с очередью занимает несколько строк использования boto3 SDK, а для выполнения фоновых задач используются serverless-функции, запускающие ffmpeg для конвертации видео.

Для фоновой обработки задач очередь сообщений выполняет роль инструмента, который можно просто использовать, ничего не меняя в архитектуре сервиса.

Для чего ещё нужно равномерное распределение задач, кроме как для фоновой конвертации видео или генерации картинок с помощью нейросетей?

Сглаживание пиков нагрузки

Перейдём от пет-проектов на Django к хайлоад-решениям бигтеха. Архитектура, основанная на микросервисах в эластичном облаке, обещала раз и навсегда решить проблемы масштабирования при изменении нагрузки. На бумаге всё выглядит просто:

  • Приложение разделено на сервисы, которые вызывают друг друга по HTTP API.

  • Если какой-то сервис становится бутылочным горлышком, то облако выделяет под его процессы больше серверов. А когда нагрузка падает, то лишние серверы удаляются.

  • Profit. Что может пойти не так?

Главной проблемой такой архитектуры стало время создания и старта серверов (или подов — в более поздних версиях, основанных на Kubernetes). Теоретически микросервисная архитектура подразумевает, что сервисы легковесные, написаны на Go, стартуют за пару секунд и потребляют мало памяти. Но на практике создание, поддержка и тестирование таких сервисов обходились очень дорого.

Большинство решений, которые я видел в бигтехе, не построены из идеальных сервисов. Они собраны из каких-то сервисов. Иногда больших. Нередко — с техническим долгом. Некоторые из сервисов могут требовать сотни гигабайт памяти. И стартовать по несколько минут.

Чтобы масштабировать по нагрузке прожорливые и медленно стартующие сервисы, облако должно иметь запас времени. Если в час пик нагрузка на приложение увеличивается в несколько раз, то нужно держать избыточное количество подов, чтобы при резком росте нагрузки успеть запустить нужное количество. Для многих компаний такой оверкоммит ресурсов неприемлем.

Как выглядит отказ приложения под нагрузкой со стороны кода и сетевой инфраструктуры?

  • Один из сервисов перестаёт справляться с нагрузкой.

  • Входящие HTTP- или gRPC-запросы копятся в очереди этого сервиса. Если другие сервисы делают HTTP-запросы к этому сервису, то они вынуждены ждать, и в их очередях также начинают копиться неотвеченные запросы. Это называется обратным давлением, или back pressure.

  • Балансировщики нагрузки не дожидаются ответа от сервисов и начинают отправлять клиентам сообщения о тайм-аутах, приложение перестаёт быть доступно.

С помощью очередей можно сгладить пики нагрузки, не резервируя избыточное количество серверов. Так же как в случае с фоновой обработкой задач, очереди можно использовать как эластичный буфер между сервисами, которые отвечают мгновенно, и сервисами, которые могут стать бутылочным горлышком при росте нагрузки.

Как выглядит архитектура сглаживания пиков нагрузки с помощью очереди сообщений:

  • Клиент отправляет HTTP-запрос приложению.

  • Балансировщик нагрузки отправляет запрос на один из подов сервиса, отвечающего за клиентские запросы.

  • Сервисы, которые могут ответить на запрос мгновенно, всё ещё делают HTTP-запросы друг к другу.

  • Если какой-то запрос долго обрабатывается, то вместо HTTP-запроса в очередь помещается сообщение о новой задаче, а отправивший такое сообщение сервис сразу же возвращает 200 ОK.

  • Клиент показывает прогресс выполнения и через некоторое время снова делает запрос к приложению, чтобы получить результат или продолжить ожидание.

Для сглаживания пиков нагрузки используются как очереди сообщений, такие как RabbitMQ и SQS, так и платформы потоковой обработки данных, такие как Kafka. При коммуникации микросервисов равномерность распределения нагрузки уже не так важна, а Kafka хорошо масштабируется в on-premises. Поэтому выбор зависит от контекста и личных предпочтений команды разработки.

На сайте Yandex Cloud есть ещё одна статья, в которой мы рассказываем про автоматическое масштабирование группы виртуальных машин для обработки сообщений из очереди Message Queue. Использование очереди сообщений вместо HTTP-запросов позволяет переложить back pressure на клиента и дать сервисам время на масштабирование без риска каскадных отказов.

Использование очереди в качестве буфера между сервисами уже требует изменений в архитектуре. Истории про «распиливание монолита на (микро)сервисы», о которых мы часто слышим на конференциях, — как раз про такие проекты, когда приложение разделяется на быстрые и медленные части с очередями сообщений между ними.

Для чего ещё, кроме сглаживания пиков нагрузки, могут использоваться очереди сообщений?

Асинхронная коммуникация микросервисов

Если приложение использует HTTP-вызовы для коммуникации между сервисами, то даже при использовании очередей фоновой обработки задач возможна ситуация каскадного отказа, когда с нагрузкой перестают справляться сервисы, которые должны отвечать на запросы быстро.

С каскадным отказом микросервисов можно бороться разными способами, но я разрабатываю очереди, поэтому хочу рассказать об их применении. Оно достаточно самоочевидно: очереди можно использовать не точечно для длительных операций, а в качестве слоя коммуникации для всех сервисов приложения.

Из описанных в статье подходов асинхронная коммуникация микросервисов — самый дорогой в разработке. Фоновую обработку можно добавить даже в старое монолитное приложение. Сглаживание пиков нагрузки с помощью очередей можно добавить почти в любое приложение с сервисной архитектурой, даже если сервисы совсем не микро. Полноценная асинхронная коммуникация между всеми сервисами требует другой архитектуры. Юмористическое видео о сложности таких систем не просто так собрало почти четыре миллиона просмотров.

Одно из преимуществ микросервисной архитектуры с очередями в качестве слоя коммуникации — возможность переживать каскадные отказы за счёт отключения или игнорирования части функциональности. Принципы отказоустойчивого снижения функциональности (graceful degradation) можно закладывать на этапе дизайна архитектуры прямо в логику обмена сообщениями между сервисами.

Общаясь на конференциях с коллегами, я всё больше слышу о разработке агентских систем с искусственным интеллектом. Из-за использования больших языковых моделей нормой становится длительное время ответа на запрос, и большинство архитектур, о которых я знаю, используют SQS-совместимые очереди сообщений или аналоги Kafka в качестве транспортного слоя.

Для асинхронной коммуникации микросервисов очереди становятся фундаментом архитектуры и определяют то, как сервисы связаны между собой. И чем больше архитектура полагается на очереди, тем важнее ассортимент дополнительных функций, которые может предложить умный сервер очередей.

Чем больше приложение полагается на очереди сообщений, тем дороже самостоятельно реализовывать всю нужную дополнительную функциональность: DLQ, FIFO, дедупликацию, отложенную доставку и всё то, что я перечислял в начале статьи. Для простой фоновой обработки задач без этих функций можно обойтись, но уже для сглаживания пиков нагрузки они будут необходимы, а для большого решения на базе микросервисов качество этих функций будет определять архитектуру и то, как мы пишем код.

Yandex Message Queue в Yandex Cloud

С помощью SQS-совместимых очередей сообщений можно разрабатывать отказоустойчивые и масштабируемые сервисы без сложной логики поверх Kafka или настройки кластера RabbitMQ.

Не буду повторять плюсы и минусы облачных решений, вы и так их знаете. Но из своего опыта разработки хочу особо подчеркнуть два аспекта, которые с большим интересом обсуждают коллеги в кулуарах конференций.

Во-первых, это интегрированные механизмы масштабирования. В облаке под нагрузкой масштабируется не только изначально спроектированная под облако очередь сообщений, но и всё остальное: сервисы приложения, СУБД, cloud functions. А во-вторых, это serverless-сценарий использования с оплатой только использованных ресурсов. Если нужно поддерживать много изолированных друг от друга очередей сообщений, то serverless-решение в облаке экономичнее и проще в поддержке, чем изолированные установки Kafka или RabbitMQ.

Что же отвечать на system design interview?

Если на system design interview вас спросят, что лучше: RabbitMQ, Kafka или SQS, то не стесняйтесь фразы: «Зависит от контекста». И задайте встречный вопрос: а зачем вам нужна очередь?

  • Если вам нужна фоновая обработка задач или сглаживание пиков нагрузки и есть возможность использовать облачные решения, то хорошим выбором будет SQS-совместимая очередь.

  • Для огромных объёмов (миллиардов событий), сбора телеметрии, поставки в DWH Kafka будет решением по умолчанию, которое специально создавалось для этих задач.

  • Ну и, наконец, для сложной маршрутизации сообщений on-premises без необходимости масштабирования хорошо подойдёт RabbitMQ.

Всё, о чём я здесь рассказывал, можно уже сейчас использовать в Yandex Cloud. Команда разработки YMQ и YDB общается с пользователями в Telegram и на Хабре. Пишите комментарии к этой статье, мне, как одному из разработчиков YMQ, будет интересно поговорить с теми, кто использует очереди сообщений в своих проектах.