504 - Код означающий, что сервер при работе в качестве внешнего шлюза или прокси-сервера не получил своевременно отклик от вышестоящего backend-сервера, к которому он обратился, пытаясь выполнить запрос.
По этой ошибке можно представить внутреннюю организацию вашего сервера: это явно связка из двух web-серверов в которой один выступает в роли frontend (nginx) и второй в качестве backend (apache).
Nginx берёт на себя роль распределяющего proxy сервера и отдаёт статикические данные (картинки, файлы), а apache вместе с PHP обрабатывает динамические данные, в том числе работа с БД.
И ошибку 504 Gateway Time-out вы получаете именно от nginx.
Но, вернёмся к делу!
Суть ошибки: в отведённое время сервер nginx просто не дожидается обратного ответа от apache и сообщает об этом вам.
Т.е. прослеживаются явные перегрузки на backend-стороне сервера. Другой вопрос в том, что именно порождает эти перегрузки от чего apache не успевает во время ответить? Но это уже другой вопрос, тут так просто не разобраться. Надо смотреть логи сервера. Либо скрипт долго работает, либо СУБД не успевает обработать множество запросов (что, кстати, бывает чаще всего). В общем ваш backend-сервер не успевает в срок выполнить скрипт, точнее он просто долго выполняет, а nginx не хочет ждать и спешит отдать вам 504 ошибку. От чего не укладывается по времени apache так же ясно: либо много запросов извне и ресурсов сервера не хватает (это можно узнать из счётчика посещаемости сайта), либо выполняемый скрипт очень тяжёлый.
В общем речь сейчас не об этом, а том как справится с ошибкой 504.
Ближе к делу: наша задача сказать серверу nginx, что бы он ждал ответа от apache подольше и не торопился отдавать клиенту ошибку 504.
С этим всё просто! Заходим на сервер, хоть даже по протоколу ssh в терминале и идём в папку с конфигурационными файлами сервера nginx.
Сразу скажу, что они меняются от версии к версии и поэтому точно сказать какой именно файл будет не могу.
Плюс ко всему всё ещё зависит от того в каком режиме работает nginx и кто его вам настраивал.
Грубо говоря нам нужен текущий файл настроек сервера nginx для требуемого виртуального хоста (сайта) либо же для всего сервера в целом.В большинстве случаев этот файл - nginx.conf.
Заходим в условный файл настроек виртуальных хостов сервера nginx, расположенному, скорее всего, по адресу: /etc/nginx/nginx.conf
Здесь мы можем либо поискать уже установленные директивы (если есть) или дописать вручную, как для всех хостов, так и для каждого конкретного, не важно.
Нам нужно указать следующие директивы, которые нужны для изменения времени ожидания:
proxy_send_timeout 60; # время ожидания при передаче запроса
proxy_read_timeout 60; # время ожидания при чтении ответа
Лучше вставлять в контекст location. У меня получилось примерно следующим образом:
server {
listen xxx.xxx.xxx.xxx:xx;
server_name xxxxxxxxxxx.xxx;
error_page 404 = @fallback;
proxy_send_timeout 600; # время ожидания при передаче запроса
proxy_read_timeout 600; # время ожидания при чтении ответа
location / {
proxy_pass http://xxx.xxx.xxx.xxx:xxxx;
proxy_redirect http://xxxxxxxx.xxx:8080/ /;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
}
Сохраняем файл и перезапускаем nginx.
Теперь он будет ждать ответа от apache именно столько времени, сколько вы указали в добавленных директивах.
Всё, теперь ошибка 504 Gateway Time-out вас беспокоить не должна.
Понятное дело, что это лишь вершина айсберга и нужно будет разбираться с самой причиной долгой генерации страницы, но это уже другая тема. Возможно придётся так же поставить таймаут побольше и для PHP, а то может быть такое, что и он начнёт ругаться, мол ему дают мало времени на обработку.
Для этого используем PHP директивы max_input_time и max_execution_time в файле настроек PHP — php.ini или в файле локальных настроек сервера Apache — .htaccess
Дополню тем, что если вы используете сервер Apache в качестве frontend-сервера и получаете ошибку 504 Gateway Time-out именно от него, тогда можно попробовать поменять опцию Timeout, находящуюся в файле конфигураций веб сервера, чаще всего это либо httpd.conf или httpd-default.conf.
Находим следующие строки:
# Timeout: The number of seconds before receives and sends time out.
Timeout 60
И вместо 60 пишем новое значение, рекомендую ставить на 600 секунд (Timeout 600), т.е. 10 минут.
На этом пожалуй всё. Надеюсь проблема 504 Gateway Time-out теперь решена для вас.