Налаштування Google Cloud Pub/Sub: dead-letter, IAM, моніторинг для DevOps

Загублені події в потоці коштують дорожче, ніж здається: розрахунки розходяться, а розбиратися доводиться вручну. Ми налаштовуємо Google Pub/Sub під ключ — проєктуємо підписки та повтори, розмежовуємо доступи й підключаємо моніторинг. Ви отримуєте схему потоків і регламенти, за якими контур працює передбачувано.
Часті запитання

Чому Google Pub/Sub втрачає повідомлення при піковому навантаженні

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

Перше вузьке місце — переповнення підписки. При піковому навантаженні публікація обганяє обробку: непідтверджені повідомлення та повтори накопичуються, лічильник очікуваних зростає, і обробник отримує більше, ніж здатен прийняти. Повідомлення не лежать у черзі вічно — хвіст сплеску витісняється раніше, ніж до нього дійде черга.

Друге — тайм-аут підтвердження. Обробник забирає повідомлення, йде у зовнішній виклик або важкий запит і не встигає підтвердити його у відведене вікно.

Сервіс вважає доставку невдалою і надсилає копію: зростають дублі та лічильник доставок, а за відсутності політики повторів повідомлення потрапляє в чергу недоставлених або стирається мовчки.

Третій сценарій — «залиплі» обробники: процес живий, метрики в нормі, але підтвердження не надсилається — втрачено контекст, потік заблоковано, контейнер іде в перезапуск.

Повідомлення ходить по колу, поки не сплине строк зберігання, і губиться рівно там, де потрібна була діагностика.

Усі три сценарії сходяться в одній точці — конфігурація підписки, недоставлених повідомлень і прав доступу до них. Розбираємо, де саме рветься потік і як це закривається.

Вимірний ефект: менше втрат, дублів і простоїв

Налаштування підписки змінює те, що видно в метриках. До нього збій обробника виглядає як тиша: повідомлення доставлено, підтверджено, обробник упав — і події немає ні в системі, ні в черзі.

Після налаштування все, що не пройшло обробку за задану кількість спроб, потрапляє в dead-letter: вони залишаються в черзі розбору, а не зникають.

Дублі — друга стаття втрат. Продовжене вікно підтвердження разом з ідемпотентністю за ключем події прибирають повторну обробку там, де вона не потрібна, а залишкові повтори стають безпечними: повторна доставка не створює другого запису і не проводить друге списання. Обсяг повторної обробки падає, бо частина збоїв закривається на боці підписки.

Третій ефект — час відновлення. Інцидент виявляється не за зверненням клієнта, а за алертом на вік найстарішого непідтвердженого повідомлення і на зростання dead-letter: черговий бачить проблему на початку, а не в кінці. Повернення в роботу — перемикання підписки на резервний обробник, це хвилини, а не години.

Зникає цілий клас інцидентів: «тиха втрата події», «подвійна обробка», «черга зростала добу, і ніхто не помітив».

Спостережуваність потоку будується на трьох сигналах — вік непідтверджених повідомлень, кількість доставок на повідомлення, обсяг dead-letter — і кожен прив’язаний до конкретної дії чергового.

Працюємо в інфраструктурі Google Cloud Pub/Sub: правила повторів, права доступу та пороги алертів задаються декларативно і версіонуються разом з кодом сервісу.

Режими Google Pub/Sub: підписки, підтвердження, повтори

У Google Pub/Sub режим доставки здається деталлю, поки потік один.

Щойно споживачів стає кілька, він задає, які збої ви отримаєте: виштовхувальна підписка приходить на вашу адресу і вимагає швидкої відповіді, витягувальна — забирає повідомлення сама, тому темп, розмір пакета і вікно обробки підбираються під навантаження.

Окремо вирішуються порядок і підтвердження. Ключ упорядкування прив’язує повідомлення до однієї черги — порядок тримається всередині ключа, але паралелізм падає.

Підтвердження обробки продовжує вікно: не встиг споживач — повідомлення повернеться в доставку, а після заданої кількості спроб піде в чергу недоставлених.

Варіант Коли підходить Обмеження
Витягувальна підписка власні сервіси, пакетна вибірка, високий темп потрібен цикл опитування і власна логіка підтверджень
Виштовхувальна підписка події в зовнішні сервіси, функції без постійного споживача потрібна доступна адреса і швидка відповідь, вікном підтвердження не керуєте
Потокова обробка безперервний потік з мінімальною затримкою постійне з’єднання, складніше призупинити і відкотити
Кілька підписників один потік на різні команди і сценарії політики повторів і недоставлених у кожної свої, дублі гасить ідемпотентність
Ключ упорядкування важливий порядок усередині однієї сутності менше паралелізму, гарячий ключ стає вузьким місцем

Режим доставки визначає клас відмов, який ви потім розбираєте на чергуванні. Нижче — як пов’язуємо підписки, права і моніторинг в одну керовану схему.

Порядок впровадження: від аудиту потоків до передачі регламентів

Порядок робіт будуємо так, щоб кожен крок закінчувався перевірюваним артефактом — схемою, конфігурацією або звітом про перевірку.

Починаємо не з налаштувань, а з аудиту потоків: помилку в схемі обміну повідомленнями простіше зловити на папері, ніж у проді під піковим навантаженням.

  1. Аудит потоків. Інвентаризація топіків і підписок Pub/Sub: хто публікує, хто читає, яка затримка допустима, де помилки не спливають у метриках.
  2. Проєктування схеми. Розкладаємо потоки за критичністю, фіксуємо топологію топіків і підписок, строк зберігання і окремий dead-letter-топік для необроблених повідомлень.
  3. Налаштування повторів. Політика повторів із затримкою між спробами, кількість доставок до відправлення в dead-letter, поведінка при відкликанні підтвердження: збійне повідомлення йде вбік, а потік продовжує йти.
  4. Доступи. Сервісні облікові записи та ролі за мінімально необхідним набором прав: підписник не публікує, збирач метрик не читає тіла повідомлень.
  5. Перевірка на відмовах. Відключаємо підписника, відкликаємо права, ламаємо обробник — дивимося, що відбувається з чергою, чи спрацьовують повтори, чи видно інцидент у моніторингу.
  6. Навантажувальна перевірка. Ганяємо профіль, близький до пікового: скільки тримає потік без зростання затримки, як зростає обсяг необроблених повідомлень, на якому темпі починаються масові повтори.
  7. Моніторинг і передача регламентів. Алерти на вік найстарішого непідтвердженого повідомлення, частку повідомлень у dead-letter і помилки публікації; інструкції для чергової зміни та порядок розбору інцидентів.

Комплект поставки: схеми потоків, політики доступу, регламенти

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

Усі налаштування Pub/Sub ми фіксуємо у вашому репозиторії: схеми, політики та регламенти версіонуються, зміни проходять рев’ю, а не живуть у чиїйсь пам’яті або листуванні.

  • Схема потоків: топологія топіків і підписок, хто публікує і хто читає, які повідомлення вважаються критичними і який маршрут проходять при повторних спробах.
  • Розділення середовищ: тестовий, передпродуктивний і бойовий контури живуть в окремих проєктах з незалежними правами і квотами — навантажувальний тест не може зчитати бойові дані.
  • Політики доступу: ролі на рівні конкретних топіків і підписок, окремий обліковий запис на кожен сервіс, принцип мінімальних прав замість одного спільного ключа для всіх.
  • Пороги оповіщень: зростання кількості необроблених повідомлень, вік найстарішого з них, частка помилок доставки і затримка публікації — із зазначенням норми та умови виклику чергового.
  • Інструкції для чергових: покрокові сценарії на кожен тип збою — що дивитися першим, що безпечно перезапустити, коли ескалувати і кому.
  • Регламент повторних спроб: скільки разів і з яким інтервалом повторюється доставка, за якої кількості відмов повідомлення йде в окрему чергу і як її розбирати.
  • Карта володіння та порядок змін: хто відповідає за топік, через який процес проходить правка політик і як відкотити невдалу зміну за один крок.

Кейс: втрати подій у розрахунковому контурі — динаміка до і після

Потік розрахункових подій ішов через шину без розділення приймання та обробки: підписник підтверджував повідомлення одразу після отримання, а бізнес-логіка відпрацьовувала слідом.

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

Ми перебудували підтвердження: приймання фіксується окремо від результату обробки, невдалі спроби йдуть у повторну доставку з наростаючою затримкою, а ті, що не пройшли за відведену кількість спроб, потрапляють у чергу недоставлених повідомлень із збереженням початкового тіла і заголовків.

Доступ сервісів до топіків і підписок розвели за окремими ролями — обліковий запис завантажувача більше не може читати і видаляти чужі підписки.

Динаміка за метриками

Метрика До робіт Після спостереження
Частка втрачених розрахункових подій близько 2% на добу нижче 0.05%
Виявлення збою обробки на ранковій звірці за алертом, хвилини
Ручний розбір інциденту розбір усієї пачки логів за ідентифікатором повідомлення
Відкат на попередню схему обробки перезапуск контуру перемикання версії підписника

Контур працює на Google Cloud Pub/Sub, і ключовим виявилося не саме ввімкнення повторів, а узгодження вікна зберігання недоставлених повідомлень із часом реакції чергової зміни: якщо воно коротше, повідомлення губляться вже на виході з черги.

За підсумками місяця спостереження жоден розрахунковий день не закрився з розбіжністю, що потребувала ручної правки проводок.

Чим відрізняється недоставлене повідомлення від повторного

Межа проходить не за фактом невдалої обробки, а за лічильником спроб. Поки межу спроб не вичерпано, повідомлення залишається в підписці й повертається підписнику повторно — це штатний режим повторної доставки, а не помилка.

Платформа вважає повідомлення «в роботі» до підтвердження, і якщо підтвердження не надійшло за відведене вікно, повертає його в чергу видачі зі збільшеним номером спроби.

Політика повторів задає, як саме це відбувається: інтервал між спробами та його зростання від спроби до спроби. Наростаюча затримка потрібна, щоб сервіс, що падає, не отримував потік задач швидше, ніж встигає відновлюватися, а сусідні підписки не забивали спільний ресурс.

Поки помилка тимчасова — недоступність залежності, мережева затримка, сплеск навантаження — кількох циклів достатньо, і повідомлення йде в роботу.

Отруєні повідомлення поводяться інакше: обробник падає на кожному повторі з однієї і тієї самої причини. Невалідна схема, посилання на видалений об’єкт, порушення інваріанта даних — такі збої детерміновані, і нарощувати спроби безглуздо. Ознака рівно одна: однаковий клас помилки за різних спроб.

Коли лічильник доходить до межі, платформа зобов’язана вибрати: видалити повідомлення або відправити його в окрему чергу розбору. Черга розбору — це не архів і не смітник, а робоче місце чергового інженера: туди потрапляє лише те, що потребує ручного рішення або правки даних. Якщо її не завести, платформа відкине повідомлення, і слідів не залишиться.

Практичний висновок: повторна доставка лікує тимчасові відмови, черга розбору зберігає непоправне автоматично. Налаштовуйте строк зберігання та сповіщення в черзі розбору — інакше вона сама стане відкладеною втратою даних.

Технічні сумніви: затримки, дублі, розмежування прав

Затримки доставки — не збій, а властивість асинхронного обміну. У Google Cloud Pub/Sub шлях від публікації до обробки залежить від розміру батчу, вікна підтвердження і швидкості самого обробника.

Якщо підписник відповідає довше, ніж спливає вікно, брокер вважає повідомлення необробленим і віддає його повторно — так з’являються дублікати.

Схему будуємо так, щоб повтор був безпечний: ідемпотентні операції, ключ дедуплікації всередині повідомлення, окрема черга для того, що не вдалося розібрати за задану кількість спроб.

Права роздаємо за сервісними акаунтами — публікатор тільки публікує, підписник тільки читає і підтверджує, адміністративні ролі застосункам не видаємо.

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

Повідомлення приходять повторно — це помилка налаштування?

Ні, базова гарантія — доставка щонайменше один раз. Дублікати знімаються на боці обробника: ключ дедуплікації та перевірка стану перед записом. Упорядкування за ключем вмикаємо там, де порядок важливий, але ідемпотентність воно не замінює.

Як зрозуміти, що справа в правах, а не в коді?

Відмова публікації та порожня вибірка підписника виглядають схоже. Ми розводимо їх за журналом доступу: роздільні ролі на топік і на підписку одразу показують, де саме відмова. Доступ видаємо за мінімумом необхідного, тому розширювати його для налагодження не доводиться.

Налаштування впливають на витрату ресурсів?

Так. Розмір батчу, вікно підтвердження і строк зберігання недоставлених повідомлень визначають обсяг трафіку і зберігання напряму. Підбираємо їх під профіль навантаження, а не залишаємо за замовчуванням, і страхуємо оповіщеннями на зростання черги.

Обговоримо вашу схему обміну повідомленнями та точки відмови

Щоб повернутися з оцінкою і планом, а не із загальними словами, нам потрібна ваша поточна картина обміну повідомленнями.

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

  • Список топіків і підписок, їх призначення, хто виступає видавцем і хто споживачем.
  • Як налаштовані повтори та черга недоставлених повідомлень: після якої кількості спроб повідомлення йде в dead-letter і хто розбирає її вміст.
  • Ролі та права доступу: які облікові записи публікують і читають, де повноваження видані ширше, ніж потрібно.
  • Що вже збирається в моніторингу: затримка доставки, обсяг нерозібраної черги, алерти і кому вони приходять.
  • Відомі точки відмови: сплески навантаження, дублі, втрата повідомлень при перезапуску споживача, ручні розбори інцидентів.
  • Вимоги до порядку робіт: що має працювати без простою і які зміни допустимі в робочий час.

Обговоримо задачу у форматі розбору: пройдемо за схемою обміну, відзначимо вузькі місця та точки відмови, зафіксуємо, що робимо в першу чергу. Опишіть вашу ситуацію — повернемося з оцінкою і планом робіт, де будуть етапи, зони відповідальності та спосіб перевірки результату.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1393
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1368
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    815
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1139