Заход номер два, конфигурационный файл nginx.
Рассмотрим конфиг сервера на примере того что есть у меня под рукой, самый простой веб-сервер, без наворотов и прибамбасов.
Итак разбираем построчно. Небольшое замечание - в примере не указаны значения по умолчанию.
##################### NGINX.CONF ###################################
# пользователь от которого запускается сервер
user nginx;
# количество потоков, обрабатывающих запросы клиентов, обычно достаточно руководствоваться формулой (количество ядер * 2) + 1 , однако если активно используется диск (или fcgi через unix socket) то имеет смысл добавить ещё несколько процессов, потому что на момент выполнения операций дискового(только ли?) ввода/вывода процесс блокируется, что снижает интерактивность веб-сервера
worker_processes 5;
# ограниечения по количеству открытых файлов (файлом является каталог, файл, сокет) и очереди posix сигналов
worker_rlimit_nofile 10240;
worker_rlimit_sigpending 32768;
# разрешающая способность таймера (влияет на точность времени в логах)
timer_resolution 5000ms;
# приоритет процессов-обработчиков
worker_priority -5;
# вышеперечисленные параметры влияют на интерактивность отдачи контента, чем выше приоритет, тем выше скорость набора скорости, тем лучше способность удержания высокой скорости отдачи, тем выше эффективность использования канала; чем выше разрешающая способность таймера тем выше скорость переключения между потоками, тем выше интерактивность веб-сервера; однако при высокой интерактивности и высоком приоритете повышается нагрузка на процессор, при большом количестве клиентов (более нескольких сотен одновременно) с этими параметрами надо играть аккуратнее.
# Вот что написано в офциальной документации: The directive allows to decrease number gettimeofday() syscalls. By default gettimeofday() is called after each return from kevent(), epoll, /dev/poll, select(), poll(). But if you need an exact time in logs when logging $upstream_response_time, or $msec variables, then you should use timer_resolution. То есть эта директива позволяет уменьшить количество системных вызовов gettimeofday(), что бывает полезно при больших нагрузках однако при этом падает точность временных отметок в логах. По-умолчанию вызов gettimeofday() производится при выходе из kevent(), epoll, /dev/poll, select(), poll().
error_log /var/log/nginx/error.log;
#error_log /var/log/nginx/error.log notice;
#error_log /var/log/nginx/error.log info;
pid /var/run/nginx.pid;
events {
# количество соединений, обрабатываемых каждым потоком
worker_connections 1024;
# механизм переключения между потоками, у нас нормальная система, поэтому мы используем epoll, а не kqueue и не ту муть которую нам предлагает венда
use epoll;
# используется ли мьютекс для вызова accept(), если нет, тогда используется лок-файл (путь к которому задаётся директивой lock_file /путь/к/файлу; ), что значительно медленнее
accept_mutex on;
# Если рабочий процесс не имеет ассоциированного с ним мьютекса с системным вызовом accept(), то по просшествии этого времени он будет снова пытаться найти этот мьютекс. Иными словами частота опроса сокета на предмет приёма очередного коннекта
accept_mutex_delay 10000ms;
# следует отметить, что при больших нагрузках точность таймера начинает плавать, а при огромных (более 20 на одноядерном процессоре по показаниям top) весьма заметно, кроме того разрешающая способность ванильного ядра довольно высока - единицы милисекунд, а у RT ядра 1 милисекунда.
# несколько запросов на мьютекс
multi_accept on;
}
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;
# формально корень сайта (очень желательно, чтобы совпадал с тем, который задаётся в момент сборки сервера, но необязательно)
root /var/www;
# подписывать ли версию ПО сервера в ответе клиенту
server_tokens on;
# без коментариев
ignore_invalid_headers on;
#
server_name_in_redirect off;
# таблица соответствий имени виртуального хоста его адресу
server_names_hash_bucket_size 128;
# ограничение по скорости на интерфейсах в том числе и backend и fcgi(?)
limit_rate 10000M;
# наверно идеальным можно считать буфер, равный средне арифметической длине отдаваемых наиболее часто страниц...
output_buffers 256 96k;
# системный вызов, если реализован в операционном окружении, его использование ускоряет отдачу контента небольшой и средней величины, если отдаваемые файлы слишком большие и их количество велико sendfile начинает уходить в своп, а это уже плохо
sendfile on;
# размер разового куска информации для системного вызова sendfile
sendfile_max_chunk 128k;
# использовать ли при создании сокета опцию TCP_NOPUSH на FreeBSD или TCP_CORK на Linux
#"tcp_nopush on" полезно для sendfile(), он в этом случае выводит данные полными пакетами. После того, как весь запрос обработан, TCP_CORK/TCP_NOPUSH выключается, что приводит в сбросу последнего неполного пакета.
tcp_nopush on;
# использовать ли при создании сокета опцию TCP_NODELAY, применяется только к keepalive соединениям (вроде бы отключает алгоритм nagle, при котором сразу после инициализации берётся маленькая пауза, после которой начинается передача данных)
tcp_nodelay on;
#
postpone_output 1460;
#"tcp_nodelay on" полезно для keep-alive. nginx включает TCP_NODELAY только по окончании запроса, после которого соединение переходит в состоянии keep-alive. До этого nginx выводит данные вызовами writev() достаточно большими порциями для заполнения пакета ("postpone_output 1460"), поэтому данные должны уходить без задержек и TCP_NODELAY не нужен. А вот с последним неполным пакетом может случится небольшая задержка, если соединение не закрывается. Для этого и нужно включить TCP_NODELAY.
# как долго держать соединение открытым в надежде получить данные по нему (очередной http запрос)
keepalive_timeout 30;
# посылать rst пакет, по истечении таймаута соединения
reset_timedout_connection on;
# считать соединение разорванным по истечении этого времени в секундах
send_timeout 90;
# linger connection - полузакрытое соединение, возникает при http pipelining, а также при запросах PUT и POST, если авторизация не была произведена корректно. Это соединения в состоянии FIN_WAIT_2 в rfc ничего не сказано по поводу таймаута такого соединения, то есть формально это соединение должно болтаться до перезагрузки системы, однако большинство операционных систем научились бороться с этим явлением выставляя таким соединениям таймауты, и тем самым сознательно идя на нарушение rfc протокола tcp, однако принято считать, что это вынужденное нарушение из-за несовершенства описания этой ситуации.
#
lingering_time 90;
#
lingering_timeout 90;
# количество захэшированных mime-типов данных
types_hash_bucket_size 128;
# Разрешает или запрещает выдавать в ответе строку заголовка "Vary: Accept-Encoding", если директивы gzip или gzip_static активны.
gzip_vary on;
# выключить сжатие для "кривых" браузеров
gzip_disable "MSIE [1-6]\.";
# включить сжатие исходящего контента глобально
gzip on;
# Директива задаёт число и размер буферов, в которые будет сжиматься ответ. По умолчанию размер одного буфера равен размеру страницы памяти, в зависимости от платформы это или 4K (x86), или 8K. До версии 0.7.28 по умолчанию использовалось 4 буфера размером 4K или 8K.
gzip_buffers 40 8k;
# наибыстрейшее сжатие при наименьшей загрузке процессора
gzip_comp_level 1;
# сжимать проксированные запросы
gzip_proxied any;
# типы контента, которые сжимать
gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss;
# используется для чтения тела ответа. В том числе и для записи в файл.
client_body_buffer_size 32k;
# Кэш дескрипторов файлов, названия красноречивы
open_file_cache max=1000 inactive=20m;
open_file_cache_valid 30m;
open_file_cache_min_uses 2;
open_file_cache_errors on;
proxy_cache_path /tmp/nginx-cache levels=1:2 keys_zone=one:10m inactive=20m max_size=500m;
# Load config files from the /etc/nginx/conf.d directory
include /etc/nginx/conf.d/*.conf;
#
# The default server
#
server {
# Для гигабитной сети вполне подойдут эти настройки, бэклог в операционном окружении должен быть больше чем обозначенный здесь
listen 80 default backlog=4096 rcvbuf=2777216 sndbuf=2777216 deferred;
server_name 10.32.0.232;
# опциональная настройка - где находится DNS сервер - очень хороший вариант повесить его на ту же тачку в качестве dns прокса и настроить его на проксирование запросов к нескольким внешним dns (желательно не менее чем к трём, если на сайт приходит довольно много народу, более 100 человек одновременно, желательно повесить это на отдельную сетевушку, которая работает для backend сети)
resolver 127.0.0.1;
resolver_timeout 3s;
#charset koi8-r;
#access_log logs/host.access.log main;
root /var/www;
location / {
root /var/www/html;
index index.html;
}
location /distr {
root /var/www;
autoindex on;
}
location /mrepo {
root /var/www;
ssi on;
ssi_types text/shtml;
autoindex on;
}
location /icons {
root /var/www;
}
location /usage {
root /var/www;
}
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;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# запросы к перловым скриптам - на бэкэнд
location ~ \.pl$ {
# если файла нет, незачем тратить на него ресурсы бэкэнда
if (!-f $request_filename) {
return 404;
break;
}
proxy_pass http://127.0.0.1:8000;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 512k;
proxy_buffering on;
output_buffers 4096 8k;
proxy_connect_timeout 40;
proxy_send_timeout 40;
proxy_read_timeout 90;
proxy_buffer_size 8k; # < - если маленький, может быть причиной нерегулярных 500-х ошибок, подбирается с небольшим запасом, большой буфер вызывает задержки
proxy_buffers 32 16k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 256k;
# относительно свежая фича - кэширование ответа от апстрима - следует использовать довольно осторожно, на некоторых приложениях может вызывать ошибки или непредвиденную реакцию, например у squirrel mail если неправильно авторизуешься, то потом долго не получится авторизоваться :)
proxy_cache_key "$scheme://$host$uri$is_args$args:";
# используем хранилище под названием one, описанное выше в proxy_cache_path
proxy_cache one;
proxy_cache_min_uses 1;
proxy_cache_valid 200 30s;
proxy_cache_use_stale error timeout http_500 http_502 http_503;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
# если файла нет, незачем тратить на него ресурсы fcgi
if (-f $request_filename) {
return 404;
break;
}
root /var/www/cgi-bin;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/cgi-bin$fastcgi_script_name;
include fastcgi_params;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /\.ht {
deny all;
}
}
}
Форматирование немного съехало из-за использования тэга <PRE>