Назад | Перейти на главную страницу

NGINX крайне неэффективно обслуживает большие файлы mp4

В настоящее время я запускаю nginx / 1.0.15 в ОС Centos 6.6. Сервер имеет следующие характеристики:

Эта проблема

Сервер имеет соединение со скоростью 1 Гбит / с, однако он достигает максимума и блокируется после 400-500 Мбит / с. Служба начинает снижаться примерно при 100 подключениях ... и скорость с сервером резко падает (несмотря на то, что 50% пропускной способности все еще доступны)

Сервер NGINX предназначен исключительно для обслуживания статических файлов .mp4. Размер каждого файла обычно составляет 400–1200 МБ (в среднем 700 МБ).

Я перепробовал много разных конфигураций, и почти все они дали мне одинаковые результаты .. Я очень расстроен ..

Нагрузка на сервер тоже никогда не превышает 0,3.

Есть ли что-нибудь явно неправильное или неправильное в моей конфигурации? Все может помочь.

Конфигурации

/etc/nginx/nginx.conf

user              nginx;
worker_processes  9;

error_log  /var/log/nginx/error.log;


pid        /var/run/nginx.pid;


events {
    worker_connections  51200;
    use epoll;
 }

worker_rlimit_nofile 600000;

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;
access_log off;

aio on;
sendfile        off;
tcp_nopush      off;
tcp_nodelay      on;

#keepalive_timeout  0;
keepalive_timeout  65;

output_buffers 1 3m;
#gzip  on;

include /etc/nginx/conf.d/*.conf;

open_file_cache          max=10000 inactive=5m;
open_file_cache_valid    2m;
open_file_cache_min_uses 1;
open_file_cache_errors   on;

}

/etc/nginx/conf.d/default.conf

server {
    listen       80 default_server sndbuf=32k;
    server_name  _;

    #charset koi8-r;

    #access_log  logs/host.access.log  main;

    include /etc/nginx/default.d/*.conf;


    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location /Videos/ {
        root /home;
        gzip off;
        gzip_static off;

        mp4;
        mp4_max_buffer_size   300m;
    }

    location /stats {
        stub_status on;
    }

    error_page  404              /404.html;
    location = /404.html {
        root   /usr/share/nginx/html;
    }


    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

Лучшим началом может стать набор следующих правил:

  1. отключить ведение журнала и accept_mutex
  2. включить sendfile
  3. установить sendfile_max_chunk

Конфигурация:

events {
    accept_mutex off;
}

access_log off;
sendfile on;
sendfile_max_chunk 512k;

Новый пул потоков функций Nginx (1.7.11 или новее) может быть действительно полезен в вашем случае:

location / {
    root /home;
    aio threads;
    mp4;
}

На тестовых образцах это значительно помогает увеличить пропускную способность с 1 Гбит / с до 9 Гбит / с. Девять раз! У вас всего 1 Гбит / с, но он использует все.

Смотрите подробнее: https://www.nginx.com/blog/thread-pools-boost-performance-9x/

Для начала лучше всего начать с самих файлов .mp4, где обычно есть много областей для улучшения.

Поэтому, прежде чем теряться в настройке NGINX или Apache, сначала настройте свои файлы .mp4.

Для этого поста кинематографический ролик похож на фильм или телешоу, где требуется смена каждого кадра. Другими словами, попытка перекодировать такой фильм, как «Семейка Крудс», на 1 кадр / с (кадр / секунду) снизит качество до невозможного для просмотра.

А не кинематографический - это снимки экрана, такие как веб-семинары, которые наши учебные программы размещают в Udemy.

Сначала рассмотрим звуковую составляющую файла. Если аудиокомпонент в основном говорит, используйте ffmpeg для перекодировки файла, в который вы копируете видеопоток (без изменений) + конвертируйте стереопоток в моно. Для многих файлов .mp4 (не кинематографических) примерно 1/3 размера файла фильма составляет видео + 1/3 - левый аудиоканал + 1/3 - правый аудиоканал. Переход от стерео к моно может значительно уменьшить размер файла.

Во-вторых, перекодируйте звук с помощью FDK-AAC (https://github.com/mstorsjo/fdk-aac), который создает файлы гораздо меньшего размера, чем другие кодировщики aac. Большинство современных версий ffmpeg в наши дни автоматически собирают FDK-AAC. Даже Macports теперь строит это. Одно соображение: для того, чтобы FDK творила настоящую магию, требуется стереодорожка + при использовании FDK стереозвук сжимается намного меньше, чем моно, поэтому, если вы используете FDK, придерживайтесь стерео.

В-третьих, для звука уменьшите битрейт. Часто это 48k, поэтому обычно используйте -ar 44100 (ffmpeg) или для разговорной речи (low fi) рассмотрите возможность снижения до 22050.

В-четвертых, установите как можно более низкую частоту кадров вашего видео. Поэтому, если вы делаете снимок экрана, кадр может меняться только один раз в 10-60 секунд, поэтому вы можете снизить частоту кадров с помощью -r $ fps, много раз с 30-60 кадров в секунду до 1-5 кадров в секунду + качество останется прежним. при этом размер файла резко падает.

Много раз я сжимаю файлы, не относящиеся к кинематографическим, где каждый 1 ГБ уменьшается до 10-20 МБ.

В-пятых, убедитесь, что атом mov faststart находится в начале ваших файлов, чтобы ваши файлы можно было передавать в потоковом режиме, а не загружать.

Мои параметры ffmpeg fdk ...

-c: a libfdk_aac -profile: a aac_he_v2 -afterburner 1 -signaling explicit_sbr -vbr 5 -ac 2 -ar 44100

Фактически, вот типичная полная команда ffmpeg ...

Сценарий mp4 - это просто оболочка для ffmpeg, которая делает такие вещи, как предположение, какие аудио + видеодорожки находятся на английском языке (для многодорожечных файлов avi + mkv) + затем создает команду ffmpeg. Что интересно, так это настоящая команда, которая является остатком многолетних экспериментов.

Попробуйте сначала запустить свои файлы через экстремальное сжатие ffmpeg, а затем посмотрите, настолько ли малы веса файлов, что настройка веб-сервера не требуется.

Области экспериментов: -r $ fps + -v: crf + -v: preset + -ar bitrate

Немного поэкспериментировав, вы получите настройки минимального размера файла + приемлемого качества.

Многие из странных опций, таких как + genpts + очистка SAR / DAR, существуют для обеспечения воспроизведения файлов .mp4 на устройствах Roku. Их хорошо сохранить, если вы каждый настраиваете свой собственный канал Roku, который является бесплатным способом охватить более 5 000 000 семей.

Моя команда ffmpeg ...

imac> mp4 --dr --noisy foo.avi

tc: diag = v:! h264: mpeg4, a:! aac: ac3 title = 'Foo (TC)' Foo-640x480-veryfast-crf18-max-tc.mp4

cd '/Users/david/Downloads/Casper.A.Spirited.Beginning.1997.DVDrip.iNTERNAL.XviD-BPDcarrier' nice -19 ffmpeg -fflags + genpts -i "foo.avi" -map 0: 0 -c: v libx264 -crf: v 18 -preset: v veryfast -tune: v film -level: v 4.1 -profile: v high -bufsize: v 5000k -vf setdar = dar = 0, setsar = sar = 0 -x264opts colorprim = bt709 : transfer = bt709: colormatrix = bt709: fullrange = off -r 29.97 -movflags + faststart -map 0: 1 -c: a libfdk_aac -profile: a aac_he_v2 -afterburner 1 -signaling explicit_sbr -vbr 5 -ac 2 -ar 44100 - метаданные title = 'Foo (TC)' -threads 0 -f mp4 -benchmark Foo-640x480-veryfast-crf18-max-tc.mp4.tmp mv -f Foo-640x480-veryfast-crf18-max-tc.mp4.tmp Foo-640x480-veryfast-crf18-max-tc.mp4

У меня сработало включение multi_accept (раньше видео останавливалось примерно на полпути, и посетитель не мог слушать / смотреть вторую половину, что очень расстраивало).

Единственное, что я установил в nginx.conf под событиями, это следующее:

events {
worker_connections 768;
multi_accept on;
}

** Это работает сегодня LOL .... завтра нам просто нужно посмотреть, будет ли он по-прежнему играть полностью