Практическое применение nginx на отдаче статики




Возможно эта статья ниочем, подумал я. Но тут намедни вопросы появились насчет разделения front-back отдачи контента. И я понял что есть еще люди… :) И они всегда будут. А значит есть о чем написать.

Все знают наш любимый и почитаемый веб сервер Apache. К сожалению время его сделало до такой степени “навороченым”, что порой поражаешься сколько памяти и ресурсов вообще он может кушать на довольно простых задачах. И иногда сервер просто не справляется с нагрузкой (в основном не хватает памяти).

Нужно констатировать факт — Apache совершенно неэкономно расходует память при отдаче статического контента (картинки, HTML файлы, стили и т.д. — любой контент, который не содержит в себе серверного кода).

Благо есть с чем сравнить. Уже давно появился легкий веб-сервер Nginx. Он написан изначально оптимизированным под отдачу статики и, в сравнении с Apache, совершенно не расходует память. И везде, где только можно кусок памяти временно скинуть на диск, он это делает не выедая лишних системных ресурсов.

Но Nginx не содержит каких либо модулей для обработки динамического контента (кроме SSI). Он может только “проксировать” (передавать) обработку контента “бекенду” — собранному на заднем плане обработчику динамики Apache (или любому другом веб серверу). Так же Nginx умеет общаться с Fast-CGI сервером на бекенде.

Вот здесь и начинается разделение на FrontEnd и BackEnd отдачи. Смысл очень простой — мы каждому предоставляем делать только то, что он хорошо умеет делать и ничего больше. Nginx стоит на фронте и принимает запросы от клиентов. Из них он ловит запросы к статическому содержимому и немедля это содержимое отдает. Запросы же к динамическому (или потенциально динамическому контенту), Nginx проксирует на Бекенд, на котором предположительно стоит Apache и обрабатывает запросы к динамическому контенту (например, PHP-скриптам). Результат отдается обратно к Nginx, которую в свою очередь, возвращает ответ клиентам.

Вырисовывается такая схема:
nginx-apache1

Таким образом, еще говорят, можно “облегчить апач”, т.е. существующий Apache поставить на бекенд, а перед ним на фронте поставить Nginx. При этом обычно апач переводят слушать какой то порт на 127.0.0.1 и туда направляют проксирующие запросы Nginx.

Если ваш одинокий Apache до этого сильно грузил сервер и у вас действительно есть что “облегчить” (т.е. много статического содержимого), то разница будет ощутима визуально и нагрузка сервера серъезно просядет.

Теперь к практике.

Облегчение нагрузки Apache с помощью Nginx.

Допустим, уже стоит и работает Apache, который испытывает перегрузки.

Первое что нужно сделать, это перевести VirtualHost’ы апача куда нибудь на 127.0.0.1. Например, было:

Listen 123.123.123.123
NameVirtualHost 123.123.123.123
<VirtualHost 123.123.123.123>
ServerName foobar.com
ServerAlias www.foobar.com
DocumentRoot /home/www/foobar.com…..SOME STUFF…..

</VirtualHost>

Теперь переводим апач на бекенд, а на фронт ставим Nginx. Таким образом, для внешнего клиента ничего якобы не меняется.

Listen 127.0.0.1
NameVirtualHost 127.0.0.1
<VirtualHost 127.0.0.1>
ServerName foobar.com
ServerAlias www.foobar.com
DocumentRoot /home/www/foobar.com…..SOME STUFF…..

</VirtualHost>

Стоит заметить, что если другие виртуалхосты так же слушают на айпи 123.123.123.123, то их либо нужно тоже переместить на бекенд, либо поместить на другой айпи, поскольку nginx и apache не могут слушать на одном и том же айпи на 80 порту.

Далее, предполагается, что nginx уже установлен — не вижу ничего сложного в этой процедуре.

Помещаем nginx на фронт:

nginx.conf:
….
server {
listen 123.123.123.123;
server_name foobar.com www.foobar.com;
# устанавливаем отдачу статики
# сюда можно добавить другие расширения файлов
# которые будет отдавать nginx
location ~* \.(jpg|jpeg|gif|png|ico|css|bmp|js|swf)$ {
root /home/www/foobar.com;
}

# Не забываем закрыть .htacces’ы
location ~ /\.ht {
deny all;
}location / {
#Все остальное отдаем апачу
proxy_pass http://127.0.0.1:80;
proxy_redirect off;
proxy_set_header Connection close;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass_header Content-Type;
proxy_pass_header Content-Disposition;
proxy_pass_header Content-Length;
}
}

Для FreeBSD так же можно указать ацепт фильтр в директиве listen:

listen 123.123.123.123 default accept_filter=httpready;

Это делается для одного сервера на один айпи. На все остальные так же распространяется. Указанный сервер будет помечен как дефолтный (если клиент указывает левый “Host:” хидер или не указывает его вообще — прямое обращение по айпи).

Зачем нужен accept filter? Когда ядро принимает новый коннекшин без ацепт фильтра, оно сразу же передает коненкшин веб серверу с помощью системного вызова accept(). С ацепт фильтром accept() происходит только тогда, когда клиентом были посланы все HTTP-заголовки. Помогает при SYN-флуде. Требует модуль ядра accf_http:

# kldload accf_http

Корректная обработка айпи клиента.

Все бы хорошо, только скрипты апача будут всегда видеть айпи клиента как 127.0.0.1 — айпи, с которого проксирует nginx. Для фикса этой проблемы можно использовать mod_realip для apache v1 или mod_rpaf для apache любой версии .

Оба этих модуля делают одно и тоже — смотрят в хидер “X-Real-IP: “, который передает nginx и меняют на соотв. айпи env переменную REMOTE_ADDR.

При использовании mod_rpaf необходимо прописать в виртуалхост на бекенде:

RPAFenable On
RPAFsethostname On
RPAFproxy_ips 127.0.0.1
RPAFheader X-Real-IP

В принципе, все. Теперь скрипты будут работать корректно и в логах апача будет корректный айпи клиента. Можно пошаманить с другими параметрами http и listen Nginx’а.

Так же не рекомендуется использовать заголовок “X-Forwarded-For” для передачи айпи, т.к. некоторые скрипты предпринимают попытку определения прокси клиента. В этом случае для них все клиенты будут якобы с прокси.

Использование Fast-CGI сервера в Nginx.

Существует определенная категория анти-фанатов Apache, которая вообще принципиально отказывается от Apache. PHP-скрипты отдаются на обработку FastCGI серверу, который заменяет собой Apache.

Наиболее популярным FastCGI сервером для PHP я считаю PHP-FPM (http://php-fpm.anight.org/).

PHP-FPM обладает некоторыми преимуществами перед апачем:

* Можно настроить обработку динамики каждого Vhost’а из под другого юзера
* Можно настроить прием соединений через Unix socket (о! не пробуйте это делать на нагруженой файловой системе — время отклика серъезно пострадает)
* Можно настроить chroot в заданную директорию для каждого виртуалхоста
* Каждому Vhost’у отделить фиксированное количество воркеров. Не больше. Но и не меньше.

С точки зрения производительности, очевидность преимущества FPM перед Apache, на мой взгляд, сомнительна. К тому же, как показывает практика, FPM ведет себя весьма плохо, если max_children выставлено неоптимально. А динамически ее конфигурировать FPM на данный момент не умеет.

Советую ставить FPM, если вы точно знаете что делаете и уже потестировали и “поигрались” с ним.

Итак, конфигурация nginx для обработки PHP-скриптов (вместо location / в предыдущем примере):

location / {
# Передавать соединения через UNIX socket
fastcgi_pass unix:/tmp/php.sock;
# Так же можно передавать через TCP:
# fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME /home/www/foobar.com$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_read_timeout 31;
fastcgi_send_timeout 31;
}

Надеюсь, я ничего не забыл из fastcgi_param :) Хотя обычно этого достаточно. Вообще конечно желательно fastcgi настроить прямо на локейшин “location ~* \.php$”. Ну в общем тут нужно покумекать в зависимости от запросов сайта.

Далее, установите патч PHP-FPM. На данном этапе лучше компилировать php в какой то свой $PREFIX:

./configure \
–prefix=/usr/local/fpm \
–enable-fastcgi \
–enable-fpm \
…другие параметры…

Содержимое $PREFIX/fpm/etc/php-fpm.conf обычно подходит стандартное с некоторыми поправками. Предполагается что будет только 1 пул воркеров. Директивы, на которые стоит обратить внимание:

#Для приема соединений на UNIX socket
<value name=”listen_address”>/tmp/php.sock</value>
#Для приема соединений на TCP socket
<value name=”listen_address”>127.0.0.1:9000</value>
# Кхе… Директива listen_address может быть только одна в пуле… Хотя могу и ошибаться.
# Юзер и группа пула
<value name=”user”>nobody</value>
<value name=”group”>nobody</value>
# Тип IPC — статический
<value name=”style”>static</value>
# Количество воркеров
<value name=”max_children”>5</value>

На остальное можно обращать внимание, а можно и не обращать )

Запускается это все дело командой

# $PREFIX/fpm/bin/php-cgi –fpm

Ну в принципе, бекенд готов. Можно запускать и тестировать. Таким же образом можно поставить любой другой FastCGI обработчик “за спиной” у nginx. Смысл в любом случае простой — каждый делает то, что он умеет хорошо делать, в результате все делается так как надо :)

Взято с http://www.pentarh.com/wp/2008/07/18/using-nginx-apache/#more-15

Popularity: 5%



Этот материал находится на сайте http://compiling.ru
__________________________________________



Похожие посты:


  • Nginx Catch-All Host As Front End To Apache For ISPConfig 3 On Debian Lenny
  • Nginx Catch-All Host As Front End 3, Configure Nginx
  • Drupal 6 Hosting With nginx And PHP-FastCGI. Part 4
  • У NGINX появилась коммерческая техподдержка
  • Обновление NGINX 1.2.0 улучшит поддержку прокси



  • Опубликовано 04 Июн 2009 в 23:46. В рубриках: Optimization. Вы можете следить за ответами к этой записи через RSS 2.0. Отзывы и пинг пока закрыты.

    Один отзыв на “Практическое применение nginx на отдаче статики”

    1. Быстрая и эффективная оптимизация сервера 25 Мар 2010 в 07:36

      [...] Хорошая статья по nginx для новичков типа меня [...]

    Партнёры:


    forum.vpnssl.ru

    Выбор решений, консультации, примеры.

    Есть вопрос! Оставь свой голос!

    Question:

    Что нужно админу для счастья?

    View Results

    Loading ... Loading ...




    Most Popular Posts



    Supported:

  • все о создании сайта .


  • free counters