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

Бот Discord на трьох серверах і той самий бот на понад двох тисячах це не одна програма більшого розміру. Кілька припущень, абсолютно нешкідливих у малому, після певного розміру стають саме тими багами, які найважче знайти.
Ось чотири, які коштували нам справжніх збоїв.
1. Збої не поширюються рівномірно, вони ховаються
AlphaCloud працює, розподілений на кілька процесів, які називають шардами. Discord вирішує, який сервер потрапляє на який шард, і кожен шард знає лише свої сервери.
Це породжує клас збоїв, що ззовні виглядає як випадковість: вітальні повідомлення працюють на одних серверах і не працюють на інших. Жодної помилки в журналі, жодного сповіщення, нічого. Причиною був один мережевий виклик без тайм-ауту. Якщо інша сторона приймає з'єднання, а потім замовкає, код чекає до кінця життя процесу. Усе, що після нього, так і не відбувається, а оскільки жодна помилка не викидається, ніщо не повідомляє про помилку.
Урок невражаючий і універсальний: кожен вихідний виклик потребує верхньої межі. Виклик, що чекає вічно, гірший за той, що завершується невдачею, бо невдача принаймні видима.
2. Перезапуск не виправлення, а дедлайн
Поки ми не знали причини, перезапуск ураженого шарда надійно допомагав. Саме в цьому й проблема з перезапусками: вони працюють, і це знімає тиск шукати причину.
Тепер ми сприймаємо «чи допомагає перезапуск?» як діагноз, а не як ліки. Якщо допомагає, зламаний стан живе в пам'яті, і в коді є місце, яке його накопичує і ніколи не прибирає.
Зворотне теж правда: усе, що має пережити перезапуск, належить до бази даних. Якщо виконується багатокрокова операція, скажімо зміна ролі для тисяч учасників, і процес помирає посередині, операція не має просто зникнути. Її треба виявити й продовжити під час наступного запуску.
3. Ліміти Discord діють на бота, а не на процес
Discord обмежує, скільки запитів бот може робити за секунду. Очевидне припущення: більше процесів, більша пропускна здатність. Неправильно. Ліміт стоїть на боті, а не на процесі. Три шарди, кожен із повним бюджетом, разом дають утричі більше дозволеного, і тоді Discord гальмує всі три.
Тож кожен наш процес обчислює, скільки їх існує загалом, і бере лише свою частку. Звучить очевидно, але таким не було, і баг довго залишався невидимим, бо кожен окремий процес сам по собі виглядав цілком пристойно.
Пов'язана пастка: повторювані завдання запускаються з фіксованими інтервалами, скажімо кожні п'ять хвилин. Якщо всі шарди стартують одночасно, вони назавжди запускають свої завдання в ту саму мить. Відтоді кожен процес отримує випадковий зсув під час запуску.
4. Те, що люди справді налаштовують, не те, чого ти очікуєш
Технічна частина це одна половина. Інша: для більшості серверів значення за замовчуванням і є налаштуванням. Модуль із неправильними значеннями за замовчуванням неправильно налаштований на переважній більшості серверів, хоч якою гарною була б сторінка налаштувань.
Звідси для нас дві речі. По-перше, кожне значення за замовчуванням потребує більше роздумів, ніж саме налаштування. По-друге, краще запитання для нового модуля не «що тут можна налаштувати», а «що робить цей модуль, коли ніхто нічого не налаштовує, і чи це правильно для звичайного сервера».
Це також причина рішення, яке спершу звучить як протилежне: з v1.8.0 майже кожне повідомлення, яке надсилає бот, можна вільно оформити. Але обов'язкові блоки, як-от причину в особистому повідомленні з попередженням чи меню категорій у панелі тікетів, можна переміщувати, але не видаляти. Свобода дизайну так, але не до того, щоб сервер випадково збудував щось, що виглядає робочим, але не працює.
Спільна нитка
Три з чотирьох це та сама думка в різних костюмах: за такого розміру тихий збій дорожчий за гучний. Про падіння повідомляють і його виправляють. Функція, яка просто перестає будь-що робити, може залишатися такою місяцями, і ти дізнаєшся про це зі звіту про баг від когось, хто не полінувався написати.
Тож перше запитання, яке ми тепер ставимо до нового коду, не «чи це працює», а «як це виглядає, коли не працює, і чи ми б це помітили».
Інші статті
Як ми стежимо за 4000 серверами Discord: Grafana, PostHog і що вони нам показали
Цикл, який непомітно створював половину нашого трафіку, три мільйони марних запитів на день і атака, що закінчилася за хвилину. Що бачить наш моніторинг і чого він свідомо не бачить.
За лаштункамиКоли наш ШІ-провайдер вимкнув модель
Заміна моделі, порожні відповіді без помилки й рахунок, що раптом виріс у кілька разів. Що зламалося і чому причину було так важко побачити.
За лаштункамиЧому майже все в AlphaCloud залишається безкоштовним
Більшість ботів Discord ховають свої найкорисніші функції за підпискою. Ми свідомо цього не робимо, і це має менше спільного зі щедрістю, ніж здається.