Linux/nginx high load
Тюнинг под большое количество запросов (DDoS)
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1
net.ipv4.tcp_max_tw_buckets=500000
net.core.somaxconn=32768
net.ipv4.tcp_max_syn_backlog=32768
net.ipv4.tcp_synack_retries=3
И поднимаем backlog в nginx до 30к(полный рестарт вроде нужен) - это всё обычно помогает против
kernel: possible SYN flooding on port 80. Sending cookies.
который как раз и генерируется при переполнении(или большом заполнении) backlog. При переполнении backlog дропаются SYN-пакеты, и возникают хорошо известные 3-хсекундные задержки соединения. Было полезно
watch --differences=cumulative --interval=1 "netstat -s|grep -A10 ^Tcp:"
watch --differences=cumulative --interval=1 "netstat -s|grep -A50 ^TcpExt:"
watch --differences=cumulative --interval=1 curl -s 127.0.0.1:8000
Разумеется, в фаерволе лучше на всякий случай отключить connection tracking для 80-го порта
- Тюнинг под выдачу видео, по мотивам
Прошёл несколько фаз
- увеличение количества worker'ов в nginx, добавление дисков
- обновление nginx и включение aio(+directio+патчи) для flv(а потом и для статики), read_ahead
- ограничение скорости выдачи на запрос чтобы обслужить больше клиентов в один момент времени - тк упор не в диски, а в канал.
- переход на схему nginx frontend + static -> (nginx backend flv sendfile, apache)
- переход на схему nginx frontend - > (nginx backend static sendfile, nginx backend flv sendfile, apache)
Ключевые моменты (неочевидные)
- увеличение кол-ва worker'ов всё равно не решает проблемы медленной работы сайта
В ОС в /etc/rc.local
/sbin/blockdev --setra 1024k /dev/sd? /dev/md?
/sbin/ethtool -G eth1 tx 2048 rx 2048
nginx 0.8.52+aio+патчи Максима Дунина+open_file_cache
read_ahead 1;
aio on;
directio 512;
output_buffers 2 256k;#4 flv
output_buffers 2 64k;#4 static
в ОС(дополнительно к тюнингу под ддос :)
fs.aio-max-nr=262144
ограничение скорости выдачи видео на запрос
- через mediainfo в цикле + awk,sort получение битрейта на все video, берём максимальный - например 1мбит
- ограничиваем скорость выдачи до 2x MAX через limit_rate в кБайтах (256к)
выдаём 5-8 секунд видео без ограничения через limit_rate_after (768k)
AIO на Linux плохо тем, что работает только с directio, а значит в обход кеша. А 7гиг кеша это вкусно - учитывая блоговую природу движка выдачи видео, имеется горячий контент, который и можно отдавать из кеша. Ключевые настройки nginx-backend
worker_processes 16;#adjust for disk subsystem
worker_rlimit_nofile 16384;
events {
worker_connections 1000;
multi_accept off;
accept_mutex off;
}
sendfile on;
keepalive_timeout 0;
gzip off;
open_file_cache max=10000 inactive=300s;
open_file_cache_valid 1200s;
open_file_cache_errors on;
open_file_cache_min_uses 1;
listen'ы желательно сделать похожими на
listen 127.0.0.1:85 default sndbuf=524288 backlog=2048 deferred;
listen unix:/tmp/nginx.sock default sndbuf=524288 backlog=2048 ; # deferred is not supported
большой sndbuf позволит nginx-backedn'у выплюнуть данные в ядро большим куском, а затем nginx-frontend будет их тянуть уже как ему надо в зависимости от клиента. Секция flv nginx-backend
location ~ \.flv$ {
flv;
read_ahead 1;
sendfile_max_chunk 256k;
send_timeout 180;
limit_rate 256k;
limit_rate_after 768k;
}
Секция flv nginx-frontend
location ~ \.flv$ {
output_buffers 2 256k;
# proxy_pass http://127.0.0.1:85;
proxy_pass http://unix:/tmp/nginx.sock;
proxy_buffering off;
proxy_buffer_size 512k;#equal to sndbuf of nginx-backend
proxy_read_timeout 30;
proxy_send_timeout 30;
proxy_connect_timeout 20;
access_log off;
}
работа через unix-сокеты показала себя более стабильно - при использовании tcp-сокетов nginx-backend забивался коннектами по невыясненным причинам, и приходилось рестартить фронтенд для сброса коннектов.
- сайт имеет много мелкой статики в интерфейсе. Использование sendfile на нагруженной дисковой подсистеме - фронтенд блокируется на диске(и проседает всё), использование aio - реальные походы(много!) к нагруженной дисковой. Решение - ещё один nginx-backend с sendfile под выдачу статики, блокирование которого не приводит к проблемам, плюс бОльшая часть едет из кеша ОС. Ключевые настройки nginx-backend - такие же как для flv, только количество worker'ов меньше.
nginx-backend локейшн для статики
location ~ \.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|wmv|wma|mp3|mpg|avi|mpeg|mp4|divx)$ {
index index.html index.htm index.php index.shtml;
access_log off;
sendfile_max_chunk 256k;
send_timeout 15;
}
nginx-frontend локейшн для статики
location ~ \.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|wmv|wma|mp3|mpg|avi|mpeg|mp4|divx)$ {
index index.html index.htm index.php index.shtml;
access_log off;
output_buffers 2 64k;
# proxy_pass http://127.0.0.1:85;
# proxy_pass http://unix:/tmp/nginx.sock;
proxy_pass http://unix:/tmp/nginx3.sock;
proxy_buffering off;
proxy_buffer_size 128k;
proxy_read_timeout 30;
proxy_send_timeout 30;
proxy_connect_timeout 20;
}
Авторан всех 3-х nginx
- nginx-frontend - системный авторан
- остальные - в /etc/rc.local
#http://nginx.org/pipermail/nginx-ru/2010-June/034560.html and following
rm -f /tmp/nginx.sock
/usr/sbin/nginx -c /etc/nginx2/nginx.conf
rm -f /tmp/nginx3.sock
/usr/sbin/nginx -c /etc/nginx3/nginx.conf