WordPress 503 «Сервіс недоступний»: що перевірити, коли сайт недоступний

Було корисно?

503 — це звук, який видає вебсайт, коли не може дотримати своїх обіцянок. Користувачі бачать порожню сторінку, команда маркетингу бачить втрачені доходи, а ви отримуєте тікет «сайт впав» з нулем корисних деталей.

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

Що насправді означає 503 (і чого це не означає)

503 «Service Unavailable» — це не одна помилка. Це клас відмов, коли компонент у ланцюжку обробки запиту не може обробити запит прямо зараз. Ключова фраза — «прямо зараз»: система достатньо жива, щоб відповісти, але в стані нездоров’я, щоб відмовити, таймаутити або скидати навантаження.

У світі WordPress 503 зазвичай піднімається з одного з цих вузьких місць:

  • Проксі/CDN на вході (Cloudflare, Fastly, ALB/ELB, Nginx): origin недоступний або надто повільний, невдачі перевірок здоров’я, upstream-помилки.
  • Вебсервер (Nginx/Apache): не може дістатися до upstream, забагато відкритих файлів, обмеження воркерів, насичення черг.
  • Рuntime додатка (PHP-FPM): менеджер процесів досяг ліміту, повільні запити, заблоковані воркери, OOM-кілли.
  • База даних (MySQL/MariaDB): досягнуто max connections, диск заповнений, довгі запити, затримка реплікації якщо читання розподілено.
  • Сховище (локальний диск, NFS, EBS): стрибки латентності, I/O wait, вичерпання inode, проблеми з правами після деплойментів.
  • Зовнішні залежності (SMTP, платіжні API, пошук): тема/плагін WordPress чекає на віддалені виклики.

Дві важливі хибні уяви:

  • 503 — це не «WordPress зламався». WordPress може бути в порядку; платформа навколо нього може якраз падати.
  • 503 — це не «високе CPU». Високе CPU може його спричинити, але так само можуть повільні диски, завислий DNS-резолвер або один плагін, що робить те, чого не повинен.

Цитата, яку варто тримати над монітором під час інцидентів: перефразована ідея від John Allspaw: система розповідає вам історію; шукайте наратив, а не козла відпущення.

Жарт №1: 503 — це спосіб вашого сервера сказати «Я зайнятий» без вказування часу — по суті техпідтримка з HTTP-заголовками.

Швидкий план діагностики (перший/другий/третій)

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

Перший: підтвердьте, де генерується 503 (edge чи origin)

  1. Перевірте зовні: чи отримуєте ви 503 від CDN/балансувальника чи від origin?
  2. Перевірте зсередини: зробіть curl прямо до origin (або VIP сервісу) з машини в тій самій мережі.
  3. Рішення: Якщо edge повертає 503, але origin в порядку, фокусуйтеся на перевірках здоров’я, WAF-політиках, доступності origin, TLS або upstream-таймаутах. Якщо origin теж повертає 503 — копайте глибше.

Другий: вирішіть, чи бракує вам потужностей, чи є збій

  1. Подивіться на навантаження, пам’ять і диск на origin: чи машина кульгає, свапиться, чекає I/O або закінчується місце?
  2. Рішення: Якщо бракує ресурсів, спочатку зменшіть навантаження (масштабуйте, безпечно перезапустіть, скидьте навантаження), а потім розслідуйте корінну причину після відновлення сервісу.

Третій: слідкуйте за шляхом запиту крок за кроком

  1. Логи вебсерверу: чи доходять запити до Nginx/Apache і які upstream-помилки з’являються?
  2. Стан PHP-FPM: чи насичені пули, чи воркери зависають, чи є повільні логи?
  3. Здоров’я бази даних: підключення, повільні запити, блокування, диск і тиск буферного пулу.
  4. Рішення: Коли ви знаходите перший компонент, що падає (не того, хто останнім поскаржився), ви знайшли важіль управління інцидентом.

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

Цікаві факти та контекст (коротко, але корисно)

  • HTTP 503 має «чесний» намір: його призначено для тимчасових ситуацій і він може включати заголовок Retry-After для коректних клієнтів.
  • 503 зазвичай використовують для режиму технічного обслуговування, бо він сигналізує пошуковикам «не індексувати це як постійну помилку», на відміну від 404.
  • Багато проксі видають 503 через проблеми з upstream, навіть якщо origin міг би повернути 504 або 500 — ваш код помилки може бути трансляцією, а не істинною причиною.
  • Nginx повертає 502/504 для багатьох upstream-збоїв, але певні конфігурації або проміжні балансувальники можуть показувати їх як 503.
  • WordPress рідко сам по собі повертає сирий 503; зазвичай це шар вебсерверу, PHP-FPM або фатальний шлях плагіна, що призводить до провалу перевірок здоров’я.
  • PHP-FPM був стандартним «важелем масштабування» для WordPress у багатьох стеках з початку 2010‑х, бо він відокремлює PHP-воркерів від процесної моделі вебсерверу.
  • «Thundering herd» — це не теоретично: одночасне протухання кешу на багатьох вузлах може спричинити синхронний наплив, штовхаючи PHP-FPM у стан 503.
  • Деякі керовані платформи WordPress умисно повертають 503, щоб захистити шар спільної інфраструктури під навантаженням, віддаючи перевагу частковій доступності над повним колапсом.

Питання для тріажу, що звужують радіус ураження

Задайте ці питання перед тим, як починати перезапуски, як у пінболі.

  • Всі сторінки чи лише деякі? Якщо лише адмінка або оформлення замовлення падає, подумайте про сесії, блокування бази даних або зовнішні API.
  • Всі регіони чи один? Якщо падає лише один регіон, підозрюйте маршрутизацію, DNS або зональні проблеми зі сховищем.
  • Щось змінювалося? Деплои, оновлення плагінів, правки теми, оновлення версії PHP, правила WAF, ротація сертифікатів.
  • Це пов’язано з навантаженням? Сплеск трафіку, хвиля ботів або cron-завдання, що запускається по годині і перетворює базу в суп.
  • Це періодично? Переривчасті 503 пахнуть насиченням: ліміти воркерів, пулів підключень або повільним I/O.

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

Практичні завдання: команди, виходи, рішення (12+)

Нижче — практичні завдання, які можна виконати на типовому Linux-origin для WordPress (Nginx + PHP-FPM + MySQL/MariaDB). Налаштуйте імена сервісів під вашу дистрибуцію. Кожне завдання включає: команду, приклад виходу, що це означає і що робити далі.

Завдання 1: Підтвердіть симптом зовні (код статусу + заголовки)

cr0x@server:~$ curl -sS -o /dev/null -D - https://example.com | sed -n '1,20p'
HTTP/2 503
date: Thu, 26 Dec 2025 10:12:41 GMT
content-type: text/html; charset=UTF-8
server: cloudflare
cf-ray: 88c0a1b8f9c01234-AMS

Значення: Відповідь згенерована на краю (server: cloudflare). Ви ще не впевнені, чи origin впав, чи edge не може до нього достукатися.

Рішення: Протестуйте origin напряму (Завдання 2). Якщо origin в порядку, досліджуйте CDN/origin-зв’язок, фаєрвол, TLS або перевірки здоров’я.

Завдання 2: Curl напряму до origin (обійти CDN)

cr0x@server:~$ curl -sS -o /dev/null -D - -H 'Host: example.com' http://127.0.0.1/ | sed -n '1,15p'
HTTP/1.1 503 Service Temporarily Unavailable
Server: nginx
Date: Thu, 26 Dec 2025 10:13:02 GMT
Content-Type: text/html
Content-Length: 190
Connection: keep-alive

Значення: Origin сам повертає 503 (nginx). Тепер ви в стеку origin: Nginx, PHP-FPM, додаток, база даних, сховище.

Рішення: Перейдіть до логів вебсерверу та перевірки upstream (Завдання 6–8).

Завдання 3: Перевірте базовий тиск хоста (load, пам’ять, swap)

cr0x@server:~$ uptime
 10:13:12 up 23 days,  4:01,  2 users,  load average: 18.42, 17.90, 16.55

Значення: Середнє навантаження дуже високе. Це може бути насичення CPU, I/O wait або вибух черги виконуваних процесів через забагато процесів.

Рішення: Підтвердіть, чи навантаження пов’язане з CPU чи I/O (Завдання 4), перш ніж бездумно збільшувати воркерів PHP (що може погіршити ситуацію).

Завдання 4: Визначте CPU vs I/O wait (vmstat)

cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
16  4      0  32120  11244 622144    0    0   120  3400 2200 6100 15  8 20 57  0
18  3      0  29804  10980 615332    0    0    90  4100 2400 6500 12  7 18 63  0
20  5      0  28512  10820 612110    0    0   110  5200 2500 6900 10  6 14 70  0
15  2      0  31040  11100 620400    0    0    95  3800 2100 6000 14  7 22 57  0
17  4      0  29520  10920 614880    0    0   105  4600 2450 6700 11  6 16 67  0

Значення: Високий wa (I/O wait) вказує, що CPU в основному чекають на диск/мережеве сховище. Колонка «b» (blocked) також підвищена.

Рішення: Дослідіть латентність диска та тиск файлової системи (Завдання 5 і 14). Не «виправляйте» це додаванням дочірніх процесів PHP-FPM; ви просто створите більше блокованих процесів.

Завдання 5: Перевірте вільне місце на диску та вичерпання inode

cr0x@server:~$ df -hT /
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/nvme0n1p2  ext4   40G   39G  520M  99% /

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

Рішення: Звільніть місце негайно (ротація логів, видалення великих тимчасових файлів, переміщення бекапів), потім повторіть тест. Якщо ситуація з inode, перевірте підзавдання 5b:

cr0x@server:~$ df -i /
Filesystem      Inodes  IUsed   IFree IUse% Mounted on
/dev/nvme0n1p2  2621440 2619900   1540  100% /

Значення: Вичерпання inode: занадто багато дрібних файлів (каталоги кешу, сесії, варіанти зображень). WordPress плюс агресивний кеш може це спричинити.

Рішення: Очистіть каталоги кешу та сховище сесій; розгляньте переміщення кешу в tmpfs або об’єктне сховище на довший термін.

Завдання 6: Перегляньте error.log Nginx для підказок upstream

cr0x@server:~$ sudo tail -n 30 /var/log/nginx/error.log
2025/12/26 10:12:58 [error] 22114#22114: *98123 connect() to unix:/run/php/php8.2-fpm.sock failed (11: Resource temporarily unavailable) while connecting to upstream, client: 203.0.113.10, server: example.com, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/run/php/php8.2-fpm.sock:", host: "example.com"
2025/12/26 10:13:01 [error] 22114#22114: *98145 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 198.51.100.42, server: example.com, request: "GET /wp-admin/ HTTP/1.1", upstream: "fastcgi://unix:/run/php/php8.2-fpm.sock:", host: "example.com"

Значення: Nginx іноді не може підключитися до PHP-FPM сокета і час від часу таймаутить. Зазвичай це насичення PHP-FPM, заблоковані воркери або проблеми з чергою сокета.

Рішення: Перевірте стан служби PHP-FPM і статус пулів (Завдання 7–9). Якщо PHP-FPM впав — перезапустіть; якщо він працює, але насичений — знайдіть повільний шлях.

Завдання 7: Перевірте, чи PHP-FPM запущений і стабільний

cr0x@server:~$ systemctl status php8.2-fpm --no-pager
● php8.2-fpm.service - The PHP 8.2 FastCGI Process Manager
     Loaded: loaded (/lib/systemd/system/php8.2-fpm.service; enabled; preset: enabled)
     Active: active (running) since Thu 2025-12-26 09:02:11 UTC; 1h 11min ago
       Docs: man:php-fpm8.2(8)
   Main PID: 1032 (php-fpm8.2)
     Status: "Processes active: 64, idle: 0, Requests: 92314, slow: 387, Traffic: 0.0req/sec"
      Tasks: 65 (limit: 18922)
     Memory: 2.4G
        CPU: 1h 03min

Значення: «idle: 0» з багатьма активними процесами вказує на повне насичення. Якщо максимум дітей пулу — 64, ви досягли стелі.

Рішення: Не просто збільшуйте max children, поки машина не впаде. Спочатку визначте, чому воркери повільні (Завдання 9) і чи база даних або сховище — справжня перешкода (Завдання 11–14).

Завдання 8: Перевірте сокет PHP-FPM і listen backlog

cr0x@server:~$ sudo ss -xlpn | grep php
u_str LISTEN 0      128    /run/php/php8.2-fpm.sock  22139            * 0 users:(("php-fpm8.2",pid=1032,fd=8))

Значення: backlog сокета — 128. Якщо бачите багато очікуваних підключень або помилок типу «Resource temporarily unavailable», черга та доступність процесів мають значення.

Рішення: Якщо backlog замалий для ваших стрибків трафіку, пізніше налаштуйте listen.backlog і kernel somaxconn. Зараз знайдіть, чому воркери не звільняються.

Завдання 9: Увімкніть/перегляньте slow log PHP-FPM (знайти повільні шляхи коду)

cr0x@server:~$ sudo tail -n 30 /var/log/php8.2-fpm/slow.log
[26-Dec-2025 10:12:55]  [pool www] pid 11844
script_filename = /var/www/example.com/public/index.php
[0x00007f6b2c2f81f0] mysqli_query() /var/www/example.com/public/wp-includes/wp-db.php:2050
[0x00007f6b2c2f7f20] query() /var/www/example.com/public/wp-includes/wp-db.php:1941
[0x00007f6b2c2f7c50] get_results() /var/www/example.com/public/wp-includes/wp-db.php:2970
[0x00007f6b2c2f6a10] get_posts() /var/www/example.com/public/wp-includes/post.php:2543
[0x00007f6b2c2f51a0] WP_Query->get_posts() /var/www/example.com/public/wp-includes/class-wp-query.php:3604

Значення: Воркери застрягли в MySQL-запитах. 503 — це симптом на рівні додатка від проблеми з базою даних (або затримки сховища, що уповільнює базу).

Рішення: Перемкніть фокус на здоров’я бази даних і поведінку запитів (Завдання 11–13). Перезапуск PHP-FPM не вирішить задушену базу даних; він лише тимчасово скине чергу.

Завдання 10: Перевірте, чи не влаштовує WordPress cron штампування

cr0x@server:~$ sudo tail -n 50 /var/log/syslog | grep -E 'wp-cron|cron' | tail -n 10
Dec 26 10:00:01 server CRON[21780]: (www-data) CMD (/usr/bin/php /var/www/example.com/public/wp-cron.php)
Dec 26 10:00:02 server CRON[21795]: (www-data) CMD (/usr/bin/php /var/www/example.com/public/wp-cron.php)
Dec 26 10:00:03 server CRON[21810]: (www-data) CMD (/usr/bin/php /var/www/example.com/public/wp-cron.php)

Значення: Кілька викликів cron підряд можуть накопичуватись, особливо якщо робота повільна або перекривається. WordPress cron відомий тим, що «допомагає» в найгірший момент.

Рішення: Тимчасово вимкніть тригери WP cron через вебзапити і перейдіть на один системний cron пізніше. Під час інциденту зупиніть штампування і перевірте навантаження знову.

Завдання 11: Перевірте max connections бази даних і тиск потоків

cr0x@server:~$ mysql -e "SHOW GLOBAL STATUS LIKE 'Threads_connected'; SHOW GLOBAL VARIABLES LIKE 'max_connections';"
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 298   |
+-------------------+-------+
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 300   |
+-----------------+-------+

Значення: Ви на межі підключень. Нові запити ставляться в чергу або падають; upstream-компоненти можуть видавати 503 залежно від того, як вони обробляють таймаути.

Рішення: З’ясуйте, хто утримує підключення (Завдання 12) і чому. Короткострокова міра — перезапустити недобросовісних клієнтів або збільшити max connections, якщо дозволяє пам’ять, але справжня робота — виправлення поведінки запитів.

Завдання 12: Знайдіть довго виконувані запити і блокування

cr0x@server:~$ mysql -e "SHOW FULL PROCESSLIST;" | head -n 20
Id	User	Host	db	Command	Time	State	Info
421	wpuser	10.0.2.15:51244	wpdb	Query	87	Sending data	SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' ORDER BY wp_posts.post_date DESC LIMIT 0, 10
422	wpuser	10.0.2.15:51262	wpdb	Query	90	Locked	UPDATE wp_options SET option_value = '...' WHERE option_name = 'rewrite_rules'
430	wpuser	10.0.2.15:51410	wpdb	Sleep	220		NULL

Значення: Є застряглі запити («Locked») і довгі SELECT-и. Оновлення таблиці опцій (наприклад, rewrite_rules) може блокувати і приглушувати роботу сайту.

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

Завдання 13: Перевірте повільний лог MySQL (якщо увімкнено)

cr0x@server:~$ sudo tail -n 20 /var/log/mysql/slow.log
# Time: 2025-12-26T10:12:41.123456Z
# User@Host: wpuser[wpuser] @ 10.0.2.15 []
# Query_time: 5.882  Lock_time: 1.204 Rows_sent: 10  Rows_examined: 890221
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' ORDER BY wp_posts.post_date DESC LIMIT 0,10;

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

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

Завдання 14: Перевірте латентність сховища та I/O wait на рівні пристрою (iostat)

cr0x@server:~$ iostat -xz 1 3
Linux 6.1.0 (server) 	12/26/2025 	_x86_64_	(8 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.31    0.00    6.22   58.44    0.00   23.03

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz  aqu-sz  %util
nvme0n1         42.00   1800.00     0.00   0.00   12.40    42.86  210.00  86000.00   120.00  36.36   95.20   409.52   20.10  99.80

Значення: Час очікування запису дуже високий і пристрій зайнятий ~100%. Коли сховище насичене, воркери PHP стають застряглими, база даних гальмує, а Nginx починає повертати upstream-таймаути/503.

Рішення: Визначте, що записує (логи, бекапи, шторм скидання БД). Зупиніть неважливі важкі I/O задачі (бекапи, cron, індексацію) і розгляньте переміщення завантажень/кешу на окремі томи.

Завдання 15: Перевірте, чи ядро вбиває процеси (OOM)

cr0x@server:~$ sudo dmesg -T | tail -n 20
[Thu Dec 26 10:11:33 2025] Out of memory: Killed process 11844 (php-fpm8.2) total-vm:2145120kB, anon-rss:612000kB, file-rss:0kB, shmem-rss:0kB, UID:33 pgtables:1920kB oom_score_adj:0

Значення: Воркери PHP-FPM вбиваються через OOM. Це може проявлятись як переривчасті 503 при зменшенні і відновленні потужності.

Рішення: Мітегуйте, зменшивши max children у PHP-FPM, виправивши витоки пам’яті (плагіни), обережно підвищивши ліміти пам’яті або додавши пам’ять/своп цілеспрямовано.

Завдання 16: Перевірте активні з’єднання вебсерверу та швидкість запитів

cr0x@server:~$ sudo ss -s
Total: 2345 (kernel 0)
TCP:   1988 (estab 612, closed 1201, orphaned 0, timewait 1103)

Transport Total     IP        IPv6
RAW	  0         0         0
UDP	  14        12        2
TCP	  787       735       52
INET	  801       747       54
FRAG	  0         0         0

Значення: Багато timewait і висока загальна кількість з’єднань можуть вказувати на сплески, ботів, неправильні налаштування keepalive або поведінку балансувальника.

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

Завдання 17: Підтвердіть ліміти дескрипторів файлів (класична прихована причина 503)

cr0x@server:~$ sudo cat /proc/$(pidof nginx | awk '{print $1}')/limits | grep -i "open files"
Max open files            1024                 1024                 files

Значення: 1024 відкритих файлів для Nginx замало для навантаженого сайту (з’єднання, логи, тимчасові файли). Коли ви досягаєте цього ліміту, виникають дивні upstream-помилки і неможливість accept-ити з’єднання.

Рішення: Підвищте ліміти через systemd override і конфіг Nginx. Під час інциденту зменшення з’єднань (ліміт ботів) може виграти час.

Завдання 18: Швидко протестуйте виконання PHP без повного стеку WordPress

cr0x@server:~$ printf '%s\n' '/dev/null
cr0x@server:~$ curl -sS http://127.0.0.1/health.php
ok

Значення: PHP-FPM може виконати тривіальний скрипт. Якщо сторінки WordPress повертають 503, але це працює, runtime живий; проблема, ймовірно, у кодовому шляху WordPress (плагін/тема), базі даних або сховищі.

Рішення: Якщо простий PHP працює, перевірте підключення до БД і безпечно відключайте підозрілі плагіни/теми (див. розділ з чеклістами).

Поширені режими відмов у стеку WordPress

1) Насичення пулу PHP-FPM (найпоширеніше, найменш зрозуміле)

Коли PHP-FPM вичерпав запас ідл воркерів, запити стоять у черзі на сокеті. Nginx чекає. Зрештою він здається і ви бачите 503/504/502 залежно від налаштувань і upstream-компонентів. Користувач бачить «Service Unavailable», ви бачите болото воркерів, що роблять щось повільне.

Що це спричиняє:

  • Повільні запити до бази даних (відсутні індекси, блокування таблиць, роздутий autoload опцій).
  • Повільне сховище (завантаження на мережевій FS, насичений диск).
  • Віддалені API виклики в процесі генерації сторінки (платежі/доставка, маркетингові пікселі, віддалені шрифти, перевірки ліцензії).
  • Занадто багато воркерів для доступної оперативної пам’яті, що призводить до OOM, потім трешу.

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

2) Неправильно налаштовані upstream-таймаути вебсерверу

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

Правило: таймаути повинні відображати реальність, а не надії. Якщо нормальні сторінки займають 8 секунд, не «виправляйте» це, ставлячи таймаут у 120 секунд. Виправляйте сторінку.

3) Ліміт підключень бази даних або шторм блокувань

WordPress може створювати дивно велику кількість одночасних запитів під навантаженням, особливо з важкими плагінами. Коли база досягає max connections, нові PHP-запити або блокуються, або падають. Це піднімається як «upstream timed out», «could not connect» або простий 503 від балансувальників, що позначають вузол як нездоровий.

Шторм блокувань часто походить від:

  • Плагінів, що часто оновлюють wp_options.
  • Генерації rewrite-правил на трафіку.
  • Кеш-плагінів, що роблять записи під навантаженням.

4) Латентність сховища та проблеми з inode

WordPress — це не тільки PHP і MySQL. Це медіафайли, кеші, сесії й уламки плагінів. Коли сховище повільне, усе сповільнюється. Коли inode вичерпані, все ламається творчими способами.

5) Edge повертає 503 через провали перевірок здоров’я

Ваш origin може нормально віддавати реальні сторінки, але провалювати health-check через редиректи, аутентифікацію або залежності викликів. Балансувальник позначає хост як нездоровий і віддає 503, навіть якщо додаток переважно працює.

6) Плагін/тема молотить після оновлення

Один плагін може додати N+1 запитів, віддалені виклики або важкі CPU-операції на кожен запит. Під реальним трафіком це повільна відмова в обслуговуванні, за яку ви заплатили самі.

Жарт №2: Плагін обіцяв «прискорити продуктивність». Він це зробив — аж поки не прискорив ваш показник помилок.

Три міні-історії з корпоративного світу (бо це повторюється)

Міні-історія 1: Інцидент через хибне припущення

У них був WordPress за CDN і керованим балансувальником. Під час запуску продукту з’явилися 503. Команда припустила «origin впав» і почала перезапуски PHP-FPM та масштабування інстансів. Це допомагало на хвилину-дві кожного разу. 503 поверталися, як повторювана зустріч у календарі.

Хибне припущення було тонким: вони трактували 503 як помилку додатка. Але балансувальник саме його повертав, бо перевірки здоров’я провалювалися. Шлях перевірки був /, який почав редиректити на гео-специфічний шлях після маркетингової зміни. Балансувальник не слідував за редиректами. Нездорові таргети — миттєвий 503.

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

Виправлення було банальним: додали окремий /healthz, що повертає plain 200, сервісований Nginx без PHP. Перевірки здоров’я стабілізувалися відразу. Після цього команда побачила реальну проблему: трафік був високим, але стек фактично справлявся, якщо йому дозволяли приймати запити.

Міні-історія 2: Оптимізація, що відкотилася

Інша компанія намагалася «прискорити WordPress», різко піднявши PHP-FPM pm.max_children і знизивши таймаути Nginx, щоб усе було швидше. На стейджингу сайт був швидким. У продакшені машина перетворилася на обігрівач із проблемою диска.

Підвищена кількість воркерів примножила одночасні запити до БД. БД почала постійно скидати dirty pages. Використання диска вперлося. I/O wait підскочив. Воркери PHP накопичувалися в очікуванні БД, а таймаути Nginx їх обрізали. Користувачі бачили 503; команда — «але ми ж збільшили потужність».

Вони оптимізували пропускну здатність «на папері», ігноруючи спільне вузьке місце: disk-backed DB I/O. Більше конкурентності не означало більше завершень. Це означало більше очікування.

План відновлення: навмисно зменшити конкурентність — знизити кількість дітей PHP-FPM, щоб відповідати можливостям БД, трохи подовжити upstream-таймаути, щоб уникнути масових ретраїв, і ввести ліміти для дорогих ендпоінтів. Після вогню додали правильний кеш і виправили найгірші запити. «Оптимізація» стала уроком про вузькі місця.

Міні-історія 3: Нудна, але правильна практика, що врятувала ситуацію

Медіакомпанія тримала WordPress під стабільним високим трафіком. Їхня секретна зброя не була у витончених сервісах, а в дисципліні: health-check без PHP, регулярна ротація логів, алерти на диск і inode, і стандартний рунабук інцидентів, яким усі дійсно користувалися.

Одного дня рівень 503 піднявся. Онкол керувався рунабуком: підтвердити edge vs origin, перевірити диск, перевірити PHP-FPM, перевірити підключення до БД. Диск був у порядку, але inode майже вичерпалися. Плагін кешу почав генерувати велику кількість дрібних файлів після зміни конфігурації. PHP не міг надійно писати сесії, і сайт почав видавати помилки і таймаути.

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

Це було не гламурно. Це було правильно. Нудна правильність — як виграють інциденти.

Типові помилки: симптом → корінна причина → виправлення

Цей розділ запобігає патерну «ми перезапустили все шість разів і стало ще гірше».

503 лише на CDN, origin виглядає в порядку

  • Симптом: Заголовки edge показують CDN/балансувальник; curl до origin повертає 200.
  • Корінна причина: Шлях перевірки здоров’я не працює, IP origin заблоковано, TLS mismatch, правило WAF або origin лімітує трафік з edge.
  • Виправлення: Використайте окремий /healthz, що повертає 200 без авторизації/редиректів; переконайтесь, що фаєрвол дозволяє IP edge; перевірте сертифікат і SNI; перегляньте логи edge.

503 під час сплесків трафіку, потім відновлюється

  • Симптом: Періодичні 503, upstream-таймаути в Nginx.
  • Корінна причина: Досягнуто max children PHP-FPM; досягнуто ліміт підключень DB; cache stampede.
  • Виправлення: Додайте кешування, що запобігає штампуванню, налаштуйте PHP-FPM відповідно до CPU/RAM і ємності БД, лімітуйте бот-шляхи і переконайтесь, що OPcache налаштовано правильно.

503 після оновлення плагіна/теми

  • Симптом: Аутейдж починається відразу після оновлення; адмін може бути недоступний; повільні логи показують конкретні PHP-шляхи.
  • Корінна причина: Плагін викликає фатальні помилки, витік пам’яті або масивні записи в БД; несумісність з версією PHP.
  • Виправлення: Вимкніть плагін перейменуванням його директорії або за допомогою WP-CLI; відкотіть; фіксуйте версії; введіть staging і canary деплои.

503 корелює з «Disk 100%» або високим iowait

  • Симптом: Високий iowait, MySQL стоїть, воркери PHP блоковані.
  • Корінна причина: Бекап, потік логів, скидання бази, повільне мережеве сховище, вичерпання inode.
  • Виправлення: Зупиніть/обмежте галасливі I/O задачі; перемістіть важкі записи з кореневого тома; налаштуйте поведінку скидання БД; відокремте uploads/cache; моніторте латентність, а не тільки пропускну здатність.

Перезапуск PHP-FPM «вирішує» проблему тимчасово

  • Симптом: Негайне покращення, потім швидкий рецидив.
  • Корінна причина: Скидання черги; підлягаюча перешкода лишається (БД, сховище, зовнішній API); або витік пам’яті, що швидко відновлюється.
  • Виправлення: Використайте коротке вікно після відновлення, щоб зібрати докази: повільні логи, processlist, топ-винуватців і ввести ліміти. Потім усуньте корінну причину.

Лише wp-admin повертає 503

  • Симптом: Головна сторінка іноді працює, адмін постійно падає.
  • Корінна причина: Сторінки з вищими правами запускають важчу логіку плагінів, не кешуються або пишуть сесії; також це може вказувати на повільний провайдер аутентифікації.
  • Виправлення: Вимкніть плагіни, що підключаються до адмінки; перевірте сховище сесій; протестуйте мінімальний PHP-ендпоінт; дослідіть зовнішні auth-виклики.

Контрольні списки / покроковий план

Чекліст A: 10‑хвилинний тріаж для відновлення сервісу

  1. Знайдіть походження 503: edge vs origin (curl заголовки; прямий виклик origin).
  2. Перевірте стан хоста: load, пам’ять, swap, місце на диску, inode.
  3. Подивіться логи Nginx/Apache: помилки підключення до upstream, таймаути, «too many open files».
  4. Перевірте PHP-FPM: чи запущений, чи hit max children, активність slow log.
  5. Перевірте насичення БД: threads connected, max connections, processlist, блокування.
  6. Мітегація:
    • Лімітуйте підозрілі шляхи/ботів на edge або Nginx.
    • Обережно очистіть або підігрійте критичні кеші, якщо безпечно.
    • Зупиніть важкі фонові завдання (бекапи, імпорти, cron-шторми).
    • Перезавантажуйте/перезавантажуйте сервіси тільки якщо розумієте, що саме скидаєте.
  7. Підтвердіть відновлення: curl до origin і зовні, перевірте 2–3 ключові сторінки, спостерігайте за падінням рівня помилок.

Чекліст B: Безпечне відключення плагіна, коли wp-admin недоступний

Якщо ви впевнені в підозрі на плагін і не маєте доступу до адмінки — робіть це з файлової системи. Це грубо, але ефективно.

  1. Знайдіть недавно оновлені плагіни (з логів деплоя або mtimes файлів).
  2. Вимкніть, перейменувавши директорію (WordPress пропустить плагін).
  3. Повторно перевірте health-ендпоінт і головну сторінку.
  4. Якщо відновилось — залиште плагін вимкненим і плануйте контрольоване включення з профілюванням.
cr0x@server:~$ cd /var/www/example.com/public/wp-content/plugins
cr0x@server:~$ sudo mv suspicious-plugin suspicious-plugin.disabled
cr0x@server:~$ curl -sS -o /dev/null -w "%{http_code}\n" -H 'Host: example.com' http://127.0.0.1/
200

Значення: Якщо статус повертає 200 після відключення — ви звузили причину до цього плагіна або пов’язаного з ним ефекту.

Рішення: Залиште його вимкненим; повідомте зацікавлені сторони; збережіть логи й копію версії плагіна для пізнішого аналізу.

Чекліст C: Акуратний рестарт сервісів, щоб не погіршити ситуацію

Перезапуски — інструмент, а не молитва. Користуйтесь ними, коли компонент дійсно завис, а не заміною діагностики.

cr0x@server:~$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
cr0x@server:~$ sudo systemctl reload nginx
cr0x@server:~$ sudo systemctl restart php8.2-fpm

Значення: Спочатку перезавантажуйте Nginx (дешево і низький ризик) після перевірки конфігурації. Перезапускайте PHP-FPM лише якщо воркери зависли/вбиваються OOM і вам потрібно скинути затор.

Рішення: Якщо перезапуск PHP-FPM відновлює сервіс, але рецидив відбувається швидко — припиніть перезапуски і перемкніться на збір доказів повільних шляхів.

Чекліст D: Стабілізація після відновлення (цей же день)

  1. Тримайте ліміти трафіку, доки не впевнитесь у стабільності під нормальним навантаженням.
  2. Зберіть артефакти: топ повільних запитів, уривки slow log PHP-FPM, помилки upstream Nginx, зразки processlist БД.
  3. Напишіть короткий таймлайн інциденту: що змінилось, коли почалось, які міри допомогли.
  4. Перетворіть найбільшу проблему на постійну перевірку (алерт, дашборд, автоматичний тест).

Поширені питання

1) Чи завжди WordPress 503 — це серверна проблема?

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

2) Чому іноді бачу 503, а іноді 504?

Різні шари транслюють відмови по-різному. Балансувальник може позначити таймаут upstream як 503, тоді як Nginx згенерує 504. Зосередьтесь на місці виникнення збою, а не на точному коді.

3) Чи потрібно збільшувати PHP-FPM pm.max_children, щоб виправити 503?

Лише якщо ви підтвердили, що маєте вільні CPU/RAM і база/сховище витримають більшу конкурентність. Інакше ви посилите вузьке місце і ризикуєте OOM-кіллами і ще гіршою латентністю.

4) Як зрозуміти, чи БД є вузьким місцем?

Повільні логи PHP-FPM із mysqli_query(), MySQL Threads_connected близько до max, довгі запити у processlist і високий диск-wait на хості БД — сильні сигнали.

5) Чи може CDN викликати 503, навіть якщо origin в порядку?

Так. Провали перевірок здоров’я, заблокований доступ до origin, невідповідність TLS/SNI або ліміти можуть змусити edge повертати 503. Завжди тестуйте origin напряму з правильним заголовком Host.

6) Який найшвидший спосіб ізолювати проблемний плагін?

Вимкніть його без доступу до wp-admin: перейменуйте директорію плагіна і повторно протестуйте. Для більш точного підходу відключайте плагіни по черзі, починаючи з останніх змін.

7) Чому перезапуск «вирішує» проблему тимчасово?

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

8) Чи може 503 спричинити проблема з правами на файли?

Косвено — так. Якщо WordPress не може писати в директорії uploads/cache/session, запити можуть зависати або помилитись, що призведе до upstream-помилок. Перевірте логи Nginx/PHP на помилки прав і стан файлової системи.

9) Який ендпоінт health check використовувати для балансувальників?

Статичний ендпоінт, сервований вебсервером (не PHP), що повертає 200 з мінімальною роботою. Якщо потрібні глибші перевірки — зробіть окремий внутрішній ендпоінт для моніторингу, а не для управління трафіком.

10) Як запобігти 503 на довший термін?

Інструментуйте вузькі місця (насичення PHP-FPM, підключення DB, латентність диска), контролюйте конкурентність, кешуйте правильні речі і ставтесь до оновлень плагінів як до деплойментів — поетапно і з можливістю відкату.

Висновок: наступні кроки після відновлення

Коли сайт знову почав віддавати, не «закривайте інцидент» і не йдіть геть. Система тільки-но показала, де вона ламається. Скористайтесь цим уроком.

  1. Перетворіть корінну причину на запобіжник: алерти на inode/латентність диска, насичення PHP-FPM, запас підключень БД і правильність health check.
  2. Виправіть повільний шлях: проіндексуйте найгірші запити, видаліть або замініть найважчі плагіни, припиніть робити віддалені виклики в критичному рендер-шляху.
  3. Підберіть правильну конкурентність: налаштуйте кількість дітей PHP-FPM під те, що база і сховище дійсно витримують, а не під «враження більшої потужності».
  4. Зробіть відмови дешевшими: додайте справжній /healthz, впровадьте кешування зі захистом від штампування і реалізуйте лімітування для зловмисних ендпоінтів.
  5. Напишіть рунабук, якого вам не вистачало: точні команди, які ви виконували, логи, що мали значення, і нотатки «не робіть цього знову». Наступного разу ви будете втомлені, але менш хитрі.

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

← Попередня
Proxmox: «vzdump backup failed» — 10 реальних причин і як перевіряти по порядку
Наступна →
Збій живої міграції Proxmox: що перевірити для мережі, прапорців CPU та сховища

Залишити коментар