Веб-серверы Nginx и Apache мало похожи друг на друга, и их отличия касаются не только особенностей подключения пользователей, но и обработки URL на сервере. Очень часто новые пользователи Nginx получают ошибку 404 для URL, которые, по сути, должны были бы работать.
В этой статье рассмотрим, почему возникает ошибка “404 not found Nginx”, а также способы её устранения и отладки.Мы не будем разбираться с ситуацией, когда файла действительно нет на сервере – это решение, не требующее пояснений. Мы рассмотрим проблему обработки location в Nginx.
Почему возникает ошибка 404 в Nginx
Давайте сначала разберёмся, как обрабатываются URL в Nginx. Когда веб-сервер определил, к какому блоку server (сайту) нужно передать запрос пользователя, просматриваются все префиксные блоки location и выбирается тот, который подходит лучше всего. Например, рассмотрим стандартную конфигурацию для WordPress. Здесь префиксные location отмечены зелёным, а с регулярным выражением – оранжевым:
location / <
index index.html index.php;
>
location /favicon.ico <
access_log off;
>
location
* .(gif|jpg|png)$ <
expires 30d;
>
location
.php$ <
fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
include fastcgi_params;
>
Префиксные локейшены всегда начинаются с символа /. Регулярные же содержат символы регулярных выражений:
$ ^ * и так далее. Если пользователь запрашивает favicon.ico, то будет выбран второй location, так как он лучше всего соответствует запросу, при любом другом запросе будет выбран location /, так как он соответствует всем запросам, а других префиксных location у нас нет. Это просто, а дальше начинается магия. После того, как был найден нужный location, Nginx начинает проверять все регулярные выражения в порядке их следования в конфигурационном файле.
При первом же совпадении Nginx останавливает поиск и передаёт управление этому location. Или, если совпадений не было найдено, используется ранее обнаруженный префиксный location. Например, если запрос заканчивается на .php, то первый location будет проигнорирован, а управление передастся четвёртому (
Таким образом, любое неверно составленное регулярное выражение в любой части конфигурационного файла может полностью всё сломать. Поэтому разработчики рекомендуют по минимум использовать регулярные выражения. Что касается вложенных location, то обрабатываются они так же как и основные, только уже после передачи управления в нужный location. Путём чтения конфигурационного файла понять, какой location вызывает 404 сложно, поэтому, чтобы исправить ошибку, нам понадобиться режим отладки Nginx.
Как включить режим отладки Nginx?
Сначала нам необходимо установить версию Nginx с поддержкой отладки. Чтобы проверить, поддерживает ли ваша текущая версия этот режим, наберите:
В выводе должна быть строчка “–with-debug”. Если её нет, значит отладка не поддерживается, и надо установить версию с поддержкой. В CentOS такой пакет называется nginx-debug. Для его установки наберите:
sudo yum install nginx-debug
Теперь появился ещё один исполняемый файл, и он собран уже с поддержкой отладки:
Откройте конфигурационный файл вашего сайта или глобальный конфигурационный файл, если вы не задавали настройки логов отдельно для каждого сайта, и в конце стоки error_log замените error на debug:
error_log /var/log/nginx/domains/test.losst.ru.error.log debug
Останавливаем обычную версию и запускаем версию с отладкой:
systemctl stop nginx
systemctl start nginx-debug
Как исправить “404 Not Found Nginx”?
1. Регулярные выражения
Как я уже сказал выше, самой частой проблемой, которая вызывает 404, являются регулярные выражения. Смотрим, что происходит в лог файле:
tail -f /var/log/nginx/domains/test.losst.ru.error.log
Видим, что серверу пришёл запрос /vstats. Дальше он проверяет location: /, /robots.txt, /vatsts/, /site-control/. Здесь уже можем понять, в чём проблема – промазали на один слеш. Дальше проверяются все регулярные выражения, и, так как в них ничего найдено не было, выбирается location /.
Далее директива try_files пытается найти файл /vstats, не находит и ищет index.php, который, в свою очередь, возвращает 404.
Если мы наберём, то что ожидает видеть Nginx – /vstats/, то откроется наша страница статистики.
Если мы добавим к конфигурационному файлу ещё один location с регулярным выражением, например:
То абсолютно все запросы будут обрабатываться именно этим регулярным выражением и, естественно, что ничего работать не будет. Видим, что приходит запрос /vstats/:
Он совпадает с префиксным location, но потом Nginx видит наше регулярное выражение и передаёт управление ему.
Поэтому будьте очень осторожны с регулярными выражениями, если они вам нужны, то размещайте их только внутри префиксных location, чтобы ограничить их область действия этим location, иначе может возникнуть ошибка 404 nginx.
2. Недостаточно памяти
Если php-скрипту не хватило оперативной памяти для выполнения, и его процесс был убит операционной системой, то Nginx тоже может вернуть ошибку 404. Такое поведение вы будете наблюдать, когда скрипт очень долго выполняется, а потом появляется “404 Not Found” или страница ошибки вашего движка. Обычно эта неисправность тоже видна в отладочном логе.
Решить такую проблему можно, освободив память на сервере, часто такое может возникать из-за утечек памяти в php, когда процессы php-fpm занимают почти всю память на сервере. Поэтому перезапуск php-fpm решает проблему:
systemctl restart php-fpm
Чтобы избежать этой проблемы в будущем, можно настроить автоматический перезапуск процессов после обработки определённого количества запросов. Например каждые 200 запросов:
3. Не найден index
Если вы запрашиваете URL вида /vstats/, но в настройках Nginx не указан файл index, который нужно использовать для этой ссылки, то у вас ничего не выйдет, и вы получите 404. Вы можете добавить директиву index в ваш location:
location / <
index index.php index.html index.htm;
>
Или сразу в server, в Nginx все location наследуют директивы, установленные в server.
4. Другие проблемы
Подобных проблем, вызывающих 404 в Nginx, может быть очень много, но все они решаемы, и всё, что нужно для их решения, есть в отладочном логе Nginx. Просто анализируйте лог и на основе этого вносите исправления.
Выводы
В этой статье мы рассмотрели основные причины, из-за которых может возникнуть ошибка 404 not found Nginx. Как видите, может быть много проблем, но всё достаточно просто решается. А с какими проблемами, вызывающими эту ошибку, вы сталкивались? Как их решали? Напишите в комментариях!