Skip to main content
За лаштунками
За лаштункамиEngineeringDecisions

Як ми стежимо за 4000 серверами Discord: Grafana, PostHog і що вони нам показали

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

Опубліковано автор AlphaCloud4 хв читання

AlphaCloud працює на трохи більш ніж 4000 серверах Discord, розподілених між чотирма шардами. Це чотири процеси, кожен з яких обслуговує частину серверів, і всі вони звертаються до одного API.

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

Два інструменти, два запитання

Grafana відповідає на запитання: що робить бот? Бот і API передають метрики в Prometheus (запити, час відповіді, частку помилок, відповіді Discord, використання ШІ), а журнали йдуть у Loki. Кожен серверний вузол має власний стек, а Grafana доступна лише через приватну мережу, не з інтернету.

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

Цей поділ свідомий. Grafana дивиться на машини, PostHog на інтерфейси. Якщо втиснути обидва в один інструмент, отримаєш або дані користувачів у серверних журналах, або серверне навантаження в продуктовій аналітиці.

Що він знайшов

Цикл, що створював половину трафіку

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

Ми помітили це лише в Grafana, коли розбили запити бота до API за шляхами: цей один ендпоінт становив понад половину всього трафіку. Усе працювало. Просто воно несло навантаження, про яке ніхто не просив.

Тепер кожен шард раз на хвилину запитує: «Які сервери взагалі мають завершене опитування?» і отримує подробиці лише для них. Приблизно 4200 запитів на хвилину перетворилися приблизно на чотири.

Три мільйони разів «не налаштовано»

Той самий шаблон, інше місце: кілька модулів (записи підтримки, відсутності, список команди, статистика бота, розсилка) у своїх циклах регулярно зчитували налаштування кожного сервера. На більшості серверів конкретний модуль узагалі не налаштований, тож відповідь була «не знайдено». Приблизно три мільйони разів на день.

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

Збої Discord не є нашими багами

Наш командний канал помилок публікував кожну невдалу дію як «Runtime Error», з унікальним посиланням і всім іншим. Сюди потрапляли й моменти, коли сам Discord відповідав серверною помилкою. Це не баг із нашого боку і не те, що ми можемо виправити, а в каналі воно виглядало точнісінько як справжній дефект.

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

Атака, що тривала одну хвилину

Одного дня наприкінці вересня наша головна сторінка отримала трохи більше 500 000 запитів за одну хвилину, одночасно з багатьох країн. Більшість зупинили ще до того, як вони дійшли до наших серверів, а за хвилину трафік повернувся до норми.

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

Чого наш моніторинг свідомо не бачить

Правила тут важать стільки ж, скільки й дашборди:

  • Жодних IP-адрес відвідувачів у журналах. Наша політика конфіденційності це обіцяє, тож ми прибираємо їх у двох місцях: коли пишеться журнал доступу і ще раз перед тим, як він зберігається.
  • Жодних ID серверів, користувачів чи повідомлень у метриках. Кожну метрику поділено лише за грубими ознаками (модуль, клас статусу, шард). Це захищає дані й тримає базу метрик маленькою.
  • Записи сесій показують наш інтерфейс, а не твій вміст. Читабельним залишається лише текст, що дослівно походить із наших файлів перекладу. Назви серверів, каналів і користувачів, введення та попередні перегляди замасковано. Якщо список дозволених текстів не вдається завантажити, маскується все.
  • Усе на сайті лише після згоди. Через це й цифри там є нижньою межею. Для справжньої кількості переглядів ми дивимося на анонімні загальні показники від нашого мережевого провайдера.

Подробиці є в політиці конфіденційності.

Що ми з цього винесли

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

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

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

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

Інші статті