Как я победил ошибку 502 Gateway timeout error в nginx+php-fpm

Php-fpm считается на сегодняшний день одним из самых быстрых движков для веб-сервера. Но он очень нестабилен при работе со сложным php-кодом. И в один прекрасный день вы можете получить ошибку 502 Gateway timeout error.

У меня в проекте так и получилось. На VPS стоял nginx + php7.0-fpm + MariaDB + memcached. Код php-скрипта использовал весь этот стэк технологий и работал благополучно пару месяцев, а потом вдруг стал выдавать 502-ю.

Для проверки, когда мой скрипт все-таки работает, я написал скрипт-чекер на php и запускал каждые 10 минут его по сron. Чекер запускался через консоль, а обращался через функцию file_get_contents() к url скрипта на сайте. В случае недоступности скрипта я отсылал через mail() письмо себе на почту.

Я выяснил, что ошибка 502 Gateway timeout error возникала не всегда. Могла появиться раз в час, а могла и на протяжении многих часов. Временно исправить проблему помогала перезагрузка nginx и memcached.

Почитав мануалы, я решил применить то, что советуют — увеличить proxy timeout в директиве Location, а также timeout в настройках php-fpm. Не помогло. Причем, когда я вообще сделал timeout в php-fpm бесконечным, скрипту все равно не хватало времени и он выполнялся без конца.

Решив, что все-таки дело в php-fpm я подумал, чем же его заменить. Порывшись в интернете я нашел решение для замены — OpenLightSpeed Webserver + php-модуль к нему.

Установив этот вебсервер, что было не совсем просто, но все же осуществимо в конце концов я обнаружил, что 502-я ошибка появляется все также. Еще я не смог настроить BasicAuth авторизацию на папках, поэтому недолго думая запустил восстановление бэкапа диска VPS-сервера и через 10 минут снова работал с nginx+php-fpm.

Последнее обстоятельство толкало на новую мысль — дело не в сервере, а в скрипте. И это оказалось правильным. Я залез в скрипт — там было 5 sql-запросов к mysql. 2 я слил в 1 при помощи LEFT JOIN, из 2-х запросов сделал 1 и еще 1 оставил как есть. Исследуя запросы, я обратил внимание на запрос SELECT max(price) FROM prices WHERE session_id = ‘1’ и решил залезть в phpmyadmin, чтобы посмотреть таблицы.

Каково было мое удивление, когда я обнаружил 400000 записей цен. При этом для этой таблицы не было установлено ни одного индекса. Все. Причины ошибки 502 были найдены! Был переписан скрипт импорта записей в таблицу цен, а в самой таблице цен созданы индексы.

После проведения работ теперь все работает как надо.

Возможно, что при появлении ошибки 502 Gateway timeout error причина может быть в базе данных и в веб-сервере, а совсем не в php-fpm. Поэтому в базе данных можно попробовать включить лог медленных запросов (slow query), а в веб-сервере промониторить, появляется ли 502-я ошибка при получении с сервера статических файлов — картинок или css-стилей.

0

Автор публикации

не в сети 2 недели

Anton Bannikov

0
Дипломированный php-программист, linux и open source-энтузиаст. Разработчик запатентованной программы расчета физико-химических свойств солей. Опыт работы с языками программирования ~25 лет, опыт работы с сайтами ~ 21 год, опыт программирования на языке php ~17 лет. Опыт программирования на языке JS ~14 лет. Разработчик антивирусного сканера (php/jquery) и участник проекта быстрого интернет-магазина "F-Shop" (php/jquery).
Комментарии: 1Публикации: 36Регистрация: 10-06-2017

Написать комментарий

Авторизация
*
*
Регистрация
*
*
*
Пароль не введен
*
Генерация пароля