Yandex Message Queue: де ламається асинхронна обробка
Під навантаженням асинхронна обробка ламається не в черзі, а до неї. Поки сервіс оформлення замовлення синхронними викликами смикає платежі, склад і надсилання листів, час відповіді складається з усіх учасників — найповільніший із них задає спільний таймаут.
У пікові години потік заявок зростає в рази, виклики починають відвалюватися за таймаутом, і заявка зникає на середині ланцюжка.
Далі починається ручний «догін»: оператор звіряє журнали операцій, шукає заявки без підтвердження і заводить їх повторно. Чим вищий трафік, тим більше розбіжностей між системами — частина задач втрачена, частина оброблена двічі. Кожна така ітерація — це години інженерного часу і підірвана довіра клієнта.
Черга повідомлень на кшталт Yandex Message Queue розриває цей зв'язок: відправник публікує задачу і одразу відповідає клієнту, а отримувачі розбирають її у своєму темпі.
Надійна доставка повідомлень тримається на підтвердженнях — якщо обробник упав, необроблене повідомлення повертається в чергу, а не зникає. Додатково налаштовуємо повторні спроби, відкладений розбір збійних повідомлень і захист від дублів, щоб повтор не створював другу заявку.
Таймаути пікового трафіку перестають бути втратою заявок — вони перетворюються на затримку в секунди. Нижче розбираємо, як це закривається на практиці.
Що дає розв'язка сервісів і як її вимірювати
Коли обробник викликається синхронно, час відповіді сервісу дорівнює часу найповільнішого кроку, а його падіння стає падінням усього сервісу. Черга в Yandex Message Queue ставить між ними буфер, і далі кожен ефект розв'язки рахується в цифрах.
Буферизація піків
Черга приймає повідомлення швидше, ніж обробник їх розбирає, тому сплеск у рази вищий за звичайний трафік гаситься накопиченням, а не відмовою. Частка задач, відхилених через перевантаження, падає до нуля, а вхідний сервіс тримає попередній час відповіді.
Ізоляція збою обробника
Помилка в споживачі більше не валить приймання: повідомлення залишаються в черзі, а сервіс на вході продовжує відповідати. Час відновлення зводиться до перезапуску обробника — недоставлені задачі не втрачаються і не потребують ручного відтворення.
Повторні спроби доставки
Кількість спроб і пауза між ними задаються явно, після вичерпання повідомлення йде в чергу необроблених. Збій на розборі одного типу повідомлень не призводить до їхнього зникнення: частка втрачених задач видна в метриках і залишається керованою.
Незалежне масштабування обробників
Кількість споживачів змінюється окремо від вхідного сервісу: при зростанні довжини черги обробники додаються, при спорожненні знімаються. Розбір прискорюється пропорційно навантаженню, при цьому вхідний сервіс не перезбирається і не перевипускається.
Стандартні та впорядковані черги: що вибрати
Режим доставки в Yandex Message Queue вибирають не за звичкою, а за схемою потоків.
Якщо події незалежні і споживачі обробляють їх у будь-якому порядку, порядок нав'язувати не потрібно: паралельні обробники забирають стільки повідомлень, скільки встигають, і пропускна здатність зростає разом з їхньою кількістю — достатньо додати споживачів у групу.
Там, де порядок є частиною логіки (переходи статусів, нарахування по одному об'єкту), потрібна впорядкована черга.
Вона тримає послідовність усередині групи повідомлень зі спільним ключем, але за це платять пропускною здатністю: усередині групи повідомлення йдуть строго одне за одним, а кількість груп і швидкість обробки в кожній обмежені.
| Варіант | Коли підходить | Обмеження |
|---|---|---|
| Стандартна черга | Незалежні події: розсилки, журнали, фонові завдання, порядок обробки не важливий | Порядок не гарантований, можливі повтори доставки — обробник має бути ідемпотентним |
| Впорядкована з ключем групи | Порядок важливий усередині об'єкта: статуси замовлення, операції по одному рахунку | Порядок лише в межах групи, обмеження на кількість груп і швидкість у кожній |
| Впорядкована з одним потоком | Строга послідовність по всьому потоку при невеликому обсязі | Низька пропускна здатність, обробники не масштабуються горизонтально |
Вибір починається з розрахунку: скільки повідомлень за секунду, скільки незалежних ключів, що станеться при повторній обробці. Якщо ключів багато і вони не перетинаються, впорядкований режим дає майже ту саму пропускну здатність, що й стандартний. Якщо ключ один або повтори нешкідливі — беремо стандартну чергу і додаємо обробників.
Етапи налаштування: від схеми потоків до приймання
Роботи йдуть фіксованими етапами, і кожен закінчується артефактом, який можна перевірити до переходу до наступного — конфігурацією, схемою або протоколом перевірки. Збій на будь-якому кроці видно до того, як він потрапить у продуктивний контур.
- Аудит обміну даними. Збираємо виробників і споживачів повідомлень, поточні способи передачі, обсяги та пікові профілі. Окремо фіксуємо місця, де повідомлення втрачаються або обробляються двічі.
- Схема потоків повідомлень. Проєктуємо маршрути: яка подія в яку чергу йде, що відбувається при помилці обробника, де важливий порядок доставки. Схема узгоджується до початку налаштування.
- Налаштування черг і прав. Заводимо черги Yandex Message Queue під кожен потік, задаємо термін видимості повідомлення, час зберігання і чергу недоставлених. Доступи роздаємо сервісним обліковим записам за мінімально необхідним набором.
- Перевірка під навантаженням. Проганяємо профіль, близький до пікового: дивимося зростання глибини черги, частку повторних обробок і поведінку системи при зупинці одного зі споживачів.
- Спостережуваність і алерти. Налаштовуємо метрики глибини черги, затримки доставки і кількості помилок, виставляємо пороги сповіщень, щоб деградація ловилася раніше за скарги користувачів.
- Передача в експлуатацію. Віддаємо конфігурацію, регламент реакції на інциденти та інструкції з додавання нових потоків; за потреби чергуємо на перших релізах.
Конфігурації, схеми та регламенти: що передаємо на руки
Передаємо не скриншоти налаштувань, а комплект артефактів щодо Yandex Message Queue: за ним черга піднімається в новому середовищі, а інцидент розбирається без дзвінка автору.
Усе зберігається в репозиторії поруч із кодом — зміни проходять рев'ю і потрапляють у середовище тим самим шляхом, що й реліз сервісу.
- Конфігурація черг — описи черг і підписок: тип черги, період зберігання повідомлень, вікно невидимості, розмір пакета, таймаути. Значення виведені з профілю навантаження, а не виставлені на око.
- Схема потоків даних — постачальник, споживач, маршрут результату, точки повторної обробки. Позначені місця, де потік може дублюватися, і як споживач це переносить.
- Політики доступу та ролі — які сервісні облікові записи пишуть і читають, що саме їм дозволено, де ключі з обмеженим терміном життя. Права розведені за мінімумом.
- Обробка збійних повідомлень — правила повторних спроб, поріг переведення в чергу збійних повідомлень, порядок розбору і повернення в потік після виправлення.
- Метрики й оповіщення — сигнали про накопичення черги, зростання частки повторів і відмову споживача, з порогами, при яких черговий отримує сповіщення.
- Регламент експлуатації — що перевіряє чергова зміна, як правити конфігурацію без втрати повідомлень, як відкотити зміну і що робити при відмові споживача.
Розбір упровадження: піковий потік заявок без втрат
Що було до перебудови
Заявки приймав синхронний сервіс: форма віддавала запит прямо в обробник, і відповідь клієнту залежала від того, чи встиг той відпрацювати.
Поки потік рівний, вузьке місце обробки не проявлялося — але в дні акцій і розсилок кількість заявок підскакувала в рази, обробник не встигав, а частина запитів губилася ще на вході: користувач бачив помилку і не повторював надсилання.
У пікові дні частка втрачених заявок сягала 3–4%, і розбирали їх вручну — вивантажували журнали і дописували пропущене.
Що перебудували
Між прийманням і обробкою поставили чергу на базі Yandex Cloud. Приймач лише фіксує заявку і підтверджує приймання, а обробники забирають повідомлення у своєму темпі.
Підтвердження йде в чергу лише після успішного завершення: якщо обробник упав, повідомлення повернеться і буде оброблене повторно. Для заявок, які не проходять за кілька спроб, завели окрему чергу розбору, щоб збійне повідомлення не блокувало решту. Обробники масштабуються за довжиною черги, а ключ заявки захищає від дублів.
Що стало
Частка втрачених заявок пішла в нуль у межах вікна повторної доставки: запит не «згорає», навіть якщо сервіс перезапускається в найбільший пік. Накопичений потік задач, який раніше розбирали майже повний робочий день, тепер іде за хвилини.
Ручних втручань стало помітно менше — замість нічних чергувань на розбір пропусків залишилися поодинокі повідомлення з черги розбору.
Що робити, якщо обмін між сервісами вже працює напряму
Прямий виклик сервісу працює, поки відмова отримувача видна одразу: постачальник тримає з'єднання і повторює запит. Та сама властивість перетворює перевантаження однієї ділянки на відмову всього ланцюжка.
Черга розриває зв'язок: повідомлення прийнято і зберігається, поки отримувач не буде готовий його обробити.
Переходити на асинхронний обмін цілком за один раз не потрібно. У Yandex Cloud першими переводять ділянки, де відповідь не потрібна в тій самій сесії: події, сповіщення, вивантаження, перерахунок довідників. Запити, від яких залежить інтерфейс користувача, залишаються прямими.
| Ділянка | Схема | При відмові отримувача |
|---|---|---|
| Події, сповіщення, вивантаження | Черга | Повідомлення залишається в черзі до відновлення |
| Запити для інтерфейсу | Прямий виклик | Постачальник бачить помилку і віддає її користувачу |
| Пакетний перерахунок, звіти | Черга | Задача не втрачається, строки зсуваються |
| Операції з однократною обробкою | Черга з підтвердженням | Повторна доставка гаситься ключем операції |
Дві схеми одночасно живуть завдяки маршрутизації за типом операції: постачальник вирішує, куди надіслати виклик, і розвилка описана в конфігурації, а не розмазана по коду.
Для черги задаються повторні спроби, відкладена доставка і черга необроблених повідомлень — прямий виклик цього не дає взагалі.
Починати зручно з одного сервісу-отримувача й однієї групи споживачів — тоді видно реальну глибину черги і час обробки. Відкат дешевий: перемикач на боці постачальника повертає прямий виклик, стара гілка працює до кінця перехідного періоду.
Обмеження, квоти й типові помилки асинхронної обробки
Черга не безкінечна: є межа за кількістю повідомлень і обсягом, а в кожного повідомлення — час утримання, після якого воно видаляється незалежно від того, чи обробив його споживач.
Занадто коротке утримання — повідомлення зникають на середині задачі, і події не доходять до споживача. При сплеску навантаження черга впирається в межу, публікація відхиляється — дані втрачаються ще на вході.
Друга помилка — розрахунок на однократну доставку. Yandex Message Queue тримає гарантію «як мінімум один раз»: при перезапуску споживача або перевищенні вікна видимості повідомлення приходить повторно.
Без ідемпотентної обробки це дає дублі операцій — подвійні списання, повторні листи, розбіжні лічильники.
Вікно видимості — ключовий компроміс: коротке породжує дублі, довге — застряглі задачі, які не переобробляються годинами.
Найгірше, коли за чергою не стежать: контроль глибини і віку найстарішого повідомлення показує, що споживачі не встигають або падають, задовго до скарг користувачів.
І окрема черга для повідомлень, не оброблених після кількох спроб, — інакше вони зациклюються або зникають безслідно.
Як відрізнити переповнення через невірний час утримання від звичайної нестачі споживачів?
Зіставте час утримання з фактичною тривалістю обробки за метриками і подивіться на вік найстарішого повідомлення: якщо він малий, а черга зростає — споживачі не встигають, потрібні нові обробники.
Якщо повідомлення зникають, не дочекавшись обробки, — утримання виставлене занадто коротко. Його беруть із запасом на пікову тривалість задачі, а «хвости» відводять в окрему чергу необроблених.
Обговоримо задачу: з чого почнемо і що потрібно від вас
Для постановки задачі не потрібен багатотомний документ — достатньо опису потоків, прикладів повідомлень і вимог до надійності. За ними вже видно, який режим черги підходить, скільки споживачів тримати і де потрібні повтори.
- Опис потоків даних: хто публікує повідомлення, хто читає, що вважається успішною обробкою і куди йде результат.
- Приклади повідомлень: структура тіла, розмір, частота і пікові години — за ними рахуємо пропускну здатність черги.
- Вимоги до порядку: чи важлива послідовність усередині групи чи обробка незалежна.
- Вимоги до надійності: допустима затримка доставки, розумна кількість повторів і правила розбору збійних повідомлень.







