FastNetMon

среда, 10 ноября 2010 г.

Установка mod_vhost_limit на Debian 5 Lenny для лимитирования числа рабочих процессов для 1 виртуального хоста

Я ранее уже писал про эту штуку: http://phpsuxx.blogspot.com/2010/09/apache-modvhostlimit-worker-vhost.html

Итак, заранее предположим, что у нас есть настроенный префорк Апач.

Собираем:
cd /usr/src
wget http://fastvps.googlecode.com/svn/trunk/packages/mod_vhost_limit/mod_vhost_limit-0.2.tgz
tar -xf mod_vhost_limit-0.2.tgz
cd mod_vhost_limit-0.2
apt-get install -y apache2-prefork-dev

После этого нужно файлик compile.sh заменить на следующий (в исходном все пути забиты под CentOS):
libtool --silent --mode=compile gcc -g -O2 -pthread -DLINUX=2 \
-D_REENTRANT -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -D_SVID_SOURCE \
-I/usr/include/apache2 \
-I/usr/include/apr-1.0 \
-prefer-pic -c mod_vhost_limit.c && touch mod_vhost_limit.slo

libtool --silent --mode=link gcc -g -O2 -pthread -DLINUX=2 \
-D_REENTRANT -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -D_SVID_SOURCE \
-D_GNU_SOURCE -DAP_HAVE_DESIGNATED_INITIALIZER \
-I/usr/include/apache2 \
-I/usr/include/apr-1.0 \
-export-dynamic -o mod_vhost_limit.la -rpath /usr/lib/apache2/modules \
-module -avoid-version mod_vhost_limit.lo


rm -rf *.a *.la *.lo *.slo *.o
mv .libs/*.so .
rm -rf .libs

Итак, теперь компилируем:
./compile.sh

В результате этих манипуляций у нас должен получить вот такой вот бинарик:
ls -al mod_vhost_limit.so
-rwxr-xr-x 1 root root 30K 2010-11-10 06:16 mod_vhost_limit.so

Создаем папку для модуля:
mkdir /opt/mod_vhost_limit
mv mod_vhost_limit.so /opt/mod_vhost_limit

Далее конфигурируем Апача:
echo "LoadModule vhost_limit_module /opt/mod_vhost_limit/mod_vhost_limit.so" > /etc/apache2/mods-enabled/vhost_limit.load
echo "MaxVhostClients 10" > /etc/apache2/mods-enabled/vhost_limit.conf

Тестируем конфиг:
apache2ctl -t
Syntax OK

Убеждаемся, что модуль загрузился:
apache2ctl -M 2>&1 | grep vhost_limit
vhost_limit_module (shared)

Перезапускаем Апача для применения изменений:
/etc/init.d/apache2 restart

Тесты

Для начала откроем лог для просмотра диагностических сообщений от модуля:
tail -f /var/log/apache2/error.log

Теперь пробуем бомбануть какой-нибудь сайт 10 потоками, чтобы создать 10 воркеров.

ab -c 10 -n 1000 http://test.ru/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking test.ru (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software: nginx/0.6.32
Server Hostname: test.ru
Server Port: 80

Document Path: /
Document Length: 358 bytes

Concurrency Level: 10
Time taken for tests: 2.005 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Non-2xx responses: 1000
Total transferred: 694000 bytes
HTML transferred: 358000 bytes
Requests per second: 498.73 [#/sec] (mean)
Time per request: 20.051 [ms] (mean)
Time per request: 2.005 [ms] (mean, across all concurrent requests)
Transfer rate: 338.01 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 1
Processing: 2 10 89.3 3 2004
Waiting: 2 10 89.3 3 2004
Total: 3 10 89.3 4 2005

Percentage of the requests served within a certain time (ms)
50% 4
66% 4
75% 4
80% 4
90% 5
95% 5
98% 6
99% 7
100% 2005 (longest request)

То есть, получаем идеальные цифры (логи при этом идеально пусты):
Complete requests: 1000

Увеличиваем до 11 потоков и тут начинается работа модуля:
ab -c 11 -n 1000 http://test.ru/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking test.ru (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software: nginx/0.6.32
Server Hostname: test.ru
Server Port: 80

Document Path: /
Document Length: 323 bytes

Concurrency Level: 11
Time taken for tests: 2.004 seconds
Complete requests: 1000
Failed requests: 657
(Connect: 0, Receive: 0, Length: 657, Exceptions: 0)
Write errors: 0
Non-2xx responses: 1000
Total transferred: 640542 bytes
HTML transferred: 346176 bytes
Requests per second: 499.01 [#/sec] (mean)
Time per request: 22.044 [ms] (mean)
Time per request: 2.004 [ms] (mean, across all concurrent requests)
Transfer rate: 312.15 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 1
Processing: 1 12 113.7 3 2003
Waiting: 1 12 113.7 3 2003
Total: 1 13 113.7 4 2004

Percentage of the requests served within a certain time (ms)
50% 4
66% 5
75% 5
80% 5
90% 6
95% 6
98% 7
99% 8
100% 2004 (longest request)


Итого, пошел серьезный отбой запросов:
Complete requests: 1000
Failed requests: 657

Также в логе ошибок появились следующие записи:
[Wed Nov 10 06:31:16 2010] [warn] Vhost Limit : Access to test.ru deferred, Max Clients 10 exceeded (11 currently)
[Wed Nov 10 06:31:16 2010] [warn] Vhost Limit : Access to test.ru deferred, Max Clients 10 exceeded (11 currently)
[Wed Nov 10 06:31:16 2010] [warn] Vhost Limit : Access to test.ru deferred, Max Clients 10 exceeded (11 currently)
[Wed Nov 10 06:31:16 2010] [warn] Vhost Limit : Access to test.ru deferred, Max Clients 10 exceeded (11 currently)
[Wed Nov 10 06:31:16 2010] [warn] Vhost Limit : Access to test.ru deferred, Max Clients 10 exceeded (11 currently)
[Wed Nov 10 06:31:16 2010] [warn] Vhost Limit : Access to test.ru deferred, Max Clients 10 exceeded (11 currently)

Ура, ура :)

Далее увеличил лимит воркеров до сотни и прогнал нагрузочный тест в виде:
ab -c 100 -n 10000 http://test.ru/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking test.ru (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests


Server Software: nginx/0.6.32
Server Hostname: test.ru
Server Port: 80

Document Path: /
Document Length: 358 bytes

Concurrency Level: 100
Time taken for tests: 51.825 seconds
Complete requests: 10000
Failed requests: 19
(Connect: 0, Receive: 0, Length: 19, Exceptions: 0)
Write errors: 0
Non-2xx responses: 10000
Total transferred: 6940950 bytes
HTML transferred: 3583439 bytes
Requests per second: 192.96 [#/sec] (mean)
Time per request: 518.251 [ms] (mean)
Time per request: 5.183 [ms] (mean, across all concurrent requests)
Transfer rate: 130.79 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.2 0 2
Processing: 2 468 3396.0 4 50099
Waiting: 2 468 3396.0 4 50099
Total: 2 468 3396.0 4 50100

Percentage of the requests served within a certain time (ms)
50% 4
66% 4
75% 5
80% 7
90% 68
95% 106
98% 6081
99% 16013
100% 50100 (longest request)


Так что вполне production ready решение.

Также еше фишка в том, что Апача выбрасывает 503 ошибку (это пример лога уже при проксировании nginx):
xx.xx.xx.xx - - [10/Nov/2010:06:47:34 +0300] "GET / HTTP/1.0" 503 323 "-" "ApacheBench/2.3"

Пруф из кода:
206 return HTTP_SERVICE_UNAVAILABLE;

В процессе работы в продакшене крайне рекомендую контролировать, на какие сайты реагирует модуль:
cat /var/log/apache2/error.log | grep 'Vhost Limit'

А вот так топ террористов устроить:
cat /var/log/apache2/error.log | grep 'Vhost Limit' | awk '{print $12}' | sort | uniq -c | sort -g

Результаты нагрузочного тестирования в продакшене

Модуль к использованию НЕ РЕКОМЕНДУЕТСЯ, так как при высокой частоте форков он не справляется и не выдерживает заданный лимит, в результате при выставленном лимите в 30 форков их плодится до сотни и более.
cat /var/log/apache2/error.log | grep deferred | awk '{print $18 " " $0}' | sed 's/(//' | sort -g | tail -n30
86 [Tue Nov 16 00:09:39 2010] [warn] Vhost Limit : Access to xxx.ru deferred, Max Clients 30 exceeded (86 currently)
87 [Sun Nov 14 18:23:44 2010] [warn] Vhost Limit : Access to xxx.ru deferred, Max Clients 30 exceeded (87 currently)
87 [Tue Nov 16 00:09:43 2010] [warn] Vhost Limit : Access to yyyyy.ru deferred, Max Clients 30 exceeded (87 currently)
88 [Sun Nov 14 18:23:44 2010] [warn] Vhost Limit : Access to xxx.ru deferred, Max Clients 30 exceeded (88 currently)
89 [Sun Nov 14 18:23:44 2010] [warn] Vhost Limit : Access to xxx.ru deferred, Max Clients 30 exceeded (89 currently)

И в итоге получаем почти зависшую машину со следующими показателями:
ps aux | grep apa| wc -l
859

cat hangup_lynx_16nov.log | grep xxx.ru | wc -l
106

1 комментарий :

  1. 1. нужен пакет apache2-threaded-dev
    apt-get install apache2-threaded-dev

    2. перед запуском compile.sh надо собрать библиотеки

    apxs2 -i -c -n mod_vhost_limit.so mod_vhost_limit.c

    3. в конфиг vhost_limit.conf нужно внести еще "ExtendedStatus On"

    ОтветитьУдалить