Błąd 504 Gateway Timeout: znajdź, co spowalnia stronę
· 6 min czytania
Co oznacza ten błąd
504 to serwer WWW z przodu (nginx, Apache, load balancer, CDN), który poddaje się w oczekiwaniu na aplikację za sobą. Żądanie zostało przekazane, backend zaczął pracować, a licznik czasu przodu wyczerpał się, zanim wróciła odpowiedź. Różnica wobec błędu 502 Bad Gateway jest taka, że backend jest osiągalny; jest tylko za wolny. Typowe liczniki to 60 sekund w nginx (fastcgi_read_timeout, proxy_read_timeout), 60 sekund w Apache (ProxyTimeout) i 100 sekund w Cloudflare, czego w bezpłatnym planie nie zmienisz.
Podniesienie limitu czasu rzadko jest naprawą. Coś trwa za długo i to coś trzeba znaleźć.
Częste przyczyny
- Wolne zapytanie do bazy danych. Wtyczka WordPressa, która przy każdym wyświetleniu liczy wiersze w ogromnej tabeli, brakujący indeks, tabela
wp_optionspełna wygasłych transientów. Każde żądanie czeka, a pod obciążeniem czekanie się sumuje. - Zewnętrzne wywołanie, które wisi. Aplikacja łączy się z dostawcą płatności, usługą poczty, API pogody albo serwerem licencji, a ta usługa jest wolna albo nie działa. Bez limitu czasu na tym wywołaniu Twoja strona na nie czeka.
- Za mało procesów roboczych. Wszystkie procesy PHP-FPM są zajęte wolnymi żądaniami; nowe czekają w kolejce, aż przód się podda. Z zewnątrz wygląda to jak przekroczenie czasu, choć każde pojedyncze żądanie byłoby szybkie.
- Cron albo kopia zapasowa na pierwszym planie. Wtyczka kopii zapasowych, import, mapa strony z 50 000 adresów: generowane wewnątrz żądania WWW przekraczają każdy limit.
- I/O dysku albo swap. Serwerowi kończy się pamięć i swapuje; wszystko zwalnia dziesięciokrotnie. Widoczne jako wysokie obciążenie przy niskim użyciu CPU.
- Sieć między przodem a tyłem. Load balancer w jednym centrum danych, backend w innym, firewall po cichu gubiący pakiety. Rzadkie, ale 504 przy każdym żądaniu z bezczynnym backendem wskazuje właśnie tu.
Jeśli odwiedzasz cudzą stronę
Odśwież po minucie. Jeśli strona jest raczej wolna niż niedziałająca, spróbuj innej podstrony; limit może dotyczyć jednej ciężkiej strony.
Jeśli to Twoja strona: najpierw sprawdź
Uruchom narzędzie Is it down?: podaje kod statusu i czas odpowiedzi z zewnątrz. Strona, która dziś odpowiada w 30 sekund, jutro pod obciążeniem pokaże 504.
Na własnym serwerze znajdź, gdzie ucieka czas:
# czy procesy robocze się piętrzą?
sudo tail -n 30 /var/log/nginx/error.log | grep -E 'timed out|timeout'
# co PHP robi w tej chwili? (wymaga pm.status_path w puli)
curl -s 'http://127.0.0.1/fpm-status?full' | grep -E 'state|request URI|duration' | head -40
# MySQL/MariaDB: które zapytania działają i jak długo?
sudo mysql -e 'SHOW FULL PROCESSLIST;'
# pamięć i swap
free -m
vmstat 1 5
Lista procesów pełna tego samego zapytania albo kolumny si/so w vmstat różne od zera podają przyczynę.
Naprawy na własnym serwerze
1. Włącz log wolnych zapytań i popraw zapytanie
SET GLOBAL slow_query_log = 1;
SET GLOBAL long_query_time = 2;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
Po kilku minutach sudo mysqldumpslow -s t /var/log/mysql/slow.log | head wymienia najgorsze zapytania. Dodaj brakujący indeks albo znajdź wtyczkę, która wykonuje to zapytanie, i ją zastąp. W WordPressie klasykiem jest rozdęta tabela opcji:
wp transient delete --all
wp db query "SELECT option_name, LENGTH(option_value) AS size FROM wp_options WHERE autoload='yes' ORDER BY size DESC LIMIT 20;"
Wszystko, co ma setki kilobajtów i ładuje się automatycznie przy każdym żądaniu, jest kandydatem do usunięcia.
2. Ustaw limit czasu na wywołania zewnętrzne
Każde wywołanie HTTP wykonywane przez aplikację potrzebuje własnego limitu czasu, krótszego niż limit serwera WWW. W PHP z cURL: CURLOPT_CONNECTTIMEOUT 5 i CURLOPT_TIMEOUT 10. W WordPressie wp_remote_get() przyjmuje argument timeout; wiele wtyczek zostawia domyślny i czeka w nieskończoność. Jeśli zewnętrzna usługa nie działa, strona powinna działać w trybie ograniczonym (pokazać formularz bez stawki dostawy na żywo), a nie umierać.
3. Przenieś długą pracę poza żądanie
Kopie zapasowe, importy, eksporty, duże mapy strony i wysyłka poczty należą do zadania cron albo kolejki, nie do wyświetlenia strony. W WordPressie wyłącz pseudo-cron i uruchom prawdziwy:
// wp-config.php
define('DISABLE_WP_CRON', true);
# crontab -e
*/5 * * * * cd /var/www/przyklad.pl && wp cron event run --due-now >/dev/null 2>&1
4. Dostosuj limity czasu, ostrożnie
Jeśli jedna strona naprawdę potrzebuje więcej czasu (eksport w panelu, raport), podnieś limit tylko dla tej lokalizacji, nie globalnie:
location = /wp-admin/export.php {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_read_timeout 300;
}
Apache z PHP-FPM: ProxyTimeout 300 wewnątrz bloku <Location>. Samo PHP ma max_execution_time; ustaw tę samą wartość, inaczej PHP zatrzyma się pierwsze i zamiast 504 dostaniesz 500. Potem sudo nginx -t && sudo systemctl reload nginx.
5. Zatrzymaj swapowanie
ps aux --sort=-%mem | head
Jeśli procesy PHP-FPM używają po 150 MB, a na serwerze z 4 GB działa ich 30, rachunek się nie zgadza. Obniż pm.max_children, dołóż pamięci albo napraw wtyczkę, która ją zużywa. Serwer, który nie swapuje, to serwer, którego błędy 504 w większości znikają.
6. Cache
Cache całych stron (FastCGI cache w nginx, wtyczka cache w WordPressie, Varnish) obsługuje powracających odwiedzających bez dotykania PHP i bazy danych. Większość błędów 504 pod obciążeniem znika, gdy strona główna i najpopularniejsze podstrony idą z cache.
Gdy to problem dostawcy hostingu
Na hostingu współdzielonym poprawisz wolne zapytania i wtyczki, ale nie limity czasu serwera ani obciążenie sąsiadów. Wyślij dostawcy:
Dzień dobry, moja strona przyklad.pl zwraca „504 Gateway Timeout” od około 16:00 UTC. Strony, które ładowały się poniżej dwóch sekund, teraz przekraczają limit czasu. Po mojej stronie nic się nie zmieniło. Czy mogliby Państwo sprawdzić, czy serwer bazy danych albo pula PHP mojego konta jest przeciążona, albo czy inne konto na serwerze generuje wysokie obciążenie, i dać mi znać, co Państwo ustalili?
Jak zapobiec następnemu
Błąd 504 to wolna strona, która zwolniła jeszcze bardziej, a czas odpowiedzi da się zmierzyć na długo przed przekroczeniem limitu. Sprawdzanie stron zapisuje czas odpowiedzi każdego sprawdzenia; ustaw na nim alert, a trend zobaczysz tygodnie przed tym, jak odwiedzający zobaczą błąd. Agent serwerowy dodaje obciążenie, pamięć i swap od środka. Awaria? Naprawiamy: na własnym serwerze Deep Fix znajduje wolne zapytanie albo wiszące wywołanie i je usuwa, rozliczany w blokach po 15 minut, cena przed zamówieniem. Zobacz naprawa serwera.
Co teraz
Sprawdź z zewnątrz
Strona nie działa u wszystkich czy tylko u Ciebie i co odpowiada serwer? Za darmo, bez rejestracji.
Is it down? Sprawdź, czy strona działaAwaria? Naprawiamy.
Na Twoim własnym serwerze albo na hostingu z dostępem SSH: Quick Fix w stałej cenie na częste przyczyny, Deep Fix rozliczany w blokach po 15 minut na resztę, przez całą dobę. Cena przed zamówieniem.
Zamów naprawęWięcej poradników
- Strona nie działa: co zrobić w pierwszych 15 minutach
- Awaria serwera: co sprawdzić i w jakiej kolejności
- Błąd 500 Internal Server Error: znajdź przyczynę w logach i przywróć stronę
- Błąd 502 Bad Gateway: znajdź przyczynę i napraw
- Błąd 503: przeciążenie, konserwacja czy limit hostingu?
- Błąd 521 i 522 w Cloudflare: serwer źródłowy nie odpowiada
- DNS_PROBE_FINISHED_NXDOMAIN: domena przestała odpowiadać
- ERR_CONNECTION_REFUSED: serwer odrzuca połączenie
- ERR_CONNECTION_TIMED_OUT: serwer nie odpowiada na czas
- Co oznacza „Połączenie nie jest prywatne” i jak to naprawić
- ERR_SSL_PROTOCOL_ERROR: bezpieczne połączenie zawodzi przed certyfikatem
- ERR_TOO_MANY_REDIRECTS: znajdź pętlę przekierowań i ją przerwij
- Błąd 403 Forbidden: co blokuje dostęp do Twojej strony
- ERR_NAME_NOT_RESOLVED: nie można znaleźć nazwy strony
- „Błąd podczas nawiązywania połączenia z bazą danych” w WordPressie: przyczyna i naprawa
- ERR_CONNECTION_RESET: dlaczego połączenie zrywa się w połowie
- Błąd 429 Too Many Requests: który limit blokuje odwiedzających
- ERR_EMPTY_RESPONSE: serwer nie wysłał żadnych danych
- Błąd krytyczny WordPress: znajdź przyczynę i przywróć stronę