Чтож, будем переучивать. Начнем с малого.
Не использовать bind.
Bind - это DNS-сервер давно считающимся штатным DNS-сервером в любой *nix системе. Сервер сочетает в себе 2 компонента - авторитативный сервер и кеширующий резольвер + обладает весьма гибким конфигом. Однако вместе со всеми его достоинствами он также обладает кучей недостатков - использование одновременно резольвера и авторитативного сервера (компоненты, которые в bind и так весьма ресурсоемки) приводит к повышеному расходу ресурсов ( связка резольвера pdns-recursor и авторитативного сервера pdns обычно расходует в 3 раза меньше ресурсов нежели 1 bind). Так как на сабжевых серверах используется только авторитативная его часть, необходимость обработки рекурсивных запросов отсутствует, то целесообразно заменить его на что-либо полегче. MyDNS - сервер использующий бекэндом БД mysql, расходует весьма мало ресурсов, но к сожалению последний его релиз был выпущен в далеком 2006-м году. Есть его форк mydns-ng, но он ушел не намного дальше своего родителя - последний апдейт в svn - от 2010-го года. Такие серверы как PowerDNS и djbdns авторами панели очевидно не рассматриваются. Остается один вариант - NSD. На сегодняшний день среди авторитативных это один из быстрейших и легковесных серверов, использует файлы описаний зон в стиле BIND и может использовать файлы BIND без изменений, благодаря чему смена DNS-сервера проходит безболезнено.
Лезем в панель, следуем по пути Service Configuration » Nameserver Selection и выбираем NSD. Пара минут и -30 (в моем случае) метров из обьема используемой памяти - немного, но мне так спокойнее - нету named в top'е, а тестовая машинка с 2 тестовыми сайтами уж очень слабенькая.
Тюнинг MySQL
Понитие достаточно абстрактное, так как для каждой машины обычно приходится притягивать за уши баланс между ресурсоемкостью и быстродействием. Дефолтная сборка MySQL притаскиваемая панелью показала не самое лучшее быстродействие, поэтому я предпочел избавиться от нее в пользу чего поновее/побыстрее. Лезем в Server Configuration » Update Preferences и выставляем MySQL - never, дабы панель не пыталась управлять установкой/обновлением MySQL. Затем грохаем ее сборку и ставим что нам больше нравится. Я предпочитаю Percona-server или MariaDB, в зависимости от задач. Так как на тестовике все таблицы в InnoDB, то улучшеная поддержка MyISAM, а соответственно и MariaDB нам не нужна. Ставим Percona.
Код: Выделить всё
yum -y erase MySQL-*
rpm -Uhv http://www.percona.com/downloads/percona-release/percona-release-0.0-1.x86_64.rpm
yum -y install Percona-Server-shared-55 Percona-Server-devel-55 Percona-Server-client-55 Percona-Server-shared-compat Percona-Server-server-55
service mysql restart
Конфиг... Какая интересная штука... А что если вот тут... АААА!!! Ну ладно, шутки в сторону, советую перед правкой почитать этот сайт - много интересного. Не буду расписывать что да как, скажу только что для машинки с 1-ядерным процом и 512 мб оперативки оптимальнейшим образом показала себя данная конфигурация:
Учим корову летать.[client]
port = 3306
socket = /var/lib/mysql/mysql.sock
[mysqld]
port = 3306
socket = /var/lib/mysql/mysql.sock
log-error=/var/lib/mysql/error.log
datadir=/var/lib/mysql
skip-external-locking
skip-networking
symbolic-links=0
character-set-server=utf8
collation-server=utf8_general_ci
wait_timeout = 300
tmpdir=/tmp
query_cache_limit=2M
query_cache_size = 16M
query_cache_type=1
tmp_table_size=128M
max_heap_table_size=128M
table_cache = 512
thread_cache_size=128
thread_stack = 64K
long_query_time = 5
slow-query-log
slow-query-log-file = /var/lib/mysql/slow.log
myisam-recover=BACKUP
max_connections = 20
key_buffer_size = 16M
max_allowed_packet = 1M
table_open_cache = 512
sort_buffer_size = 512K
net_buffer_length = 8K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 8M
join_buffer_size = 4M
innodb_data_home_dir = /var/lib/mysql
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = /var/lib/mysql
innodb_buffer_pool_size = 16M
innodb_additional_mem_pool_size = 2M
innodb_log_file_size = 5M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50
innodb_file_per_table
[mysqld_safe]
log-error=/var/lib/mysql/error.log
nice = 0
[mysqldump]
quick
quote-names
max_allowed_packet = 16M
[mysql]
no-auto-rehash
safe-updates
[myisamchk]
key_buffer_size = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
В дефолтном виде конфиг apache генерируемый скриптами WHM работоспособен, но во-первых небезопасен, во-вторых не оптимален - при попытке выбрать с сайта страницу с 500 результатами на страницу сервер упал. Попробуем приблизить его к оптимальному варианту. Лезем в панель и выставляем следующие опции приближенные к тем что ниже:
Код: Выделить всё
Timeout 300 # у нас есть очень тяжелые запросы
TraceEnable Off # Это нам ни к чему
ServerSignature Off # Зачем светить интимными местами?
ServerTokens ProductOnly # См. выше
FileETag None # Эт тоже фтопку
StartServers 5 # Сколько процесс-потомков запускать при старте
<IfModule prefork.c>
MinSpareServers 5 # Минимальное количество ждущих процессов
MaxSpareServers 10 # Максимальное количество
</IfModule>
ServerLimit 35 # Максимальное количество порождаемых потомков
MaxClients 35 # Максимальное количество клиентов для которых заведется свой процесс
MaxRequestsPerChild 500 # Сколько запросов обработает потомок прежде чем убьется
KeepAlive On # Возможность подавать несколько запросов в 1 соединении
KeepAliveTimeout 5 # Слишком долго ждать запросов тоже не стоит...
MaxKeepAliveRequests 60 По дефолту апач работает в режиме модели мультипроцессинга prefork и имеет возможность подключения php как dso, cgi, fastcgi и suphp. Как разграничитель прав доступа он использует mod_suexec либо mod_ruid2 либо все тот же suphp. Пройдемся по каждому пункту:
- DSO - динамически подключаемая библиотека, она же пресловутый mod_php. По скорости уступает только fastcgi поднимаемому внешним приложением (php-fpm, spawn-fcgi, но их к сожалению панель использовать не умеет).
 - cgi - достаточно устаревшая технология, раз в 7 медленнее dso. Суть заключается в том, что апач сам поднимает процесс интерпретатора php и убивает его после обработки скрипта.
 - fastcgi - без внешнего спаунера - примерно то же что и cgi (скорость также примерно одинакова), однако расходует меньше оперативной памяти.
 - suphp - прослойка между веб-сервером и интерпретатором php. php запускается как отдельный процесс от имени указаного пользователя не обгоняет по скорости cgi, ибо сам по сути запускает обработку php как cgi, только от указаного ему пользователя.
 - mod_suexec, mod_ruid2 - модули обеспечивающие работу виртуалхоста от имени указаного пользователя. Имеют особенность оставлять огрехи в виде сгенерированных динамическим контентом файлов принадлежащих корневому пользователю apache и недоступных для модификации/удалению пользователем виртуалхоста.
 
К сожалению я не нашел в панели нативной поддержки apache как mpm-itk. Однако нашелся модуль "впиливающий" такую функциональность в EasyApache. Пляшем от радости, катаемся по полу, разгоняемся, качаем, ставим:
Код: Выделить всё
wget http://docs.cpanel.net/twiki/pub/EasyApache3/CustomMods/MPMitk.tar.gz
 tar -C /var/cpanel/easy/apache/custom_opt_mods -xzf MPMitk.tar.gzРвем волосы, крошим зубами столешницу... Изучаем механизмы EasyApache и находим интересный кусок кода в файле /var/cpanel/perl/easy/Cpanel/Easy/Utils/PHP.pm :
Код: Выделить всё
                        $self->run_system_cmd( [ '/usr/local/apache/bin/apxs', '-q', 'MPM_NAME' ], 0, 1 );
                        if ( $self->{'last_run_system_cmd'} !~ /^prefork$/m ) {
                            # Don't generate CGI/FCGI binary on first pass (unless PHP 5.4 or later)
                            $self->add_to_configure( { '--disable-cgi' => '' }, "Cpanel::Easy::PHP5" ) unless $v5_4_or_later;
                            # Don't generate mod_php; we don't support Zend Thread Safety (ZTS)
                            $self->delete_from_configure( { '--with-apxs' => undef, '--with-apxs2' => undef }, "Cpanel::Easy::PHP5" );
                        }Код: Выделить всё
if ($opt_q) {
    ##       
    ##  QUERY INFORMATION 
    ##                    
    my $result = get_vars(@args);                      
    print "$result\n";
}Код: Выделить всё
if ($opt_q) {
    ##       
    ##  QUERY INFORMATION 
    ##                    
    my $result = get_vars(@args);
    if ($result =~ "itk") { 
    print "prefork\n";           
    }                            
    else {                       
    print "$result\n";           
    }                            
}Чтобы не дергать файлик туда-сюда вручную воспользуемся поддержкой хуковых скриптов EasyApache.
Создадим 2 файла - /scripts/after_apache_make_install куда запишем:
Код: Выделить всё
#!/bin/bash
if [ -f /root/apxs ]; then
mv -f /usr/local/apache/bin/apxs /usr/local/apache/bin/apxs.orig
cp -f /root/apxs /usr/local/apache/bin/apxs
fiи
/scripts/posteasyapache
Код: Выделить всё
#!/bin/bash
if [ -f /usr/local/apache/bin/apxs.orig ]; then
rm -f /usr/local/apache/bin/apxs
mv /usr/local/apache/bin/apxs.orig /usr/local/apache/bin/apxs
fiТопаем в панель и собираем апач и php, включив при сборке MPMitk и отключив MPMprefork, suPHP, mod_ruid2 и кучу других ненжных модулей (вырубаем все, что не используется нами или панелью - лишний модуль - лишняя память). После сборки с учетом вышеизложеных кастомизаций у нас должно остаться 2 пункта в списке доступных типов подключения php - cgi и dso. Включаем пых как dso и перезапускаем апач. Проверяем права в папках пользователей, и приступим к написанию правильного конфига, через правку шаблона для cPanel, ибо панелька не признает никаких правок кроме как ею же созданых или дописаных в предзаготовленные ей внешние файлы и в случае обнаружения вмешательства чьих-либо шаловливых рук с радостью перезаливает все из шаблона.
Для этого скопируем файл /var/cpanel/templates/apache2/main.default в /var/cpanel/templates/apache2/main.local и открываем целевой файл для редактирования. Ищем в нем секцию:
Код: Выделить всё
# These can be set in WHM under 'Apache Global Configuration'
[% IF main.timeout.item.timeout.length %]Timeout [% main.timeout.item.timeout %][% END %]
[% IF main.traceenable.item.traceenable.length %]TraceEnable [% main.traceenable.item.traceenable %][% END %]
[% IF main.serversignature.item.serversignature.length %]ServerSignature [% main.serversignature.item.serversignature %][% END %]
[% IF main.servertokens.item.servertokens.length %]ServerTokens [% main.servertokens.item.servertokens %][% END %]
[% IF main.fileetag.item.fileetag.length %]FileETag [% main.fileetag.item.fileetag %][% END %]
[% IF main.startservers.item.startservers.length %]StartServers [% main.startservers.item.startservers %][% END %]
<IfModule prefork.c>
    [% IF main.minspareservers.item.minspareservers.length %]MinSpareServers [% main.minspareservers.item.minspareservers %][% END %]
    [% IF main.maxspareservers.item.maxspareservers.length %]MaxSpareServers [% main.maxspareservers.item.maxspareservers %][% END %]
</IfModule>
[% IF main.serverlimit.item.serverlimit.length %]ServerLimit [% main.serverlimit.item.serverlimit %][% END %]
[% IF main.maxclients.item.maxclients.length %]MaxClients [% main.maxclients.item.maxclients %][% END %]
[% IF main.maxrequestsperchild.item.maxrequestsperchild.length %]MaxRequestsPerChild [% main.maxrequestsperchild.item.maxrequestsperchild %][% END %]
[% IF main.keepalive.item.keepalive.length %]KeepAlive [% main.keepalive.item.keepalive %][% END %]
[% IF main.keepalivetimeout.item.keepalivetimeout.length %]KeepAliveTimeout [% main.keepalivetimeout.item.keepalivetimeout %][% END %]
[% IF main.maxkeepaliverequests.item.exists('maxkeepaliverequests') %]MaxKeepAliveRequests [% main.maxkeepaliverequests.item.maxkeepaliverequests || 0 %][% END %]Код: Выделить всё
<IfModule mpm_itk_module>
    [% IF main.minspareservers.item.minspareservers.length %]MinSpareServers [% main.minspareservers.item.minspareservers %][% END %]
    [% IF main.maxspareservers.item.maxspareservers.length %]MaxSpareServers [% main.maxspareservers.item.maxspareservers %][% END %]
    NiceValue -2  # приоритет процесса. Зададим ему -2 (чуть выше дефолтного). Как возможно вы заметили выше, mysql у нас запускается с нулевым приоритетом (nice = 0 ), чуть более высший приоритет будет иметь веб-сервер, дабы строилась логическая цепочка - фронтэнд-бекэнд, посредством которой процессы фронтэнда не вытеснялись процессами бекэнда. 
    AssignUserID [% main.user.item.user %] [% main.group.item.group %] # запускаем дочерние процессы, обслуживающие корневые вирты и/или вирты без явно назначеного владельца от имени пользователя и группы апача, в случае с cPanel это nobody.
</IfModule>
# привнесем в скудный конфиг немного секурности и быстродействия:
ContentDigest Off 
AddDefaultCharset Off
BufferedLogs Off
LimitInternalRecursion 5
LimitRequestBody 0
ListenBacklog 1024
<IfModule mod_headers.c>
        RequestHeader unset Range
        RequestHeader unset Request-Range
</IfModule>
<IfModule reqtimeout_module>
        RequestReadTimeout header=20-40,minrate=500
        RequestReadTimeout body=10,minrate=500
</IfModule>
 
<IfModule mod_deflate.c>
        AddOutputFilterByType DEFLATE text/html text/plain text/xml
        AddOutputFilterByType DEFLATE text/css
        AddOutputFilterByType DEFLATE application/x-javascript application/javascript application/ecmascript
        AddOutputFilterByType DEFLATE application/rss+xml
        DeflateCompressionLevel 1
</IfModule>Код: Выделить всё
    [%- IF supported.mod_suphp %]
    <IfModule mod_suphp.c>
        suPHP_UserGroup nobody nobody
    </IfModule>
    [%- END %]Код: Выделить всё
    <IfModule itk.c>
        AssignUserID [% main.user.item.user %] [% main.group.item.group %]
        NiceValue -2
        MaxClientsVHost 10 # Ограничиваем количество запускаемых процессов на вирт.
    </IfModule>Код: Выделить всё
[% IF vhost.user != 'nobody' -%]
    <IfModule !mod_disable_suexec.c>
        <IfModule !mod_ruid2.c>
            SuexecUserGroup [% vhost.user %] [% vhost.group %]
        </IfModule>
    </IfModule>
    <IfModule mod_ruid2.c>
        RUidGid [% vhost.user %] [% vhost.group %]
    </IfModule>
[% END -%]Код: Выделить всё
[% IF vhost.user != 'nobody' -%]
    <IfModule !mod_disable_suexec.c>
        <IfModule !mod_ruid2.c>
            SuexecUserGroup [% vhost.user %] [% vhost.group %]
        </IfModule>
    </IfModule>
    <IfModule mod_ruid2.c>
        RUidGid [% vhost.user %] [% vhost.group %]
    </IfModule>
    <IfModule itk.c>
        AssignUserID [% vhost.user %] [% vhost.group %]
        NiceValue -2
        MaxClientsVHost 10
    </IfModule>
[% END -%]Код: Выделить всё
[% IF supported.mod_suphp -%]
    <IfModule mod_suphp.c>
        suPHP_UserGroup [% vhost.user %] [% vhost.group %]
    </IfModule>
[% END -%]Код: Выделить всё
[% IF supported.mod_suphp -%]
    <IfModule !itk.c>
    <IfModule mod_suphp.c>
        suPHP_UserGroup [% vhost.user %] [% vhost.group %]
    </IfModule>
    </IfModule>
[% END -%]блок
Код: Выделить всё
[% IF !vhost.hascgi -%]
	Options -ExecCGI -Includes
	RemoveHandler cgi-script .cgi .pl .plx .ppl .perl
[% END -%]Код: Выделить всё
[% IF supported.mod_alias -%]Код: Выделить всё
<Directory "[% vhost.documentroot %]">
    Options ExecCGI IncludesNOEXEC Indexes SymLinksIfOwnerMatch -FollowSymLinks
    AllowOverride All
</Directory>Сохраняем, пробуем пересобрать конфигу:
Код: Выделить всё
/usr/local/cpanel/bin/build_apache_confПусть лошадь думает, у нее голова большая...
Если все предыдущие шаги выполнены, у вас ничего не сломалось, а наоборот - работает и даже немного лучше чем раньше - самое время отбросить шлак от апача. Для этого к панели уже целый модуль написали - будем ставить nginx. Следуя инструкции на сайте скачиваем модуль, распаковываем и... Ээ, нет! Я привык сначала смотреть с чем сталкиваюсь! Рассмотрим его конфиги и все что нам предлагается. Порывшись в папке /usr/src/publicnginx я все-таки обнаружил что конкретно меня не устраивало.
1. Конфиг nginx. Это конечно дело вкуса, но мой конфиг мне больше нравится нежели тот, что идет в поставке модуля. Я заменил содержимое файла nginx.conf на свой шаблончик:
Код: Выделить всё
user nobody nobody;
worker_processes 4;
worker_rlimit_nofile 20480;
worker_priority -5;
timer_resolution 100ms;
error_log  /var/log/nginx/error.log info;
events {
 worker_connections 2048;
 use epoll;
}
http {
 access_log off;
 server_name_in_redirect off;
 server_names_hash_max_size 10240;
 server_names_hash_bucket_size 1024;
 include    mime.types;
 default_type  application/octet-stream;
 server_tokens off;
 sendfile on;
 sendfile_max_chunk  128k;
 tcp_nopush on;
 tcp_nodelay on;
 keepalive_requests 100;
 keepalive_timeout 50s 35;
 keepalive_disable msie6;
 ignore_invalid_headers on;
 client_header_timeout  3m;
 client_body_timeout 3m;
 send_timeout 3m;
 reset_timedout_connection on;
 connection_pool_size  256;
 client_header_buffer_size 256k;
 large_client_header_buffers 4 256k;
 client_max_body_size 200M; 
 client_body_buffer_size 128k;
 request_pool_size 32k;
 output_buffers 4 32k;
 postpone_output 1460;
 client_body_in_file_only on;
 log_format bytes_log "$msec $bytes_sent .";
 underscores_in_headers on;
 lingering_time 30;
 lingering_timeout 10;
 
 proxy_temp_path  /tmp/nginx/nginx_proxy/;
 proxy_cache_path /tmp/nginx/proxy_temp levels=2 keys_zone=pagecache:5m inactive=10m max_size=50m;
 
 proxy_cache pagecache;
 proxy_headers_hash_bucket_size 6400;
 proxy_headers_hash_max_size 51200;
 proxy_connect_timeout 90;
 proxy_send_timeout 90;
 proxy_read_timeout 320;
 proxy_buffer_size 64k;
 proxy_buffers 16 32k;
 proxy_busy_buffers_size 64k;
 proxy_temp_file_write_size 64k;
 proxy_redirect off;
 proxy_hide_header Vary;
 proxy_set_header Accept-Encoding '';
 proxy_ignore_headers Cache-Control Expires;
 proxy_ignore_client_abort off;
 proxy_intercept_errors off;
 proxy_set_header Referer $http_referer;
 proxy_set_header Host   $host;
 proxy_set_header Range "";
 proxy_set_header Request-Range "";
 proxy_set_header Cookie $http_cookie;
 
 gzip off;
 gzip_vary on;
 gzip_disable "MSIE [1-6]\.";
 gzip_proxied any;
 gzip_http_version 1.1;
 gzip_min_length  1000;
 gzip_comp_level  6;
 gzip_buffers  16 8k;
 gzip_types    text/plain text/xml text/css application/x-javascript application/xml application/xml+rss text/javascript application/atom+xml;
 include "/etc/nginx/vhosts/*";
}Код: Выделить всё
def writeconfded(user, domain, docroot, passedip, alias):
        user = user
        domain = domain
        passedip = passedip
        dedipvhost = """server {
          error_log /var/log/nginx/vhost-error_log warn;
          listen %s:80;
          server_name %s %s %s;
          access_log /usr/local/apache/domlogs/%s bytes_log;
          access_log /usr/local/apache/domlogs/%s combined;
          root %s;
          location / {
          location ~.*\.(3gp|gif|jpg|jpeg|png|ico|wmv|avi|asf|asx|mpg|mpeg|mp4|pls|mp3|mid|wav|swf|flv|html|htm|txt|js|css|exe|zip|tar|rar|gz|tgz|bz2|uha|7z|doc|docx|xls|xlsx|pdf|iso)$ {
          expires 1d;
          try_files $uri @backend;
          }
          error_page 405 = @backend;
          add_header X-Cache "HIT from Backend";
          proxy_pass http://%s:8081;
          include proxy.inc;
          }
          location @backend {
          internal;
          proxy_pass http://%s:8081;
          include proxy.inc;
          }
          location ~ .*\.(php|jsp|cgi|pl|py)?$ {
          proxy_pass http://%s:8081;
          include proxy.inc;
          }
          location ~ /\.ht {
          deny all;
          }
        }""" % (passedip, domain, alias, passedip, domain + "-bytes_log", domain, docroot, passedip, passedip, passedip)
        if not os.path.exists( '/etc/nginx/vhosts'):
                os.makedirs('/etc/nginx/vhosts')
        if os.path.exists( '/etc/nginx/staticvhosts/' + domain):
                pass
        else:
                domainvhost = open ('/etc/nginx/vhosts/' + domain, 'w')
                domainvhost.writelines( dedipvhost )
                domainvhost.close()
def writeconfshared(user,domain,docroot,passedip, alias):
        sharedipvhost = """server {
          error_log /var/log/nginx/vhost-error_log warn;
          listen %s:80;
          server_name %s %s;
          access_log /usr/local/apache/domlogs/%s bytes_log;
          access_log /usr/local/apache/domlogs/%s combined;
          root %s;
          location / {
          location ~.*\.(3gp|gif|jpg|jpeg|png|ico|wmv|avi|asf|asx|mpg|mpeg|mp4|pls|mp3|mid|wav|swf|flv|html|htm|txt|js|css|exe|zip|tar|rar|gz|tgz|bz2|uha|7z|doc|docx|xls|xlsx|pdf|iso)$ {
          expires 1d;
          try_files $uri @backend;
          }
          error_page 405 = @backend;
          add_header X-Cache "HIT from Backend";
          proxy_pass http://%s:8081;
          include proxy.inc;
          }
          location @backend {
          internal;
          proxy_pass http://%s:8081;
          include proxy.inc;
          }
          location ~ .*\.(php|jsp|cgi|pl|py)?$ {
          proxy_pass http://%s:8081;
          include proxy.inc;
          }
          location ~ /\.ht {
          deny all;
          }
        }""" % (passedip, domain, alias, domain + "-bytes_log", domain, docroot, passedip, passedip, passedip)
        if not os.path.exists( '/etc/nginx/vhosts'):
                os.makedirs('/etc/nginx/vhosts')
        if os.path.exists( '/etc/nginx/staticvhosts/' + domain):
                pass
        else:
                domainvhost = open ('/etc/nginx/vhosts/' + domain, 'w')
                domainvhost.writelines( sharedipvhost )
                domainvhost.close()Код: Выделить всё
def writeconfded(user, domain, docroot, passedip, alias):
        user = user
        domain = domain
        passedip = passedip
        dedipvhost = """server {
          listen %s:80;
          server_name %s %s %s rcvbuf=8192 sndbuf=16384 backlog=32000;
          access_log /usr/local/apache/domlogs/%s bytes_log;
          access_log /usr/local/apache/domlogs/%s combined;
          location ~* ^.+\.(3gp|gif|jpg|jpeg|png|ico|wmv|avi|asf|asx|mpg|mpeg|mp4|pls|mp3|mid|wav|swf|flv|html|htm|txt|js|css|exe|zip|tar|rar|gz|tgz|bz2|uha|7z|doc|docx|xls|xlsx|pdf|iso)$ {
                    root %s;
                    expires 1d;
                    error_log /var/log/nginx/vhost-error_log warn;
                    error_page 403 = @fallback;
                    error_page 404 = @fallback;
                    error_page 405 = @fallback;
                    try_files $uri $uri/ @fallback;
          }
          location / {
                    proxy_pass http://%s:8081;
                    proxy_redirect http://%s:8081/ /;
                    proxy_set_header Host $host;
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header X-Forwarded-Proto $scheme;
                    proxy_set_header X-Real-IP $remote_addr;
          }
 
          location @fallback {
                    proxy_pass http://%s:8081;
                    add_header X-Cache "Jump to backend";
                    proxy_set_header Host $host;
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header X-Forwarded-Proto $scheme;
                    proxy_set_header X-Real-IP $remote_addr;
          }
 
          location ~ /\.ht {
                    deny all;
          }
        }""" % (passedip, domain, alias, passedip, domain + "-bytes_log", domain, docroot, passedip, passedip, passedip)
        if not os.path.exists( '/etc/nginx/vhosts'):
                os.makedirs('/etc/nginx/vhosts')
        if os.path.exists( '/etc/nginx/staticvhosts/' + domain):
                pass
        else:
                domainvhost = open ('/etc/nginx/vhosts/' + domain, 'w')
                domainvhost.writelines( dedipvhost )
                domainvhost.close()
def writeconfshared(user,domain,docroot,passedip, alias):
        sharedipvhost = """server {
          listen %s:80;
          server_name %s %s;
          access_log /usr/local/apache/domlogs/%s bytes_log;
          access_log /usr/local/apache/domlogs/%s combined;
          location ~* ^.+\.(3gp|gif|jpg|jpeg|png|ico|wmv|avi|asf|asx|mpg|mpeg|mp4|pls|mp3|mid|wav|swf|flv|html|htm|txt|js|css|exe|zip|tar|rar|gz|tgz|bz2|uha|7z|doc|docx|xls|xlsx|pdf|iso)$ {
                    root %s;
                    expires 1d;
                    error_log /var/log/nginx/vhost-error_log warn;
                    error_page 403 = @fallback;
                    error_page 404 = @fallback;
                    error_page 405 = @fallback;
                    try_files $uri $uri/ @fallback;
          }
          location / {
                    proxy_pass http://%s:8081;
                    proxy_redirect http://%s:8081/ /;
                    proxy_set_header Host $host;
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header X-Forwarded-Proto $scheme;
                    proxy_set_header X-Real-IP $remote_addr;
          }
 
          location @fallback {
                    proxy_pass http://%s:8081;
                    add_header X-Cache "Jump to backend";
                    proxy_set_header Host $host;
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header X-Forwarded-Proto $scheme;
                    proxy_set_header X-Real-IP $remote_addr;
          }
 
          location ~ /\.ht {
                    deny all;
          }
        }""" % (passedip, domain, alias, domain + "-bytes_log", domain, docroot, passedip, passedip, passedip)
        if not os.path.exists( '/etc/nginx/vhosts'):
                os.makedirs('/etc/nginx/vhosts')
        if os.path.exists( '/etc/nginx/staticvhosts/' + domain):
                pass
        else:
                domainvhost = open ('/etc/nginx/vhosts/' + domain, 'w')
                domainvhost.writelines( sharedipvhost )
                domainvhost.close()Код: Выделить всё
Код: Выделить всё
--http-client-body-temp-path=/tmp/nginx_client  --http-proxy-temp-path=/tmp/nginx_proxy  --http-fastcgi-temp-path=/tmp/nginx_fastcgiКод: Выделить всё
--http-client-body-temp-path=/tmp/nginx/nginx_client  --http-proxy-temp-path=/tmp/nginx/nginx_proxy  --http-fastcgi-temp-path=/tmp/nginx/nginx_fastcgiищем:
Код: Выделить всё
proc = subprocess.Popen("rm -f /etc/nginx/proxy.inc > /dev/null 2>&1", shell=True)
output = proc.communicate()
proc = subprocess.Popen("cp /" + currentdir + "/proxy.inc /etc/nginx/proxy.inc", shell=True)
output = proc.communicate()Код: Выделить всё
proc = subprocess.Popen("mkdir -p /tmp/nginx/nginx_proxy", shell=True)
output = proc.communicate()
proc = subprocess.Popen("mkdir -p /tmp/nginx/nginx_fastcgi", shell=True)
output = proc.communicate()
proc = subprocess.Popen("mkdir -p /tmp/nginx/nginx_client", shell=True)
output = proc.communicate()
proc = subprocess.Popen("chown -R nobody:nobody /tmp/nginx", shell=True)
output = proc.communicate()Код: Выделить всё
find /home -type f -exec chmod 0755 {} \;Код: Выделить всё
Timeout 300
TraceEnable Off
ServerSignature Off
ServerTokens ProductOnly
FileETag None
StartServers 5
MinSpareServers 5
MaxSpareServers 10
ServerLimit 35
MaxClients 25
MaxRequestsPerChild 100
KeepAl% END %ive Off
KeepAliveTimeout 5
MaxKeepAliveRequests 60Результаты нагрузочного теста via siege:
Код: Выделить всё
Transactions: 487 hits
Availability: 97.40 %
Elapsed time: 839.42 secs
Data transferred: 3.63 MB
Response time: 7.61 secs
Transaction rate: 0.58 trans/sec
Throughput: 0.00 MB/sec
Concurrency: 4.42
Successful transactions: 487
Failed transactions: 13
Longest transaction: 29.60
Shortest transaction: 1.31Теперь можно с гордостью собирать eAccelerator или Xcache - с нашим апачем они будут работать (с suphp они не дружат). Кстати я предпочитаю использовать phpexpress

