В последнее время я не занимаюсь активным программированием, однако поддерживать свой сервер и размещенные на нем сайты приходится. Уже с 2003-го года мы с друзьями держим выделенный, арендованный сервер в Америке, на котором размещен Сервер христианского общения JesusChrist.ru, Молитва.ру, а также другие сайты, включая этот блог timh.ru. Посещаемость на одном только JesusChrist.ru за последние годы выросла с 2000 человек в день в 2005-м году до 6000 человек в день в 2009-м году. Такое количество людей пока не создает нам проблем. Но вот поисковые роботы при каждом посещении нашего сервера создают огромную нагрузку. Бывает, что 200 роботов с Yahoo работают одновременно, забивая память сервера так, что обычные посетители уже не могут открыть ни одной странички. Получается своего рода DoS-атака, санкционированная поисковиком и вызванная тем, что у нас много страниц на сервере.
Мы уже думали купить дополнительно оперативной памяти, но это стоит дорого, а на улице кризис. Поэтому решили пойти другим путем. Главным потребителем памяти на любом веб-сервере, конечно, является сам веб-сервер (тавтология получается какая-то), а у нас используется Apache. После некоторых исследований я решил попробовать nginx. И вот что получилось…
Сначала несколько слов о nginx. Этот софт для обслуживания веб-серверов написан российским программистом Игорем Сысоевым, когда он работал в компании Рамблер (работает ли он сейчас там, я не знаю). Nginx написан специально для часто посещаемых, популярных сайтов (а Рамблер один из таковых, хотя я предпочитаю ему Яндекс). Это очень легковесный софт, главная задача которого – получить данные из внутреннего, более тяжелого сервера, и быстро отдать клиенту. В моем случае тяжелый сервер это многофункциональный Apache.
В обычной схеме работы любой посетитель сайта провоцирует запуск отдельной копии Апача, который создает страницу и отдает посетителю, а затем ждет закрытия соединения, даже если посетитель больше ничего не запросит с сайта (таких посетителей, обычно пришедших с поисковых машин, пока что большинство). А висячий в памяти процесс Apache это дополнительные расходы. Если 200 роботов с Yahoo зайдут одновременно, то вся память расходуется сразу. 200 х 16 Мбайт это уже будет почти 3.2 Гбайта, а у нас только 2 Гбайта на сервере. Сервер начинает часто использовать файл подкачки и долго не может выйти из такого перегруженного состояния.
Nginx же получает данные от Apache сам, упаковывает их и быстро отдает клиенту. Apache может никого не ждать, или даже если он будет ждать, то новая копия процесса не нужна для обслуживания другого клиента (теперь уже клиента nginx). Насколько я понял, nginx сам оптимальным образом распоряжается соединениями и запущенными им копиями Apache. Так, нагрузка на сервере становится приемлемой практически в любое время суток.
Как же быстро перейти с Apache на nginx? В Интернете есть много рецептов, одни простые, другие сложные, с использованием всех возможностей nginx. Но лучше попробовать сначала следующий простой вариант.
Во-первых, ничего не меняйте в настройках Апача, кроме номера порта. Поменяйте везде в httpd.conf (и других файлах, если есть) номер порта с 80 на 8080 (и с 443 на 8443, если вы используете SSL). То есть запись “Listen 132.233.134.235:80″ превратится везде в “Listen 132.233.134.235:8080″, “NameVirtualHost 80″ в “NameVirtualHost 8080″, а “<VirtualHost *:80>” в “<VirtualHost *:8080>”.
Во-вторых, настраиваем nginx как прозрачный прокси. В nginx.conf надо закомментировать настройки по умолчанию, приведенные разработчиками в качестве примера, и сделать свои:
server { listen 132.233.134.235:80; # после слова alias можно указать ВСЕ домены # если они все указывают на один IP server_name localhost alias vash-domen.ru www.vash-domen.ru vash-domen2.ru www.vash-domen2.ru vash-domen3.ru www.vash-domen3.ru ; location / { proxy_pass 132.233.134.235:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
После этого перезапускаете Apache, который теперь слушает запросы на порте 8080, и запускаете nginx, который встает на порт 80, и все дела! Вот таким образом русский nginx помог индейцу Apache на нашем сервере.
P.S.: Конечно, можно было бы подробнее рассказать об установке самого nginx, но ставится он легко, прямо из исходников. Читайте документацию на nginx.net, а также хорошую статью в Википедии.
3 комментариев
nginx и KeepAlive
Одним из способов для оптимизации соединения в Apache это KeepAlive On/Off в httpd.conf. Через открытое соединение гоняются все файлы, связанные со страницей или веб-сайтом, вместо того, чтобы грузить для каждого файла отдельную копию Apache.
С другой стороны, если клиент посетит только одну страницу, а потом отключится, то копия Apache останется висеть в памяти. Если же KeepAlive в Off, то возвращаемся к исходному состоянию. Тупик выходит.
А в nginx обнаружился параметр keepalive_requests. Игорь Сысоев в рассылке советует использовать keepalive_requests 5; keepalive_timeout 15; например. Как я понимаю, это означает, что keepalive будет не для всех, а только кому надо. Как это nginx определяет, не знаю – надо будет почитать.
Если nginx работает с Apache, то KeepAlive в самом Apache отключите напрочь. Как пишут, nginx работает по протоколу HTTP 1.0 с бэк-ендом (Apache).
Re: nginx и KeepAlive
См. http://www.google.com/search?q=nginx+apache+KeepAlive
Re: nginx и KeepAlive
Ан-нет, keepalive_requests не такой умный, как я написал. Но остальное – правильно.
http://wiki.nginx.org/NginxHttpCoreModule#keepalive_requests
Number of requests which can be made over a keep-alive connection.