Сюда обычно чего-то пишут. Но меня ломает...

Установка Nginx как фронтенда к Apache на сервер c WHM/Cpanel

Меня окончательно утомили тормоза апача на моем ВДС (700 метров памяти, центос-5, whm/cpanel, апач 2.2, куплен в ТекТонике, рекомендую). Причина банальна - выжирание памяти апачем при довольно смешной нагрузке в 2-2.5 тысячи пользователей в день. Тюнинг maxclients помог, но не сильно (зарежешь число клиентов чтобы стало больше свободной памяти - начинаются еще более страшные тормоза).

Поэтому было принято дальше кота за яйца не тянуть и перейти на схему с фронтендом на Nginx и бэкэндом на апаче. Схема давно стала фактически индустриальным стандартом для тяжело нагруженных серверов, для тех, кто в танке вот тут человеческим языком объясняется почему такая схема эффективна.

Основная проблема заключалась в том, что прикрутить надо было не к голому серверу, а установленной панельке WHM/Cpanel, что поначалу казалось непросто. За основу был взят вот этот мануал, но в нем многое было не описано, подразумевалось, что ты, типа, старый линуксоид, и тебе и так все понятно. Я же опишу для идиотов, типа себя, чтобы потом  не забыть.

Начать надо с установки mod_rpaf на апач. Он нужен для того, чтобы апач получал правильные адреса посетителей от nginxa.

Логинимя под рутом, далее

cd /root/tmp
mkdir mod_rpaf
cd mod_rpaf/
wget http://stderr.net/apache/rpaf/download/mod_rpaf-0.6.tar.gz
tar xzf mod_rpaf-0.6.tar.gz
cd mod_rpaf-0.6
/usr/local/apache/bin/apxs -i -c -n mod_rpaf-2.0.so mod_rpaf-2.0.c

Последняя строчка собственно устанавливает модуль.
Теперь надо прописать настройки модуля. Идем в WHM,  Main >> Service Configuration >> Apache Setup > Include Editor > Pre Main Include и вставляем там приведенный код:

LoadModule rpaf_module modules/mod_rpaf-2.0.so

RPAFenable On
# Enable reverse proxy add forward
RPAFproxy_ips 127.0.0.1 LIST_OF_YOUR_IPS
# which ips are forwarding requests to us
RPAFsethostname On
# let rpaf update vhost settings
# allows to have the same hostnames as in the “real”
# configuration for the forwarding Apache
RPAFheader X-Real-IP
# Allows you to change which header mod_rpaf looks
# for when trying to find the ip the that is forwarding
# our requests
List_of_your_IPs меняем на список купленных к серверу адресов, через пробел. Жмем сохранить, перезапустить апач. Ахтунг! при докупке свежих IP их всех нужно будет потом руками прописывать в этом месте
Теперь нам надо перетащить апач на какой нибудь другой порт, например 81, потому что на стандартный 80 порт мы будем сажать nginx. Для этого в WHM идем в Tweak settings и правим порт на котором висит апач - 0.0.0.0:80 на 0.0.0.0:81. Жмем “apply” - ответа мы уже не дождемся, порт поменян. При необходимости можно зайти по http://whm.че-то-там.com:81
Обратите внимание, что https мы не переносим. Если есть желание, можно попробовать перенести и его за nginx, но особо смысла не вижу.
Возвращаемся в консоль - нам надо поправить настройки prefork’a в конфиге апачи.
Для начала убедитесь, что у вас используется именно prefork, используя:
httpd -V | grep MPM

Поравьте соответствующий раздел конфига

vi /usr/local/apache/conf/httpd.conf,

поправьте на что-то вроде этого:
<IfModule prefork.c>
StartServers 5
MinSpareServers 5
MaxSpareServers 5
MaxClients 100
MaxRequestsPerChild 100
</IfModule>
Если у Вас worker, то раздел, естественно, другой.

Теперь нужно конфиг продистилировать скриптами WHM, чтобы он нормально прососался:
/usr/local/cpanel/bin/apache_conf_distiller –update –main
/scripts/rebuildhttpdconf
поправтье номер порта 80 на 81 в настройках сервиса мониторинга
vi /etc/chkserv.d/httpd
и перезапустите его:
/etc/init.d/chksrvd restart
или
/etc/init.d/chkservd restart
сервис  может называться по разному, в крайнем случае ребут вас спасет.
На этом с апачем мы закончили, ставим nginx (по мотивам отсюда):
Нам понадобится компилятор, ставим его если еще нет:
yum -y install gcc pcre-devel zlib-devel
Скачиваем и распаковываем nginx:
mkdir /root/tmp/nginx
cd /root/tmp/nginx
wget http://sysoev.ru/nginx/nginx-0.6.35.tar.gz
tar xzf nginx-*.tar.gz
cd nginx-*/

Устанавливаем:
./configure
make
make install
ln -s /usr/local/nginx/conf /etc/nginx
Прописываем ротацию логов:
vi /etc/logrotate.d/nginx
туда:
/usr/local/nginx/logs/*log {
daily
rotate 7
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
/bin/kill -USR1 `cat /usr/local/nginx/logs/nginx.pid` 2> /dev/null || true
endscript
}

Делаем инит-скрипт:
vi /etc/init.d/nginx
туда:
#!/bin/sh
#
# Init file for nginx server daemon
#
# chkconfig: - 85 15
# description: nginx server daemon
#

bin=’/usr/local/nginx/sbin/nginx’
pid_file=’/usr/local/nginx/logs/nginx.pid’

case “$1″ in
start)
echo -n “Starting nginx: ”
$bin && echo OK || echo FAILED
;;

stop)
echo -n “Stopping nginx: ”
kill `cat $pid_file` && echo OK || echo FAILED
;;

configtest)
$bin -t
;;

reload)
echo -n “Reloading nginx: ”
kill -HUP `cat $pid_file` && echo OK || echo FAILED
;;

restart)
$0 stop
sleep 1
$0 start
;;

*)
echo “Usage: $0 {start|stop|restart|reload|configtest}”
exit 1
;;
esac

Добавляем права на выполнение:
chmod +x /etc/init.d/nginx
и прописываем автозагрузку (runlevel 3)
ln -s ../init.d/nginx /etc/rc3.d/S99nginx
Теперь нам надо прицепить скрипт, который генерит конфиги nginxa на основании насроек whm. Мы запихаем его в /scripts/postwwwacct, чтобы он обновлял конфиги после каждого добавления аккаунта:
vi /scripts/postwwwacct
туда:
#!/bin/sh

cat > “/usr/local/nginx/conf/nginx.conf” <<EOF
user  nobody;
worker_processes  2;

error_log  logs/error.log info;

worker_rlimit_nofile  8192;

events {
worker_connections  512; # increase for more busy servers
use rtsig; # you should use epoll here for Linux kernels 2.6.x
}

http {
server_names_hash_max_size 2048;

include    mime.types;
default_type  application/octet-stream;

sendfile on;
tcp_nopush on;
tcp_nodelay on;

keepalive_timeout  10;

gzip on;
gzip_min_length  1100;
gzip_buffers  4 32k;
gzip_types    text/plain text/html application/x-javascript text/xml text/css;
ignore_invalid_headers on;

client_header_timeout  3m;
client_body_timeout 3m;
send_timeout     3m;
connection_pool_size  256;
client_header_buffer_size 4k;
large_client_header_buffers 4 32k;
request_pool_size  4k;
output_buffers   4 32k;
postpone_output  1460;

include “/usr/local/nginx/conf/vhost.conf”;
}

EOF

/bin/cp /dev/null /usr/local/nginx/conf/vhost.conf

cd /var/cpanel/users
for USER in *; do
for DOMAIN in `cat $USER | grep ^DNS | cut -d= -f2`; do
IP=`cat $USER|grep ^IP|cut -d= -f2`;
ROOT=`grep ^$USER: /etc/passwd|cut -d: -f6`;
echo “Converting $DOMAIN for $USER”;

cat >> “/usr/local/nginx/conf/vhost.conf” <<EOF
server {
access_log off;

error_log  logs/vhost-error_log warn;
listen    80;
server_name  $DOMAIN www.$DOMAIN;

# uncomment location below to make nginx serve static files instead of Apache
# !WARNING!
# it will make the bandwidth accounting incorrect as these files won’t be logged!
#location ~* .(gif|jpg|jpeg|png|wmv|avi|mpg|mpeg|mp4|htm|html|js|css)$ {
# root   $ROOT/public_html;
#}

location / {
client_max_body_size    10m;
client_body_buffer_size 128k;

proxy_send_timeout   90;
proxy_read_timeout   90;

proxy_buffer_size    4k;
# you can increase proxy_buffers here to suppress “an upstream response
#  is buffered to a temporary file” warning
proxy_buffers     16 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;

proxy_connect_timeout 30s;

proxy_redirect  http://www.$DOMAIN:81   http://www.$DOMAIN;
proxy_redirect  http://$DOMAIN:81   http://$DOMAIN;

proxy_pass   http://$IP:81/;

proxy_set_header   Host   $host;
proxy_set_header   X-Real-IP  $remote_addr;
proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
EOF
done
done
service nginx restart

Для ядра 2.6 нужно также поменять use rtsig на use epoll.
Если сервер лично ваш и/или вам пофиг на корректность отображения трафа в WHM/Cpanel, можно поставить nginx не только как реверс-прокси к апаче, но и как веб-сервер под статический контент - картинки, файлы и прочее и получить еще большее увеличение производительности. Для этого надо в скрипте раскомментировать строки:
#location ~* .(gif|jpg|jpeg|png|wmv|avi|mpg|mpeg|mp4|htm|html|js|css)$ {
# root   $ROOT/public_html;
В первый раз запустим генератор конфигурации руками (на первый запуск закомментируем в нем последнюю строку):
/scripts/postwwwacct
Теперь проверим, чего он нагенерил:
/usr/local/nginx/sbin/nginx -t
Стартуем nginx:
/usr/local/nginx/sbin/nginx
И - вуаля! На всякий случай стоит проверить поведение сервера после ребута.
Результаты можете оценить сами.

Материалы по теме

5 Каментов к статье “Установка Nginx как фронтенда к Apache на сервер c WHM/Cpanel”. Оставьте камент »

  1. Камент от Art — 2009/08/18 @ 20:45

    Статья супер! Впервые вижу так детально описанное решение по cpanel, которое немедленно можно использовать в работе. Относительно скрипта генерации виртуальных хостов к nginx - есть замечание.

    Если в субдоменах есть * (напр. *.domen.name) - тогда при выборке этого домена из настроек юзера и генерации для него конфига получаем такую запись: http://www.*.domen.name - на что nginx честно ругается:

    [emerg]: invalid server name or wildcard “www.*.domen.name” on 0.0.0.0:80

    Надо, наверное, проверять * и не генерировать для него вообще с префиксом www ни server_name, ни proxy_redirect.

  2. Камент от Art — 2009/08/18 @ 22:00

    И еще один момент - дополнительные домены - если раскомментировать отдачу статики - для них она отдаваться не будет вообще (404), т.к. root - не $ROOT/public_html, а $ROOT/public_html/some_add_domain_dir

  3. Камент от admin — 2009/08/19 @ 5:09

    Art, да, скрипт мной был честно утащен отсюда - http://figvam.blogspot.com/2008/05/using-nginx-to-accelerate-apache-on.html, чел его писал для сервачка под собственные нужды (как в общем то и я использую). Для multi-user, хостинга и т.п. стоит наверно поправить ;)

  4. Камент от Lest — 2010/02/19 @ 19:33

    Nginx можно настроить более универсально используя $host в proxy_pass и не забыв указать опцию resolver. Подробно написал у себя в блоге.

  5. Камент от Lanselot — 2011/02/01 @ 13:39

    Для мультихостинга мне пришлось поломать голову и переписать скрипт с нуля.
    В итоге он учитывает все Addon, sub, parked domains и субдомены вида *.domain.com
    Вроде все учел.
    Правило proxy_backend введено для случаев rewrite_rule на html, например и прочие файлы, которых в действительности не существует, а php их генерирует.
    Подробнее тут:
    http://lanselot.me/2011/02/nginx-apache-and-cpanel/

RSS поток бредоспама. Трэкбэк адрес

Оставьте камент




Политика комментирования:

Как вы можете заметить, тут нет поля "сайт", бесполезно оставлять бессмысленные каменты ради ссылок.
Однако ссылки в теле комментариев, как, например вот эта, приветствуются и открыты для индексации.
Поэтому комментарии проходят ручную модерацию. Адекватные комментарии обычно апрувятся.