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

ограничение скорости выдачи видео на запрос

  1. через mediainfo в цикле + awk,sort получение битрейта на все video, берём максимальный - например 1мбит
  2. ограничиваем скорость выдачи до 2x MAX через limit_rate в кБайтах (256к)
  3. выдаём 5-8 секунд видео без ограничения через limit_rate_after (768k)

  4. 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

results matching ""

    No results matching ""