Есть две слабеньких виртуальных машины на AWS (1 CPU, 1 ГБ RAM). На одной крутится nginx с php-fpm, на второй MySQL.
Обе ВМ для сервиса email-рассылок, с базой в примерно 500 тыс. адресов.
По крону выполняются довольно тяжелые скрипты:
1. Собственно отправка (~10 писем в секунду).
2. Обновление сегментов.
3. Импорт базы (редко, но грузит сильно, импорт пары сотен тысяч может идти несколько часов, тормозя всё остальное).
Кроме этого в процессе отправки рассылок на nginx и php-fpm (и далее MySQL) прилетает куча легких запросов, когда пользователи открывают письма и переходят по ссылкам (настроен трекинг открытий и переходов по ссылкам). Ну и плюс всякие мелочи, вроде жалоб на спам, отписок и т.п.
Статику для писем (картинки, шрифты) уже и так перекинул на другой сервер.
Проблемы:
1. Когда идет рассылка ВМ явно не выдерживают нагрузку, переходы по ссылкам в письмах могут обрабатываться по 10-15 секунд, что очень много, и плохо влияет на переходы из рассылки.
2. Обновление сегментов очень тормозит. Простой сегмент обновляется примерно минуту. Тяжелый около 12 минут. Всего сегментов несколько десятков, из которых большинство тяжелые. Желательно их обновлять хотя бы несколько раз в день.
Собственно, я не силен в администрировании и прочитав ряд гайдов прописал в конфигах такое:
/etc/php/7.4/fpm/pool.d/www.conf
pm = ondemand
pm.max_children = 128
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.process_idle_timeout = 30s;
pm.max_requests = 2048
request_terminate_timeout = 0
/etc/php/7.4/fpm/php.ini
max_input_vars = 2048
memory_limit = 512M
max_input_time = 600
max_execution_time = 900
max_execution_time = 900 потому что по крону скрипты запускаются раз в 15 минут. Может лучше 0, как request_terminate_timeout?
Остальное в php - дефолтные значения.
/etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 2048;
multi_accept on;
}
http {
##
# Basic Settings
##
charset utf-8;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_requests 2048;
keepalive_timeout 360;
send_timeout 120;
client_body_timeout 90;
client_header_timeout 90;
client_body_buffer_size 16M;
client_header_buffer_size 8K;
client_max_body_size 64M;
types_hash_max_size 4096;
reset_timedout_connection on;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log off;
error_log /var/log/nginx/error.log crit;
##
# Gzip Settings
##
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
gzip_min_length 256;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
В конфиге хоста:
...
location / {
try_files $uri $uri/ /$uri.php$is_args$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
include fastcgi_params;
fastcgi_read_timeout 900;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_intercept_errors on;
fastcgi_index index.php;
}
...
Буду благодарен советам что лучше изменить (и почему) или что почитать, чтобы лучше понимать как это все работает. :)
PS: Уменьшать скорость отправки не вариант, рассылка по полной базе и так идет 10-15 часов, что уже очень долго (письма упавшие в ящик ночью показывают процент открытий в разы меньше, чем дневные).