Що зазвичай падає першим
Майже ніколи не PHP сам по собі. Найчастіше база даних: кілька важких запитів, які в тихий час непомітні, під навантаженням блокують усе інше. Потім з'єднання: пул до бази вичерпаний, PHP-FPM не має вільних процесів, кожен новий користувач чекає в черзі, поки не відвалиться за таймаутом. Потім зовнішні сервіси: платіжна система або API доставки відповідає повільно, а застосунок чекає на неї синхронно, тримаючи процес.
Іноді причина в одному місці: сторінка, яка робить сотню запитів до бази, або звіт в адмінці, який хтось відкрив у найгірший момент.
Як знаходимо причину
Логи й метрики за момент падіння: що саме закінчилось першим, процеси, з'єднання, пам'ять, диск. Повільні запити до бази за той самий період. Якщо метрик немає, ставимо їх і відтворюємо навантаження на тестовому середовищі, а не чекаємо наступної акції.
Після цього вузьке місце зазвичай видно. Воно одне або два, а не «вся система».
Що виправляємо
Індекси й запити, які тримають базу. Кеш для того, що не міняється щохвилини: каталог, налаштування, сторінки для гостей. Черги для всього, що не має відбуватися під час запиту користувача: листи, повідомлення, виклики зовнішніх API, генерація файлів. Правильні ліміти для PHP-FPM і пулу з'єднань, щоб перевантаження давало повільніші відповіді, а не повну відмову.
Кожна зміна перевіряється навантажувальним тестом до і після. Ви бачите, скільки одночасних користувачів система тримала і скільки тримає тепер.
Коли треба міняти інфраструктуру
Іноді після виправлення коду впираємось у сервер: тоді потрібне масштабування, кілька інстансів застосунку, окрема база на читання. Це зрозумілі кроки, але робити їх до виправлення коду безглуздо: система з тими самими проблемами просто падатиме на дорожчому залізі.
Як підготуватись до наступного піку
Моніторинг, який покаже проблему до того, як вона стане відмовою. Навантажувальний тест перед великою акцією, а не після. І документ про те, що робити, коли все ж упало: кому дзвонити, що перезапускати, де логи. Це частина роботи, а не додаткова послуга.