Определить Nginx worker_processes и worker_connections
Настройки по умолчанию хороши, но их стоит немного оптимизировать: max_clients = worker_processes * worker_connections
.
Базовые настройки Nginx могут обрабатывать сотни одновременных соединений:
1
2
|
worker_processes 1;
worker_connections 1024;
|
Обычно 1000 одновременных соединений на один сервер это хорошо, но порою другие части, например жесткий диск могут оказаться медленными и это приведет к тому, что Nginx будет заблокирован на операции ввода-вывода (I/O). Чтобы избежать блокировки используйте, например, следующие настройки: одни worker_process на ядро процессора
:
Worker Processes
1
|
worker_processes = [число ядер процессора];
|
Чтобы определить сколько ядер имеет ваш процессор, введите:
1
2
3
4
5
|
$ cat /proc/cpuinfo | grep processor
processor : 0
processor : 1
processor : 2
processor : 3
|
В данном случае у меня четыре ядра, поэтому окончательный парамерт worker_processes
устанавливаем как 4:
1
|
worker_processes = 4;
|
Worker Connections
Лично я придерживаюсь 1024 соединений на один воркер, потому что у меня нет никаких оснований для повышения этого значения. Но если например 4096 соединений в секунду не хватает, то можно попробовать удвоить 2048 соединений на процесс.
Окончательные настройки выглядят седующим образом:
1
|
worker_connections 1024;
|
Скрыть токены Nginx / Скрыть номер версии Nginx
Это хорошо из соображений безопасности — скрыть токены Nginx и скрыть номер версии Nginx, тем более если вы используете устаревшую версию Nginx. Это очень легко сделать — достаточно добавить в секцию http/server/location
файла конфигурации следующую строку:
1
|
server_tokens off;
|
Ограничение на размер передаваемых данных сервером Nginx
Если вы хотите разрешить пользователям загружать файлы, то вы должны увеличить размер сообщения. Это может быть сделано с помощью значения client_max_body_size
, которое находится в секции http/server/location
файла конфигурации. По умолчанию он равен 1 Мб, но его можно увеличить, например, до 20 Мб, а также увеличить размер буфера:
1
2
|
client_max_body_size 20m;
client_body_buffer_size 128k;
|
Если вы получаете сообщение об ошибке, то вы знаете, что client_max_body_size
слишком мало:
«Request Entity Too Large» (413)
Управление кешем для статических файлов
Кэш браузера сохранит ресурсы и пропускную способность вашего сервера. Это несложная настройка Nginx позволит выключить ведение логов (access log
и not found log
), и установить срок истечения заголовка в 360 дней.
1
2
3
4
5
|
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
access_log off;
log_not_found off;
expires 360d;
}
|
Если вы хотите более сложный заголовки или другие типы файлов, то вы можете настроить их отдельно.
Проксируйте PHP запросы к PHP-FPM
Вы можете использовать по умолчанию стек tcp/ip
или соединение через Unix-сокет. Также необходимо установить PHP-FPM слушать точно такой же ip:port
или Unix-сокет. Вот очень простой пример конфигурации (вариант с Unix-сокетом закоментирован):
1
2
3
4
5
6
7
8
9
|
# Pass PHP scripts to PHP-FPM
location ~* \.php$ {
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
#fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
|
Это дает возможность запуска PHP-FPM другим сервером.
Предотвращение (запрет) доступа к скрытым файлам
Это очень распространено, когда корень сервера или другие публичные каталоги имеют скрытые файлы, которые начинаются с точки (.) И, как правило, они не предназначены для пользователей сайта. Публичный каталог может содержать файлы системы контроля версий: .git
, .svn
; файлы IDE: .idea
; .htaccess
файлы. Настройки запещают доступ к скрытым файлам и отключают ведение логов:
1
2
3
4
5
|
location ~ /\. {
access_log off;
log_not_found off;
deny all;
}
|
Советы по настройке и оптимизации PHP-FPM
Файлы конфигурации PHP-FPM
Обычно конфигурации PHP-FPM расположенны в файле /etc/php-fpm.conf
и в каталоге /etc/php-fpm.d/
. Весь пулл конфигов расопложен в дикертории /etc/php-fpm.d/
. Чтобы это работало, вы должны добавить следующую строку в php-fpm.conf
:
1
|
include=/etc/php-fpm.d/*.conf
|
Глобальная конфигурация PHP-FPM
Настройки emergency_restart_threshold
, emergency_restart_interval
и process_control_timeout
по умолчанию выключены, но я считаю что их стоит влючить, например, со следующими значениями:
1
2
3
|
emergency_restart_threshold 10
emergency_restart_interval 1m
process_control_timeout 10s
|
Что это значит? Если 10 дочерних процессов PHP-FPM завершатся с помощью SIGSEGV или SIGBUS в течении 1 минуты, то PHP-FPM перезагрузится автоматически. А также дочерним процессам установлен лимит времени реакции в 10 секунд на сигнал от мастера.
Конфигурация пулов PHP-FPM
В PHP-FPM возможно использовать отденьные пулы для каждого сайта и точно распределять ресурсы, а также использовать разных пользователей и разные группы для каждого пула. Приведем примеры конфигураци трех различнх сайтов (или фактически три части одного сайта):
/etc/php-fpm.d/site.conf
/etc/php-fpm.d/blog.conf
/etc/php-fpm.d/forums.conf
Примеры конфигурации каждого пула:
/etc/php-fpm.d/site.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
[site]
listen = 127.0.0.1:9000
user = site
group = site
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/slowlog-site.log
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 5
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 200
listen.backlog = -1
pm.status_path = /status
request_terminate_timeout = 120s
rlimit_files = 131072
rlimit_core = unlimited
catch_workers_output = yes
env[HOSTNAME] = $HOSTNAME
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
|
/etc/php-fpm.d/blog.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
[blog]
listen = 127.0.0.1:9001
user = blog
group = blog
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/slowlog-blog.log
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 4
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 200
listen.backlog = -1
pm.status_path = /status
request_terminate_timeout = 120s
rlimit_files = 131072
rlimit_core = unlimited
catch_workers_output = yes
env[HOSTNAME] = $HOSTNAME
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
|
/etc/php-fpm.d/forums.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
[forums]
listen = 127.0.0.1:9002
user = forums
group = forums
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/slowlog-forums.log
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 10
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 400
listen.backlog = -1
pm.status_path = /status
request_terminate_timeout = 120s
rlimit_files = 131072
rlimit_core = unlimited
catch_workers_output = yes
env[HOSTNAME] = $HOSTNAME
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
|
Это просто примеры как настроить несколько различных пулов.
Конфигурация менеджера процессов (Pool Process Manager) PHP-FPM
Лучший способ использовать менеджер процессов PHP-FPM — это донамическое управление процессами, поэтому PHP-FPM запускает процессы только при необходимости. Это почти такой же подход как в Nginx с параметрами worker_processes
и worker_connections
. Таким образом большие значения не обеспечивают хорошего результата. Каждый процесс ест определнное количество памяти и, конечно, если у сайта очень большой трафик и много оперативной памяти на сервере, то высокие значения — это правильный выбор. Но такие серверы как VPS обычно имеют ограниченное количество памяти: 256 Мб, 512 Мб, 1024 Мб. Такого небольшого объема ОЗУ достаточно даже для очень большого трафика (даже десятки запросов в секунду), если эту память использовать с умом.
Проверим сколько процессов PHP-FPM позволит легко справляться серверу с нагрузкой. Сначала запустим Nginx и PHP-FPM и загрузим несколько страниц PHP, желательно самые тяжелые. Затем проверим сколько использует памяти процесс PHP-FPM — в Linux можно воспользоваться утилитами top
или htop
. Предположим что наш сервер имеет 512 Мб оперативной памяти и 220 Мб может быть использованно PHP-FPM, каждый процесс использует 24 Мб оператичной памяти (некоторые CMS с плагинами могут легко кушать 20-40 Мб на один запрос или даже больше). Затем просто вычислим значние max_children
для сервера:
220 / 24 = 9.17
Приемлемым значнием pm.max_children
будет 9. Это значние основанно на среднем значении и возможно далее его необходимо будет изменить, когда вы заметите длительное время использования памяти процессом. После быстрого тестирования несложно выбрать значния pm.start_servers value
, pm.min_spare_servers
и pm.max_spare_servers
.
Окончательная конфигурация нашего примера может выглядеть следующим образом:
1
2
3
4
5
|
pm.max_children = 9
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 200
|
Максималоное количество запросов на процесс по умолчанию не ограничено, но хорошо бы установить какое-нибудь небольшое значение, например 200, и избежать проблем с памятью. Такого вида настрока может обрабарывать большое количество запросов, даже если значение параметра невелико.
=============================================================
Подробный разбор параметров конфигурационных файлов:
Конфигурация и параметры
Глобальный конфиг:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
;;;;;;;;;;;;;;;;;;;;;
; FPM Configuration ;
;;;;;;;;;;;;;;;;;;;;;
;
; Подключаем пулы из указанной директории
include=/etc/php-fpm.d/*.conf
;
;;;;;;;;;;;;;;;;;;
; Global Options ;
;;;;;;;;;;;;;;;;;;
;
[global]
; Расположение PID-файла
pid = /var/run/php-fpm/php-fpm.pid
;
; Путь до лога с ошибками и уровень логирования (alert, error, warning, notice, debug)
error_log = /var/log/php-fpm/error.log
log_level = notice
;
; Если количество процессов достигнет указанного, то произойдет рестарт ...
emergency_restart_threshold = 8
;
; ... через 1 минуту ...
emergency_restart_interval = 1m
;
; ... с лимит времени реакции в 10 секунд на сигнал от мастера
process_control_timeout = 10s
;
; Демонизация процесса
daemonize = no
|
Теперь можно рассмотреть конфигурацию пула (для примера /etc/pfp-fpm.d/blog.conf):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
; Имя пула (не должно совпадать с именем пользователя в системе)
[www]
;
; Адрес с портом или сокет, на который будут идти запросы FastCGI запросы
listen = /tmp/php-fpm.sock
;
; listen.backlog это параметр backlog функции TCP listen того сокета, на котором висит fpm
; параметр backlog отвечает за размер очереди одновременно ожидающих подключений к сокету,
; то есть инициированных (SYN - SYN,ACK - ACK), но еще не принятых сервером (established)
; -1 использует текущий hard limit net.core.somaxconn
listen.backlog = -1
;
; Список ip клиентов, которым разрешено подключение
listen.allowed_clients = 127.0.0.1
;
; Владелец Unix-сокета, его группа и права доступа к сокету
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
;
; Воркеры пула будут работать от имени указанного пользователя и группы
user = nginx
group = nginx
;
; Метод порождения процессов
; static - строго постоянное количество процессов-обработчиков,
; dynamic - переменное количество обработчиков, для которых
;указываетсяминимальноеимаксимальное
; количество процессов, а также количество процессов-обработчиков
; "на подхвате",которыедержатся
; готовыми на случай внезапного наплыва нагрузки, чтобы
; не терять время на порождение новых процессов-обработчиков,
; ondemand - режим, при котором обработчики порождаются только
; при поступлении запросов и завершаются спустя указанный период простоя.
pm = dynamic
;
; Число дочерних процессов, созданных для static, либо
; максимальное число, когда pm установлен в dynamic
pm.max_children = 7
;
; Число дочерних процессов, содаваемых при запуске (только dynamic)
pm.start_servers = 5
;
; Желаемое минимальное число неактивных процессов сервера (только dynamic)
pm.min_spare_servers = 5
;
; Желаемое максимальное число неактивных процессов сервера (только dynamic)
pm.max_spare_servers = 7
;
; Число запросов дочернего процесса, после которого процесс будет перезапущен
; Тут можно ограничить количество запросов, последовательно обслуживаемых одним процессом
; После этого процесс будет завершён и запущен снова - это может помочь от утечек памяти
pm.max_requests = 300
;
; Ссылка, по которой можно посмотреть страницу состояния FPM
;pm.status_path = /status
;
; Ссылка на ping-страницу мониторинга FPM (можно собрать своеобразный health-check)
;ping.path = /ping
;
; Эта директива может быть использована на настройки ответа на ping-запрос
;ping.response = pong
;
; Таймаут для обслуживания одного запроса, после чего рабочий
; процесс будет завершен (если не сработает max_execution_time)
;request_terminate_timeout = 0
;
; Таймаут для обслуживания одного запроса, после чего PHP backtrace
; будет сохранен в файл 'showlog'
; Доступные единицы измерения: s(секунды), m(минуты), h(часы) или d(дни)
request_slowlog_timeout = 2s
;
; Лог-файл для медленных запросов
slowlog = /var/log/php-fpm/www-slow.log
;
; Устанавливает лимит дескрипторов открытых файлов rlimit.
; Значение по умолчанию: определяется значением системы.
;rlimit_files = 1024
;
; Устанавливает максимальное количество используемых ядер rlimit
;rlimit_core = 0
;
; Директория chroot окружения при старте
;chroot =
;
; Chdir изменяет текущую директорию при старте
;chdir = /var/www
;
; Перенаправление STDOUT и STDERR рабочего процесса в главный лог ошибок.
; Если не установлен, STDOUT и STDERR будут перенаправлены в /dev/null в
; соответствии со спецификацией FastCGI
;catch_workers_output = yes
;
; ограничение выполнение файлов по расширению имени
security.limit_extensions = .php .php3 .php4 .php5
;
; Передача переменных окружения и настроек PHP пулу
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com
;php_flag[display_errors] = off
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 128M
php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/session
|
Также, отредактируем php.ini файл, указав:
1
|
cgi.fix_pathinfo = 0
|