Документация по ОС FreeBSD Суббота, 27.04.2024, 19:32
Приветствую Вас Гость | RSS
Меню сайта

Категории каталога
Apache [58]
DNS [25]
FTP [27]
Mail [74]
Samba [24]
Squid [46]
SSH [23]
VPN [35]
РРР [20]
Net [173]

Главная » Статьи » Сеть » Apache

Веб сервер на много много коннектов и высокую нагрузку (nginx+php-fpm+mysql) [2008]
Предисловие.

Вот хочу поделится с коллегами своими наработками, думаю они многим пригодятся.

1. Начнем с подготовки фри к нашим изгалениям.

Сетапим на сервер фрю семерку архтиктуры amd64 (можно и i386 но там надо делать PAE ядро и расширять адресацию), обнавляем исходники
nice -20 csup /usr/src/csup

ee /usr/src/csup
*default host=cvsup6.ru.FreeBSD.org
*default base=/var/db
*default prefix=/usr
*default release=cvs tag=RELENG_7
*default delete use-rel-suffix
*default compress

src-all
ports-all tag=.
doc-all prefix=/usr/src tag=.

Правим конфиги
ee /etc/make.conf
CPUTYPE?=core2
NO_PROFILE=yes
NO_GAMES=yes
DOC_LANG=en_US.ISO8859-1 ru_RU.KOI8-R
WITHOUT_X11=YES
NO_X11=YES
WITH_IDEA=yes
MAKE_IDEA=yes
WITHOUT_GAMES=yes
WITHOUT_INET6=yes
WITHOUT_INET6_SUPPORT=yes
WITHOUT_PROFILE=yes
WITHOUT_IPV6=yes

PORTSDIR?= /usr/ports

DEFAULT_MYSQL_VER=51
.if ${.CURDIR} == ${PORTSDIR}/databases/mysql51-server
WITH_PROC_SCOPE_PTH=yes # треды
BUILD_OPTIMIZED=yes # флаги оптимизации компилятору
BUILD_STATIC=yes # дает небольшой прирост производительности 
 #и независимость от внешних библиотек
.endif
.if ${.CURDIR} == ${PORTSDIR}/databases/mysql51-client
WITH_PROC_SCOPE_PTH=yes
BUILD_OPTIMIZED=yes
BUILD_STATIC=yes
.endif

ee /etc/src.conf
WITHOUT_INET6=yes
WITHOUT_INET6_SUPPORT=yes
WITHOUT_PROFILE=yes

и пересобираем систему

cd /usr/src
nice -20 make -j6 buildworld

Пока собирается система можно занятся конфигом ядра в следующщей консоле (или другом ssh терминале).
cd /usr/src/sys/amd64/conf
cp GENERIC SERVER64
ee SERVER64

И правим ядро для наших целей, я например викидываю от туда дебаг, ipv6, и все не нужные мне драйвера
(nfs ntfs fat все рейды и сетевухи которых у меня нету fairwair usb wlan), и добавляю следующщее

options SC_HISTORY_SIZE=8192 # чтобы в консоли можно было 
 # далеко листать историю
options IPFIREWALL
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=4000
options IPFIREWALL_DEFAULT_TO_ACCEPT
options IPFIREWALL_FORWARD
options DUMMYNET
options ACCEPT_FILTER_DATA # фильтры для nginx
options ACCEPT_FILTER_HTTP # ...
options HZ=1000
options DEVICE_POLLING

После того как сборка мира в первой консоле успешно закончится, можно приступать к сборке и установке нового ядра
nice -20 make -j2 kernel KERNCONF=SERVER64 # с -j6 иногда не 
 # собирается почемуто...

Так как хороший одмин должен быть ленивым, я создаю в корне скриптик
ee /upgrade && chmod 755 /upgrade
#!/bin/sh
fsck -p
mount -u /
mount -a
cd /usr/src
adjkerntz -i 
mergemaster -p
make installworld &&\
make delete-old &&\
mergemaster -i

Цепляем ip-kvm, ну или топаем туда где стоит сервер (нужна консоль), и перезагружаем его в однопользовательский режим.
nextboot -o "-s" -k kernel && reboot

Загружается система, на приглашение к выбору шела нажимаем Enter и после того как появиться консоль вводим
/upgrade && exit

mergemaster поспрашивает вас о конфигах, make delete-old поспрашивает о удалении старых файлов, после того как все вопросы будут отвечены и система установленна шел закроется и продолжиться нормальная загрузка уже новой системы.
2. Устанавливаем софт

Собственно ставим сам nginx, на запросы отвечаем так:
cd /usr/ports/www/nginx/ ; nice -20 make install clean
[ ] DEBUG Enable nginx debugging
[ ] GOOGLE_PERFTOOLS Enable google perftools module
[X] HTTP_MODULE Enable HTTP module
[X] HTTP_ADDITION_MODULE Enable http_addition module
[X] HTTP_DAV_MODULE Enable http_webdav module
[X] HTTP_FLV_MODULE Enable http_flv module
[X] HTTP_PERL_MODULE Enable http_perl module
[X] HTTP_REALIP_MODULE Enable http_realip module
[X] HTTP_REWRITE_MODULE Enable http_rewrite module
[X] HTTP_SSL_MODULE Enable http_ssl module
[X] HTTP_STATUS_MODULE Enable http_stub_status module
[X] HTTP_SUB_MODULE Enable http_sub module
[ ] MAIL_MODULE Enable IMAP4/POP3/SMTP proxy module
[ ] MAIL_IMAP_MODULE Enable IMAP4 proxy module
[ ] MAIL_POP3_MODULE Enable POP3 proxy module
[ ] MAIL_SMTP_MODULE Enable SMTP proxy module
[ ] MAIL_SSL_MODULE Enable mail_ssl module
[X] WWW Enable html sample files

Дальше ставим мускул и пхп:
cd /usr/ports/databases/mysql51-server/ ; nice -20 make install clean &&\
cd /usr/ports/lang/php5/ ; nice -20 make install clean

[X] CLI Build CLI version
[X] CGI Build CGI version
[ ] APACHE Build Apache module
[ ] DEBUG Enable debug
[X] SUHOSIN Enable Suhosin protection system (not for jails)
[X] MULTIBYTE Enable zend multibyte support
[ ] IPV6 Enable ipv6 support
[X] MAILHEAD Enable mail header patch
[X] REDIRECT Enable force-cgi-redirect support (CGI only)
[X] DISCARD Enable discard-path support (CGI only)
[X] FASTCGI Enable fastcgi support (CGI only)
[X] PATHINFO Enable path-info-check support (CGI only)

Cтавим сопутствующщий софт:
cd /usr/ports/lang/php5-extensions/ ; nice -20 make install clean

Выбираем себе нужные модули для пыха.

И не забываем про ZendOptimizer (довольно часто попадаются зазенденные скрипты, поэтому всегда втыкаю его докучи, авось пригодится)
/usr/ports/devel/ZendOptimizer/ ; nice -20 make install clean

Ставим phpMyAdmin (вечное требованние программеров на пыхе, в консоли для них не кошерно...)
/usr/ports/databases/phpmyadmin/ ; nice -20 make install clean

Ставим wget из /usr/ports/ftp/wget  (это типа консольная качалка такая)
скачиваем порт php-fpm под фрю (я же говорил уже что хороший одмин он ленивый, и с патчами в исходниках ковырятся ему должно быть лень если все и так хорошо работает), распаковываем его в /usr/ports/lang/php5-fpm идем туда и сетапим его:
cd /usr/ports/ftp/wget ; nice -20 make install clean &&\
cd /usr/ports/lang &&\
wget http://php-fpm.anight.org/downloads/freebsd-port/php5-fpm-0.5.9.tar.gz &&\
tar xfz php5-fpm-0.5.9.tar.gz &&\
cd php5-fpm &&\
nice --20 make install clean

[X] CLI Build CLI version
[ ] DEBUG Enable debug
[X] SUHOSIN Enable Suhosin protection system (not for jails)
[X] MULTIBYTE Enable zend multibyte support
[ ] IPV6 Enable ipv6 support
[X] MAILHEAD Enable mail header patch
[X] PATHINFO Enable path-info-check support (CGI only)

Ну вот как бы и усе как бы для голого веб сервера все уже готово, переходим к настройке.
3. Конфигурируем

Мой конфиг nginx:
less /usr/local/etc/nginx/nginx.conf
worker_processes 100; # рекомендуют делать по количеству ядер
 # но время отклика реально уменьшяется если запутить побольше воркеров,
 # т.к. у меня памяти много сделал сразу 100
worker_priority -5; # приоретет воркеров, сделал повыше 
 # чтобы из за медленных скриптов и корявых мускульных 
 # запросов статика отдавалась без лагов
worker_rlimit_nofile 51200;

events {
 worker_connections 51200;
 use kqueue;
}

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

 log_format main '$remote_addr - $remote_user [$time_local] $request '
 '"$status" $body_bytes_sent "$http_referer" '
 '"$http_user_agent" "$http_x_forwarded_for"';

 server_names_hash_bucket_size 512;
 sendfile on;
 tcp_nopush on;
 keepalive_timeout 70 30;
 send_timeout 30s;
 reset_timedout_connection on;
 resolver 127.0.0.1;
 resolver_timeout 10s;

 open_file_cache max=100000 inactive=40s;
 open_file_cache_valid 60s;
 open_file_cache_min_uses 2;
 open_file_cache_errors on;

 server {
 listen 80;
 server_name www.ru;
 charset koi8-r;
 location / {
 root /usr/local/www/nginx;
 index index.html index.htm;
 }
 }

 server {
 listen 80 default accept_filter=httpready; # фильтр позволяет отфильтровывать 
 # все не хттп соеденения до их установки на уровне ядра 
 # (собираются все пакеты анализируется GET загаловок, 
 # если его нет соеденение отбрасывается, если есть то соедененине 
 # появляется в системе и нгинксе, оч полезно от примитивного доса).

 server_name www.mysite.ru mysite.ru

 charset windows-1251;

 access_log /home/igrosoft/access_log main;
 error_log /home/igrosoft/error_log error;

 location / {
 root /home/igrosoft;
 index index.html index.htm index.php;
 }

 location /mrtg/ { # это mrtg
 alias /usr/local/www/mrtg/;
 index index.html index.htm;
 auth_basic Admin;
 auth_basic_user_file /usr/local/www/mrtg/.htpasswd;
 }

 location /.,ak,234sfyf34.:,.s/ { # а это для phpmyadmin
 alias /usr/local/www/phpMyAdmin/;
 index index.html index.htm index.php;
 auth_basic Admin;
 auth_basic_user_file /usr/local/www/phpMyAdmin/.htpasswd;
 }

 location ~* \.php$ { # передаем обработку пхп скриптов на php-fpm
 fastcgi_pass unix:/tmp/php-fpm.sock;
 fastcgi_index index.php;
 fastcgi_param SCRIPT_FILENAME /home/igrosoft$fastcgi_script_name;
 include fastcgi_params;
 }

 location ~ /\.ht { # закрываем доступ к файлам .htpasswd
 deny all;
 }

 error_page 500 502 503 504 /50x.html;
 location = /50x.html {
 root /usr/local/www/nginx-dist;
 }

 location /nginx_status { # с этой странички мы будем брать статистику по нгинксу для мртг
 stub_status on;
 access_log off;
 allow 127.0.0.1;
 deny all;
 }




 # HTTPS
 server {
 listen 443;
 server_name localhost;

 ssl on; # задаем настройки для ssl 
 ssl_certificate cert.pem;
 ssl_certificate_key cert.key;
 ssl_session_timeout 5m;
 ssl_protocols SSLv2 SSLv3 TLSv1;
 ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
 ssl_prefer_server_ciphers on;

 server_name www.myserver.ru myserver.ru

 # а дальше все тоже самое описание location'ов
 # аналогичное тому что было указанно выше 

 }
}

Теперь поправим конфиг у fpm'a
ee /usr/local/etc/php-fpm.conf
я там изменил только следующщие строчки:
 <!-- меняем сокет, вместо tcp'шного делаем локальный чтобы лишний раз стек не напрягать -->
<value name="listen_address">/tmp/php-fpm.sock</value>

 <!-- устанавливаем количество процессов php-cgi отнестить к этому нужно внимательно т.к. -->
 <!-- именно столько максимум php скриптов сможет выполняться одновременно-->
<value name="max_children">120</value>

 <!-- Очень полезная для оптимизации скриптов и мускульных запросов фича -->
 <!-- записывает в лог все данные о скрипте который выполняется дольше указанного времени -->
<value name="request_slowlog_timeout">5s</value>
<value name="slowlog">/var/log/php-slow.log</value>

 <!-- сколько запросов выполнит один cgi процесс прежде чем его перезапустят -->
<value name="max_requests">1500</value>

Пхп каждый конфигурит себе сам, но на основе длительного ковыряния с кучей серверов у меня получилось оптимальным вот это:
ee /usr/local/etc/php.ini
[PHP]
engine = On
zend.ze1_compatibility_mode = Off
short_open_tag = On
asp_tags = Off
precision = 14
y2k_compliance = On
output_buffering = 4096
zlib.output_compression = Off
implicit_flush = Off
unserialize_callback_func=
serialize_precision = 100
allow_call_time_pass_reference = Off
safe_mode = Off
safe_mode_gid = Off
safe_mode_include_dir =
safe_mode_exec_dir =
safe_mode_allowed_env_vars = PHP_
safe_mode_protected_env_vars = LD_LIBRARY_PATH
disable_functions =
disable_classes =
expose_php = On
max_execution_time = 30
max_input_time = 60
memory_limit = 128M
error_reporting = E_ALL & ~E_NOTICE
display_errors = Off
display_startup_errors = Off
log_errors = On
log_errors_max_len = 10240
ignore_repeated_errors = On
ignore_repeated_source = On
report_memleaks = On
track_errors = On
variables_order = "EGPCS"
register_globals = On
register_long_arrays = Off
register_argc_argv = Off
auto_globals_jit = On
post_max_size = 32M
magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off
auto_prepend_file =
auto_append_file =
default_mimetype = "text/html"
doc_root =
user_dir =
enable_dl = On
file_uploads = On
upload_max_filesize = 800M
allow_url_fopen = On
allow_url_include = Off
default_socket_timeout = 60

[Syslog]
define_syslog_variables = Off

[mail function]
SMTP = localhost
smtp_port = 25

[SQL]
sql.safe_mode = Off

[ODBC]
odbc.allow_persistent = On
odbc.check_persistent = On
odbc.max_persistent = -1
odbc.max_links = -1
odbc.defaultlrl = 4096
odbc.defaultbinmode = 1

[MySQL]
mysql.allow_persistent = On
mysql.max_persistent = -1
mysql.max_links = -1
mysql.default_port =
mysql.default_socket =
mysql.default_host =
mysql.default_user =
mysql.default_password =
mysql.connect_timeout = 60
mysql.trace_mode = Off

[MySQLi]
mysqli.max_links = -1
mysqli.default_port = 3306
mysqli.default_socket =
mysqli.default_host =
mysqli.default_user =
mysqli.default_pw =
mysqli.reconnect = Off

[mSQL]
msql.allow_persistent = On
msql.max_persistent = -1
msql.max_links = -1

[PostgresSQL]
pgsql.allow_persistent = On
pgsql.auto_reset_persistent = Off
pgsql.max_persistent = -1
pgsql.max_links = -1
pgsql.ignore_notice = 0
pgsql.log_notice = 0

[Sybase]
sybase.allow_persistent = On
sybase.max_persistent = -1
sybase.max_links = -1
sybase.min_error_severity = 10
sybase.min_message_severity = 10
sybase.compatability_mode = Off

[Sybase-CT]
sybct.allow_persistent = On
sybct.max_persistent = -1
sybct.max_links = -1
sybct.min_server_severity = 10
sybct.min_client_severity = 10

[bcmath]
bcmath.scale = 0

[Informix]
ifx.default_host =
ifx.default_user =
ifx.default_password =
ifx.allow_persistent = On
ifx.max_persistent = -1
ifx.max_links = -1
ifx.textasvarchar = 0
ifx.byteasvarchar = 0
ifx.charasvarchar = 0
ifx.blobinfile = 0
ifx.nullformat = 0

[Session]
session.save_handler = files
session.use_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 256000
session.bug_compat_42 = 0
session.bug_compat_warn = 1
session.referer_check =
session.entropy_length = 0
session.entropy_file =
session.cache_limiter = nocache
session.cache_expire = 18000
session.use_trans_sid = 0
session.hash_function = 0
session.hash_bits_per_character = 5
url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry"

[Tidy]
tidy.clean_output = Off

[soap]
soap.wsdl_cache_enabled=1
soap.wsdl_cache_dir="/tmp"
soap.wsdl_cache_ttl=86400

[Zend]
zend_optimizer.optimization_level=2 ; потому что на архетитуре amd64 
 ; при дефолтном значении 15 кладет пых в корку
zend_extension_manager.optimizer="/usr/local/lib/php/20060613/Optimizer"
zend_extension_manager.optimizer_ts="/usr/local/lib/php/20060613/Optimizer_TS"
zend_extension="/usr/local/lib/php/20060613/ZendExtensionManager.so"
zend_extension_ts="/usr/local/lib/php/20060613/ZendExtensionManager_TS.so"

Тепер переходим к тюнингу tcp стека:
ee /etc/sysctl.conf
net.inet.tcp.blackhole=2 # включаем черные дыры для tcp
net.inet.udp.blackhole=1 # и udp
kern.ipc.nmbclusters=65536 # увеличиваем лимиты
kern.ipc.somaxconn=32768 
kern.ipc.maxsockets=204800
kern.maxfiles=256000
kern.maxfilesperproc=230400
net.inet.ip.portrange.first=1024
net.inet.ip.portrange.last=65535
net.inet.ip.portrange.randomized=0
net.inet.tcp.maxtcptw=40960
net.inet.tcp.msl=40000 # самый на мой взгляд важный параметр, субьективно:
 # при уменьшении уменьшается количество вейтов, сервер лудьше держит нагрузку
 # при увеличении реже рветься связь на плохих каналах, нагрузка возрастает
net.inet.tcp.finwait2_timeout=40000
net.inet.tcp.syncookies=1
net.inet.tcp.sack.enable=1
net.inet.tcp.nolocaltimewait=1
net.inet.tcp.fast_finwait2_recycle=1
net.inet.icmp.drop_redirect=1
net.inet.icmp.log_redirect=1
net.inet.ip.redirect=0
kern.polling.enable=1
kern.polling.burst_max=1000
kern.polling.each_burst=50
net.inet.icmp.icmplim=5000

ee /boot/loader.conf
net.inet.tcp.syncache.hashsize=1024
net.inet.tcp.syncache.bucketlimit=100
net.inet.tcp.tcbhashsize=4096

По оптимизации стека и настройку sysctl можно почитать следующщее:
http://www.opennet.ru/base/net/tune_freebsd.txt.html
http://www.lissyara.su/?id=1147

По настроке nginx:
http://sysoev.ru/nginx/docs/
http://www.lexa.ru/nginx-ru/

Ну и напоследок гугл еще никто не отменял ;-)

Уф, великовата уже статейка получилась, пора бы и закруглятся, ждите продолжений.



Источник: http://www.lissyara.su/?id=1639
Категория: Apache | Добавил: oleg (20.11.2008) | Автор: nikll
Просмотров: 1620 | Рейтинг: 0.0/0 |
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа

Beastie

Друзья сайта

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
links

Copyright MyCorp © 2024