Если у вас есть сайт php+mysql и VPS OpenVZ с небольшим количеством оперативки (192), и хочется выжать перфоманс (для CentOS, минимальная инсталляция, если есть апач — выключить):
# /sbin/chkconfig nginx on
# /sbin/chkconfig mysqld on
# /sbin/chkconfig php-fpm on
Конфигурируем nginx (файл /etc/nginx.conf), привожу свой, взял на скорую с тестового сервера с малым количеством ресурсов (поэтому worker_processes 1 и т.д.), для одиночного wordpress, работает rewrite (конфиг для старого nginx из epel!!!, в > 0.7.x немного другой синтаксис), что-то лишнее вырезанно, не настроены кеши и т.д. (всё равно быстро), если что sysoev.ru/nginx/:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
use epoll; # конфиг для linux CentOS
}
http {
include /etc/nginx/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"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
###
server_tokens off;
### fastcgi nodes
# у меня работает и через tcp, и unix сокет, через tcp незначительно быстрее (TIME_WAIT?)
#
upstream backend {
# server unix:/tmp/fcgi.sock;
server 127.0.0.1:9000;
}
#
# yourdomain.com server
#
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
autoindex off;
###
gzip on; # use gzip compression
gzip_proxied any; # enable proxy for the fcgi requests
gzip_types text/plain text/html text/css text/javascript;
index index.php;
location / {
log_not_found off;
error_page 404 = @wordpress;
}
location @wordpress {
fastcgi_pass backend;
fastcgi_param SCRIPT_FILENAME /var/www/html/yourdomain.com/index.php;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_NAME /index.php;
}
location ~ \.php$ {
if (!-e $request_filename) {
rewrite ^(.+)$ /index.php break;
break;
}
fastcgi_index index.php;
fastcgi_pass backend;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
#charset koi8-r;
access_log /var/log/nginx/yourdomain.com.access.log main;
error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
# Load config files from the /etc/nginx/conf.d directory
include /etc/nginx/conf.d/*.conf;
}
Конфигурируем PHP-FPM (файл /etc/php-fpm.conf). Используется локальный socket. Наиболее важный параметр тут – max_children, его значение должно быть подобрано с учетом конфигурации (память, CPU) в процессе тестов нагрузки. Обязательны синтетические тесты, у меня max_children = 5 был медленней max_children = 1, max_children = 2.
<?xml version="1.0" ?>
<configuration>
All relative paths in this config are relative to php's install prefix
<section name="global_options">
Pid file
<value name="pid_file">/var/run/php-fpm.pid</value>
Error log file
<value name="error_log">/var/log/php-fpm.log</value>
Log level
<value name="log_level">notice</value>
When this amount of php processes exited with SIGSEGV or SIGBUS ...
<value name="emergency_restart_threshold">10</value>
... in a less than this interval of time, a graceful restart will be initiated.
Useful to work around accidental curruptions in accelerator's shared memory.
<value name="emergency_restart_interval">1m</value>
Time limit on waiting child's reaction on signals from master
<value name="process_control_timeout">5s</value>
Set to 'no' to debug fpm
<value name="daemonize">yes</value>
</section>
<workers>
<section name="pool">
Name of pool. Used in logs and stats.
<value name="name">default</value>
Address to accept fastcgi requests on.
Valid syntax is 'ip.ad.re.ss:port' or just 'port' or '/path/to/unix/socket'
<!-- <value name="listen_address">/tmp/fcgi.sock</value> -->
<value name="listen_address">127.0.0.1:9000</value>
<value name="listen_options">
Set listen(2) backlog
<value name="backlog">-1</value>
Set permissions for unix socket, if one used.
In Linux read/write permissions must be set in order to allow connections from web server.
Many BSD-derrived systems allow connections regardless of permissions.
<value name="owner"></value>
<value name="group"></value>
<value name="mode">0666</value>
</value>
Additional php.ini defines, specific to this pool of workers.
<value name="php_defines">
<!-- <value name="sendmail_path">/usr/sbin/sendmail -t -i</value> -->
<!-- <value name="display_errors">0</value> -->
</value>
Unix user of processes
<value name="user">nginx</value>
Unix group of processes
<value name="group">nginx</value>
Process manager settings
<value name="pm">
Sets style of controling worker process count.
Valid values are 'static' and 'apache-like'
<value name="style">static</value>
Sets the limit on the number of simultaneous requests that will be served.
Equivalent to Apache MaxClients directive.
Equivalent to PHP_FCGI_CHILDREN environment in original php.fcgi
Used with any pm_style.
<value name="max_children">1</value>
Settings group for 'apache-like' pm style
<value name="apache_like">
Sets the number of server processes created on startup.
Used only when 'apache-like' pm_style is selected
<value name="StartServers">20</value>
Sets the desired minimum number of idle server processes.
Used only when 'apache-like' pm_style is selected
<value name="MinSpareServers">5</value>
Sets the desired maximum number of idle server processes.
Used only when 'apache-like' pm_style is selected
<value name="MaxSpareServers">35</value>
</value>
</value>
The timeout (in seconds) for serving a single request after which the worker process will be terminated
Should be used when 'max_execution_time' ini option does not stop script execution for some reason
'0s' means 'off'
<value name="request_terminate_timeout">0s</value>
The timeout (in seconds) for serving of single request after which a php backtrace will be dumped to slow.log file
'0s' means 'off'
<value name="request_slowlog_timeout">0s</value>
The log file for slow requests
<value name="slowlog">logs/slow.log</value>
Set open file desc rlimit
<value name="rlimit_files">1024</value>
Set max core size rlimit
<value name="rlimit_core">0</value>
Chroot to this directory at the start, absolute path
<value name="chroot"></value>
Chdir to this directory at the start, absolute path
<value name="chdir"></value>
Redirect workers' stdout and stderr into main error log.
If not set, they will be redirected to /dev/null, according to FastCGI specs
<value name="catch_workers_output">yes</value>
How much requests each process should execute before respawn.
Useful to work around memory leaks in 3rd party libraries.
For endless request processing please specify 0
Equivalent to PHP_FCGI_MAX_REQUESTS
<value name="max_requests">500</value>
Comma separated list of ipv4 addresses of FastCGI clients that allowed to connect.
Equivalent to FCGI_WEB_SERVER_ADDRS environment in original php.fcgi (5.2.2+)
Makes sense only with AF_INET listening socket.
<value name="allowed_clients">127.0.0.1</value>
Pass environment variables like LD_LIBRARY_PATH
All $VARIABLEs are taken from current environment
<value name="environment">
<value name="HOSTNAME">$HOSTNAME</value>
<value name="PATH">/usr/local/bin:/usr/bin:/bin</value>
<value name="TMP">/tmp</value>
<value name="TMPDIR">/tmp</value>
<value name="TEMP">/tmp</value>
<value name="OSTYPE">$OSTYPE</value>
<value name="MACHTYPE">$MACHTYPE</value>
<value name="MALLOC_CHECK_">2</value>
</value>
</section>
</workers>
</configuration>
Теперь добавляем пользователя и нужную базу данных, если надо (можно конечно поставить phpmyadmin, я не ставил, был не нужен и не секьюрно):
# mysql --user=root -p
mysql> CREATE USER 'wordpressuser'@'localhost' IDENTIFIED BY 'my_password';
mysql> CREATE DATABASE mywordpress;
mysql> GRANT ALL PRIVILEGES ON `mywordpress`.* TO 'wordpressuser'@'%' WITH GRANT OPTION;
И дальше ставим движок php.
Тестировал apache benchmark'ом (с сервером ping 50-100mc, мой канал 1Мбит) ab -n 100 -c 5, wordpress 3.0 с одним средним постом, какой-то темой и seo плагином.
Document Length: 9774 bytes
Concurrency Level: 5
Time taken for tests: 49.761 seconds
Complete requests: 100
Failed requests: 0
Write errors: 0
Total transferred: 997800 bytes
HTML transferred: 977400 bytes
Requests per second: 2.01 [#/sec] (mean)
Time per request: 2488.066 [ms] (mean)
При выключенном apc — в 2,5 раза всё медленней. Интересно, что при подключенном ZendOptimizer (с apc не работает) — медленней в 2,2-2,3 раза. optimization_level почти не влияет на результат (104 против 111 секунд на время теста). Так что не знаю откуда zend берёт 40% ускорения в своей рекламе. С eaccelerator к сожалению не сравнивал (ходит инфа, что быстрее apc, но пока сам не увидишь..), может быть руки дойдут.
PS Нюансы — старый nginx из epel, минимальный max_children (для меня было лучшее значение), можно ещё тюнить mysql, я привёл стандартный конфиг «mysql small». Ещё репозиторий varien похоже забросили, но исходники со спеками там есть.
php-fpm конечно. Это рабочая конфигурация, без апача, с rewrite. Апач не нужен для генерации динамического контента, он может понадобится из-за каких-то своих специфических модулей или заморочек с .htaccess (решаемо в nginx). Вообще на хостингах где стоит nginx+apache, apache оставляют не для «генерации», так как там всё равно генерит динамику fcgi(fcgid), он нужен из-за модулей, rewrite, htaccess etc.
Php-fpm, как известно, глючит при работе с ним через unix-сокет, об этом было неоднократно сказано в рассылке разрабов, советую поменять его работу на tcp-сокет, если не хотите периодически ловить 503 и 504.
Сам конкретного по 50* ничего не нашёл, что-то есть, но не то. Реализовать 50* у себя синтетическими тестами не получилось. Но через tcp работает немного быстрее (у меня 48-49 против 50 секунд, что в принципе в рамках погрешности). Поправил статью с учётом работы черех tcp, оставив сокет в комментах.
стопстопстоп… Я никогда не использовал нгинкс… Расскажи, что в нем заменяет хтакцесс? Я всегда считал, что нгинксом рулит только егойный конфиг и более ничего.
Вы правильно понимаете работу nginx, меня неправильно поняли :). Я имел ввиду, что можно переписать правила .htaccess для конфига nginx, ну и ложить их например в conf.d/. Вот например _http://bit.ly/aPweyH. То-есть для одиночных сайтов можно отказаться от апач, на хостинге нет (замучаться можно под каждого конфиг nginx делать).
Ну так вот когда нгинкс научится дополнять свой конфиг по пути следования до целевого файла и соответственно несколько менять свое поведение, тогда наступит рай на земле. Можно будет переписать хтакцессы в его формат и накласть новые конфиги рядом с хтакцесссами, так что не важно на чем работает сайт, работать он будет одинаково.
Можно скриптами реализовать некоторые варианты :). Но это конечно не айс, хотя мы да и многие, немного для другого (динамической генерации конфига nginx), делали.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.
А кто будет генерировать динамический контент?
Вот тут можете почитать, в целом все работает, но иногда возникают проблемы.
Как я понял, проблемы только в Linux, т.к. народ с БСД пишет что разницы вообще нет.