Echo 404 напрямую из nginx для улучшения производительности
Я отвечаю за производственные серверы, обслуживающие статический контент для веб-сайта. Эти серверы постоянно просматриваются ботами, которые ищут потенциальные эксплойты (что не является большой проблемой с точки зрения безопасности, поскольку ни одно приложение не может быть доступно за веб-сервером), но генерирует тысячи 404
в день, иногда в час. Я ищу способы блокировать эти запросы, но это сложно (вы хотите убедиться, что вы не блокируете законный трафик, и эти боты становятся все более и более умными в том, чтобы выглядеть так, как будто они законны), и это займет у меня некоторое время найти приемлемое решение.
В то же время я хотел бы уменьшить влияние производительности 404
страницы. На самом деле мы используем nginx
который по умолчанию настроен на обслуживание это 404
страницы с диска (это можно изменить с помощью error_page
директива, но в конце концов 404
нужно будет либо обслуживать с диска, либо из другого внешнего источника (например, из вышестоящего приложения, что было бы хуже), что не идеально.
Я провел тест с ab
на моей локальной машине с базовой конфигурацией: в одном случае я echo
сообщение непосредственно от nginx
так что диск вообще не трогается, в другом случае я попал на недостающую страницу и nginx
служит своим 404
с диска.
server {
# [...] the default nginx stuff
location / {
}
location /this_page_exists {
echo "this page was found";
}
}
Вот результаты теста (на моем ноутбуке установлен Intel(R) Core(TM) i7-2670QM + SSD на случай, если вам интересно, почему они такие высокие):
$ ab -n 500000 -c 1000 http://localhost/this_page_exists
Requests per second: 25609.16 [#/sec] (mean)
$ ab -n 500000 -c 1000 http://localhost/this_page_doesnt_exists
Requests per second: 22905.72 [#/sec] (mean)
Как видите, возвращая значение с echo
является 11%
((25609−22905)÷22905×100) быстрее, чем обслуживать 404
страница с диска. Соответственно хотелось бы echo
просто 404 Page not Found
строка из nginx
,
До сих пор я пробовал много вещей, но все они потерпели неудачу, по сути, идея заключалась в следующем:
location / {
try_files $uri @not_found;
}
location @not_found {
echo "404 - Page not found";
}
Проблема в том, что как только echo
директива используется, http response code
установлен в 200
, Я пытался изменить это, делая error_page 200 = 400
но это нарушает конфигурацию.
Как я могу служить 404
страница прямо из nginx? (без взлома источника, который может быть следующим шагом)
2 ответа
На самом деле, по умолчанию nginx генерирует ответ 404 внутри. Он подает файл с диска только в том случае, если вы указали это с помощью директивы error_page. Если вы хотите контролировать формат страницы 404, а не echo "404 - page not found";
, ты можешь использовать return 404 "404 - page not found";
(Предполагается, что вы используете несколько новую версию nginx, я считаю, что вам нужно 0.9 или новее)
Nginx echo module is what you need. But you should use it with error_page:
error_page 404 @echo_404;
location @echo_404 { echo "Not found"; }
Вы можете заставить nginx закрыть активное соединение, вернув 444:
return 444;
Это немедленно закроет сокет, ничего не записав в сеть.
Разница в ваших вычислениях заключается только в том, что open_file_cache не был включен. Если вы хотите, чтобы это пошло быстрее, настройте вашу систему: примите фильтры, очередь сокетов и буферы и так далее.