Jump to content
Калькуляторы

Настройка OTT сервера nginx, linux

Видео, оно конечно файлы :) но есть специфика, что за ними ходят раз в 10 секунд в не зависимостои от. На том что я видел, при *3 от времени чанка и более разницы не видно. Меньше не всегда хорошо выходило, часто закрывались сессии. Но это вообще от клиента сильно зависит. У нас он более менее одинаковый.

 

Кстати, а сколько разных входящих потоков (ну ТВ каналов, и если в разных качествах, то каждое качество считать за канал)? всего, и в среднем в момент времени. А то 20Г+ можно и на одном канале отдать, тогда игры с апстримами смысла не имеют почти, там входящего на этом фоне вообще не булет заметно. а можно на 200 каналов, тогда смысл есть.

зы, с юникс сокетами вынос в апстримы тоже улучшает реакцию.

Share this post


Link to post
Share on other sites

По dpdk-nginx - действительно, оказалось не всё так легко. Хоть инструкция чертовски простая, но тем не менее...

 

И так, пробую простейший вариант с одной 40G сетевой картой/одним CPU/одним ip адресом и одним nginx процессом.


     
  1. dpdk - скомпилил. Забиндил одну i40e сетевую карту на драйвер igb_uio, включил huge_pages на 2GB
  2. dpdk-ans - скомпилил, запустил [./build/ans -c 0x1 -n 1 -- -p 0x1 --config=(0,0,0)]. Во второй консоли с помощью anscli поменял ip адрес с дефолтного 2.2.2.2 на наш. ip адрес пингуется.
  3. dpdk-nginx - взял их конфиг (с "worker_processes 1" и "master_process off"), добавил location для m3u8 и ts файлов. Просто файлы из html - раздаёт.
     

Возникшие проблемы:


     
  1. если nginx запускать без конфига, просто "./objs/nginx -V" - получаю segfault (это из-за дефолтных опций master_process/..?)
  2. запускаю с конфигом - работает, статические файлы с диска раздаёт, но тоже с особенностями:

       
    • если включить sendfile, то ничерта не работает, в консоли на мои curl-запросы пишет "skip linux fd 5"
    • не заработал proxy_pass на unix сокет (m3u8 файлы). Для http:// proxy_pass работает, а вот с сокетом - почему-то нет. В консоли - тот же "skip linux fd 5". Может наш backend (nodejs) как-то править надо, чтобы через socket'ы заработало?
       

Это я что-то недопонял и неправильно сделал, или есть какие-то особенности?

Share this post


Link to post
Share on other sites

OKyHb

прикол в том, что c лупбэком 127.0.0.1 не работает, т.к. dpdk его не поддерживает, на счёт unix-сокетов надо смотреть

 

sendfile работать и не должен потому что у вас сетевой стек другой совсем с dpdk

 

давайте свой конфиг, помогу

Share this post


Link to post
Share on other sites

Сорри за портянки текста, но чтобы ничего не упустить... Мой конфиг:

 

- создание тестового сокета:

 

 

[1]~> cat /var/node/unix.js

var http = require('http'),
       fs = require('fs');

var UnixSocket = "/run/test.socket";

var Server = http.createServer(function (req, res) {
       var data = [''];

       data.push('METHOD: '+ req.method);
       data.push('URL: '+ req.url);
       data.push('HEADERS: '+ JSON.stringify(req.headers, null, '  '));
       data.push('');

       process.stdout.write(data.join('\r\n'));

       res.end('OK')
})

fs.unlink(UnixSocket, function() {
       Server.listen(UnixSocket)
})

 

 

- конфиг nginx

 

 

[1]~> egrep -v "^\s*#|^$" ~/dpdk-nginx/conf/nginx.conf
user  root;
worker_processes  1;
error_log  stderr debug;
master_process off;
daemon off;
events {
   worker_connections  1024;
   multi_accept on;
}
http {
   include       mime.types;
   default_type  application/octet-stream;
   sendfile        off;
   keepalive_timeout  65;
   log_format stream "$status:$bytes_sent $uri";
   proxy_cache_key $host$uri;
   proxy_store_access user:rw group:rw all:rw;
   proxy_cache_path /mnt/live levels=1:2 keys_zone=live:16m inactive=1m;
   upstream socket_live {
       server unix:/run/test.socket;
   }
   server {
       listen       80 reuseport;
       server_name  localhost;
       charset utf8;
       server_name test.company.local;
       error_page   403 404 500 502 /status.txt;
       location / {
           return 301 http://company.local;
       }
       location /test {
          proxy_pass http://socket_live;
       }
       location /status.txt {
           return 200 "$status\r\n";
       }

       location /crossdomain.xml {
           root /var/www;
       }
       location ~ "^/tv/(.*)\.ts$" {
           proxy_http_version 1.1;
           proxy_cache live;
           proxy_cache_lock on;
           proxy_cache_valid any 60s;
           proxy_cache_lock_timeout 60s;
           proxy_pass http://10.100.60.2:8080/$1.ts;
       } 
   }
}

 

 

- консоль c запущенным nginx

 

 

[/home/osa/dpdk-nginx]: ./objs/nginx -c ~osa/dpdk-nginx/conf/nginx.conf
EAL: Detected lcore 0 as core 0 on socket 0
EAL: Detected lcore 1 as core 1 on socket 0
EAL: Detected lcore 2 as core 2 on socket 0
EAL: Detected lcore 3 as core 3 on socket 0
EAL: Detected lcore 4 as core 0 on socket 0
EAL: Detected lcore 5 as core 1 on socket 0
EAL: Detected lcore 6 as core 2 on socket 0
EAL: Detected lcore 7 as core 3 on socket 0
EAL: Support maximum 128 logical core(s) by configuration.
EAL: Detected 8 lcore(s)
EAL: Setting up physically contiguous memory...
EAL: WARNING: Address Space Layout Randomization (ASLR) is enabled in the kernel.
EAL:    This may cause issues with mapping memory into secondary processes
EAL: Analysing 1024 files
EAL: Mapped segment 0 of size 0x400000
EAL: Mapped segment 1 of size 0x400000
EAL: Mapped segment 2 of size 0x800000
...

EAL: Mapped segment 205 of size 0x200000
EAL: memzone_reserve_aligned_thread_unsafe(): memzone <RG_MP_log_history> already exists
RING: Cannot reserve memory
EAL: TSC frequency is ~3499998 KHz
EAL: Master lcore 0 is ready (tid=7af38a00;cpuset=[0])
USER8: LCORE[-1] anssock any lcore id 0xffffffff 
USER8: LCORE[1] anssock app id: 10796 
USER8: LCORE[1] anssock app name: nginx 
USER8: LCORE[1] anssock app bind lcoreId: 0 
USER8: LCORE[1] anssock app bind queueId: 0 
USER8: LCORE[1] anssock app lcoreId: 1 
skip linux fd 5 
2016/06/10 13:05:50 [notice] 10796#0: using the "epoll" event method
2016/06/10 13:05:50 [notice] 10796#0: nginx/1.9.5
2016/06/10 13:05:50 [notice] 10796#0: built by gcc 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC) 
2016/06/10 13:05:50 [notice] 10796#0: OS: Linux 3.10.0-327.10.2.ott.x86_64
2016/06/10 13:05:50 [notice] 10796#0: getrlimit(RLIMIT_NOFILE): 1024:4096
2016/06/10 13:06:05 [info] 10796#0: *1 client 10.10.50.13 closed keepalive connection
skip linux fd 7 
...

 

 

 

Вроде как nginx к тестовому сокету обращается:

[~]: /usr/local/bin/node /var/node/unix.js

METHOD: GET
URL: /test
HEADERS: {
 "host": "socket_live",
 "connection": "close",
 "user-agent": "curl/7.49.1",
 "accept": "*/*"
}

 

Но на запрос nginx ничего не возвращает, и в консоль пишет:

skip linux fd 7 
2016/06/10 13:06:38 [info] 10796#0: *2 client prematurely closed connection, so upstream connection is closed too while sending request to upstream, client: 10.10.50.13, server: localhost, request: "GET /test HTTP/1.1", upstream: 
"http://unix:/run/test.socket:/test/1.html", host: "10.10.90.109"

 

Собственно, это сообщение ("skip linux fd 7") пишется для любых запросов, для которых надо обращаться к unix-сокету.

 

P.S. crossdomain.xml, status.txt, *.ts отдаются.

Share this post


Link to post
Share on other sites

OKyHb

Ну смотрите, это фигня из-за dpdk. Тут есть два варинта:

1. обсудить эту проблему с разработчиками nginx-dpdk

2. workaround - делаете образ VM(kvm), запихиваете туда nginx-dpdk, прокидываете через passthrough туда порты 40GE и делаете один порт virtio, который будет "бриджом" между гипервизором и VM. На гипервизоре запускаете nodejs, только делаете взаимодействие не через unix-сокет, а по IP-сети, которая у вас будет на порту внутри VM и на соответстующем tap-интерфейсе на гипервизоре. Только virtio не очень быстрый, поэтому много трафика через него не гоняйте. Я так понимаю там копейки весят эти m3u8-файлы. Или нет?

Накладные расходы на такую виртуализацию около 0

 

Если решитесь на вариант 2 и что-то не получится, то пишите, помогу

Share this post


Link to post
Share on other sites

echo -e "GET /good/path HTTP/1.0\r\n" | netcat -U /run/test.sock

что возвращает?

 

 

 

package main

import (
"fmt"
"net"
"net/http"
)

func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
	resp := fmt.Sprintf("Path: %s\nHeader: %s\n", r.RequestURI, r.Header)
	fmt.Fprint(w, resp)
	fmt.Print(resp)
})

if l, err := net.Listen("unix", "/run/testing.sock"); err != nil {
	panic(err)
} else {
	if err := http.Serve(l, nil); err != nil {
		panic(err)
	}
}
}

 

 

 

попробуйте это собрать на go 1.6 и скормить нжинксу

Share this post


Link to post
Share on other sites

Тест на Go - та же картина. Ну и, похоже, unix сокеты дейсвительно не поддерживаются. Хоть и не смертельно, но огорчает.

Share this post


Link to post
Share on other sites

OKyHb

Не пробовали как я написал? общаться с nodejs через IP(не локалхост)?

Share this post


Link to post
Share on other sites

Забирать плейлисты по http - можно, работает. Но из-за нашей специфики возникли и другие сложности. Наверно, эти вопросы стоит задавать разработчикам, но мало ли...

 

1. В описании dpdk-ans говорится следующее: "The listen sockets of APP processes are created on each lcore averagely. For example: ans(with -c 0x3) run on two lcore, shall run two nginx(only run master ), one nginx listens on lcore0, another nginx listens on lcore1.".

То есть, если я хочу задействовать 4 CPU, то надо запускать 4 отдельных независимых процесса nginx? (c reuseport и одинаковым конфигом, но разными pid/log файлами). При этом одинаковый proxy_cache_path использовать чревато?

 

2. С "master_process off" nginx не чистит proxy_cache. Файлы складывает, но ничего не удаляет. Чистить его по крону - как-то жёстко. Но других вариантов ж нет?

 

И самое непонятное - почему-то при просмотре через VLC мой тестовый поток заикался. Параллельно запущенный wireshark в такие моменты показывал заметное к-во потерь/ретрансмитов при получении чанка. Вроде ж должен быть буффер в VLC, пофиг на потери - но тем не менее, реально заметно. И вот не знаю, это из-за proxy_pass или где-то в dpdk буферы настраивать?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this