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

Libxml чтоб его так

Вчера наконец разобрался с давно нервировавшм меня косяком. Косяк в том, что simplepie отказывался нормально тянуть фиды. Проявлялось причем на всем - как на обычном вордпрессовоском агрегаторе, который виджет, так и на feedwordpress и wp-o-matic. То есть тянуть то он их тянул, но при этом коцал тэги < > & - в таком духе. Естественно, часть фидов превращалась в какую-то хренотень, потому что хтмл-разметка лезла в текст. Самое сложное как всегда было найт причину. А она в том, что libxml, начиная с версии 2.7.0 коцал эти тэги. Баг типа вылечен в версии 2.7.2, как заявляется. Но на самом деле это не так. Лечение работает только для php 5.2.8, а для более ранних версий - хрен. Пришлось пересобрать апач с похапе 5.2.8 и либхмл 2.7.3. Попутно стало понятно, что на whm+nginx автоапдейт с easyapache не работает. Чтобы заработал, надо убрать Main >> Service Configuration >> Apache Setup > Include Editor > Pre Main Include, пересобрать и после этого запихать скрипт обратно. Естественно, перед этим надо /usr/local/apache/bin/apxs -i -c -n mod_rpaf-2.0.so mod_rpaf-2.0.c

Aнализ нагрузки веб-сервера

Колдунства для анализа нагрузки веб-сервера. Чел писал для борьбы с ДДОСами, но пригодится и в более мирных случаях.

Число процессов Apache:
ps aux | grep httpd |wc -l

Число коннектов на 80 порт:
netstat -na | grep :80 | wc -l

То же, в статусе SYN
netstat -na | grep :80 | grep syn

Пример SYN-флуда:
netstat -na | grep :80 | grep SYN | wc -l 767

Посмотреть много ли разных IP:
netstat -na | grep :80 | grep SYN | sort -u | more

На какой домен чаще всего идут запросы:
tcpdump -npi eth0 port domain

Статус Apache:
apachectl status

Посмотреть откуда IP:
whois xxx.xxx.xxx.xxx

или
jwhois xxx.xxx.xxx.xxx

С какого IP сколько запросов:
netstat -na | grep :80 | sort | uniq -c | sort -nr | more

Установка 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
И - вуаля! На всякий случай стоит проверить поведение сервера после ребута.
Результаты можете оценить сами.