Користење на TSDuck за следење на тековите на IP(TS).

Денес, постојат готови (комерцијални) решенија за следење на тековите на IP(TS), на пример VB и iQ, тие имаат прилично богат сет на функции и обично големите оператори кои се занимаваат со ТВ услуги имаат слични решенија. Оваа статија опишува решение засновано на проект со отворен код TSDuck, дизајниран за минимална контрола на тековите на IP(TS) со помош на бројачот CC (континуитетен бројач) и брзината на битови. Можна апликација е следење на загубата на пакети или на целиот проток низ изнајмениот канал L2 (кој не може да се следи нормално, на пример, со читање бројачи на загуби во редици).

Многу накратко за TSDuck

TSDuck е софтвер со отворен код (2-клаузула BSD лиценца) (збир на комунални услуги за конзола и библиотека за развивање на ваши сопствени комунални услуги или приклучоци) за манипулирање со тековите на TS. Како влез, може да работи со IP (multicast/unicast), http, hls, dvb тјунери, dektec dvb-asi демодулатор, има внатрешен TS stream генератор и читање од датотеки. Излезот може да биде снимање во датотека, IP (multicast/unicast), hls, dektec dvb-asi и HiDes модулатори, плеери (mplayer, vlc, xine) и пуштање. Помеѓу влезот и излезот, можете да овозможите различни сообраќајни процесори, на пример, повторно мапирање на PID-и, правење мешање/дескрамблирање, анализа на CC бројачи, пресметување на брзината на битови и други операции типични за TS-протоците.

Во оваа статија ќе се користат IP стримови (multicast), ќе се користат процесори за bitrate_monitor (од името е јасно што е ова) и процесори за континуитет (CC контра анализа). Без никакви проблеми, можете да го замените IP multicast со друг тип на влез поддржан од TSDuck.

Има официјални конструкции/пакети TSDuck за повеќето актуелни ОС. За Debian нема, но без проблем успеавме да ги составиме за Debian 8 и Debian 10.

Следно, се користи TSDuck верзија 3.19-1520, Linux се користи како оперативен систем (дебиан 10 се користел за подготовка на решението, CentOS 7 се користел за вистинска употреба)

Подготовка на TSDuck и OS

Пред да ги следите вистинските текови, треба да бидете сигурни дека TSDuck работи правилно и дека падовите не се појавуваат на ниво на мрежната картичка или OS (сокет). Ова е потребно за да не мора подоцна да погодувате каде се случиле падовите - на мрежата или „внатре во серверот“. Можете да ги проверите падовите на ниво на мрежната картичка со командата ethtool -S ethX, подесувањето се врши од истата ethtool (обично треба да го зголемите RX тампонот (-G) и понекогаш да оневозможите некои исфрлања (-K)). Како општа препорака, препорачливо е да се користи посебна порта за да се прими анализираниот сообраќај, ако е можно, ова ќе ги минимизира лажните позитиви поради фактот што падот се случил истовремено на портата на анализаторот поради присуството на друг сообраќај. Ако тоа не е можно (користете мини-компјутер/NUC со една порта), тогаш многу е препорачливо да го конфигурирате приоритетот на анализираниот сообраќај во однос на остатокот на уредот на кој е поврзан анализаторот. Што се однесува до виртуелните средини, тука треба да бидете внимателни и да можете да најдете падови на пакети почнувајќи од физичката порта и завршувајќи со апликацијата во виртуелната машина.

Генерирање и примање пренос во домаќинот

Како прв чекор во подготовката на TSDuck, ќе генерираме и примаме сообраќај во еден домаќин користејќи мрежи.

Подготовка на околината:

ip netns add P #создаём netns P, в нём будет происходить анализ трафика
ip link add type veth #создаём veth-пару - veth0 оставляем в netns по умолчанию (в этот интерфейс будет генерироваться трафик)
ip link set dev veth1 netns P #veth1 - помещаем в netns P (на этом интерфейсе будет приём трафика)
ip netns exec P ifconfig veth1 192.0.2.1/30 up #поднимаем IP на veth1, не имеет значения какой именно
ip netns exec P ip ro add default via 192.0.2.2 #настраиваем маршрут по умолчанию внутри nents P
sysctl net.ipv6.conf.veth0.disable_ipv6=1 #отключаем IPv6 на veth0 - это делается для того, чтобы в счётчик TX не попадал посторонний мусор
ifconfig veth0 up #поднимаем интерфейс veth0
ip route add 239.0.0.1 dev veth0 #создаём маршрут, чтобы ОС направляла трафик к 239.0.0.1 в сторону veth0

Околината е подготвена. Стартувајте го анализаторот на сообраќајот:

ip netns exec P tsp --realtime -t 
 -I ip 239.0.0.1:1234 
 -P continuity 
 -P bitrate_monitor -p 1 -t 1 
 -O drop

каде што „-p 1 -t 1“ значи дека треба да ја пресметате брзината на битови секоја секунда и да прикажувате информации за брзината на битови секоја секунда
Стартуваме генератор на сообраќај со брзина од 10 Mbit/s:

tsp -I craft 
 -P regulate -b 10000000 
 -O ip -p 7 -e --local-port 6000 239.0.0.1:1234

каде што „-p 7 -e“ значи дека треба да спакувате 7 TS пакети во 1 IP пакет и да го направите тоа тешко (-e), т.е. секогаш чекајте 7 TS пакети од последниот процесор пред да испратите формирање на IP пакет.

Анализаторот започнува да ги прикажува очекуваните пораки:

* 2020/01/03 14:55:44 - bitrate_monitor: 2020/01/03 14:55:44, TS bitrate: 9,970,016 bits/s
* 2020/01/03 14:55:45 - bitrate_monitor: 2020/01/03 14:55:45, TS bitrate: 10,022,656 bits/s
* 2020/01/03 14:55:46 - bitrate_monitor: 2020/01/03 14:55:46, TS bitrate: 9,980,544 bits/s

Сега да додадеме неколку капки:

ip netns exec P iptables -I INPUT -d 239.0.0.1 -m statistic --mode random --probability 0.001 -j DROP

и се појавуваат пораки како оваа:

* 2020/01/03 14:57:11 - continuity: packet index: 80,745, PID: 0x0000, missing 7 packets
* 2020/01/03 14:57:11 - continuity: packet index: 83,342, PID: 0x0000, missing 7 packets 

што се очекува. Ја оневозможуваме загубата на пакети (ip netns exec P iptables -F) и се обидуваме да ја зголемиме бит-стапката на генераторот на 100 Mbit/s. Анализаторот известува еден куп CC грешки и околу 75 Mbit/s наместо 100. Се обидуваме да откриеме кој е виновен - генераторот не држи чекор или проблемот не е во него, за да го направиме ова, почнуваме да генерираме фиксен број на пакети (700000 TS пакети = 100000 IP пакети):

# ifconfig veth0 | grep TX
       TX packets 151825460  bytes 205725459268 (191.5 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
# tsp -I craft -c 700000 -P regulate -b 100000000 -P count -O ip -p 7 -e --local-port 6000 239.0.0.1:1234
* count: PID    0 (0x0000):    700,000 packets
# ifconfig veth0 | grep TX
        TX packets 151925460  bytes 205861259268 (191.7 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Како што можете да видите, беа генерирани точно 100000 IP пакети (151925460-151825460). Значи, откриваме што се случува со анализаторот, за да го направиме ова, проверуваме со бројачот RX на veth1, тој е строго еднаков на бројачот TX на veth0, а потоа гледаме што се случува на ниво на штекер:

# ip netns exec P cat /proc/net/udp                                                                                                           
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode ref pointer drops             
  133: 010000EF:04D2 00000000:0000 07 00000000:00000000 00:00000000 00000000     0        0 72338 2 00000000e0a441df 24355 

Овде можете да го видите бројот на падови = 24355. Во TS пакетите ова е 170485 или 24.36% од 700000, така што гледаме дека истите 25% од изгубената брзина на битови се капки во приклучокот UDP. Падовите на UDP приклучокот обично се случуваат поради недостаток на бафер, ајде да видиме која е стандардната големина на баферот на штекерот и максималната големина на баферот на приклучокот:

# sysctl net.core.rmem_default
net.core.rmem_default = 212992
# sysctl net.core.rmem_max
net.core.rmem_max = 212992

Така, ако апликациите експлицитно не ја бараат големината на баферот, сокетите се создаваат со бафер од 208 KB, но ако бараат повеќе, тие сè уште нема да го добијат она што го побарале. Бидејќи во tsp можете да ја поставите големината на баферот за влез на IP (--buffer-size), ние нема да ја допреме стандардната големина на сокетот, туку само ќе ја поставиме максималната големина на баферот и ќе ја одредиме големината на баферот експлицитно преку аргументите tsp:

sysctl net.core.rmem_max=8388608
ip netns exec P tsp --realtime -t -I ip 239.0.0.1:1234 -b 8388608 -P continuity -P bitrate_monitor -p 1 -t 1 -O drop

Со ова подесување на баферот на приклучокот, пријавената брзина на битови сега е приближно 100 Mbps, нема CC грешки.

Врз основа на потрошувачката на процесорот од самата апликација tsp. Што се однесува до еден јадрен процесор i5-4260U @ 1.40 GHz, за да се анализира протокот од 10 Mbit/s, ќе бидат потребни 3-4% од процесорот, 100Mbit/s - 25%, 200Mbit/s - 46%. Кога се поставува % загуба на пакети, оптоварувањето на процесорот практично не се зголемува (но може да се намали).

На попродуктивен хардвер, беше можно да се генерираат и анализираат текови со брзина поголема од 1 Gb/s без никакви проблеми.

Тестирање на вистински мрежни картички

По тестирањето на парот veth, треба да земете два домаќини или две порти на еден домаќин, да ги поврзете портите едни со други, да го вклучите генераторот на еден, а анализаторот на вториот. Овде немаше изненадувања, но всушност се зависи од хардверот, колку е послаб, толку ќе биде поинтересно овде.

Користење на добиените податоци од системот за следење (Zabbix)

tsp нема машински читлив API како SNMP или слично. CC пораките треба да се соберат најмалку 1 секунда во исто време (со висок процент на загуба на пакети, може да има стотици/илјадници/десетици илјади во секунда, во зависност од бит-стапката).

Така, со цел да се зачуваат информации и да се исцртаат графикони за CC грешки и бит-стапки и да се направат некакви несреќи понатаму, може да има следниве опции:

  1. Анализирајте го и агрегирајте (по CC) излезот од tsp, т.е. преобразете го во посакуваната форма.
  2. Додадете ја самата лажичка и/или приклучоците за процесорот bitrate_monitor и континуитет, така што резултатот ќе биде излезен во машински читлива форма соодветна за системот за следење.
  3. Напишете ја вашата апликација на врвот на библиотеката tsduck.

Очигледно, во однос на трошоците за работна сила, опцијата 1 е наједноставна, особено ако се земе предвид дека самиот tsduck е напишан на ниско ниво (според современите стандарди) јазик (C++)

Едноставен прототип на парсер + агрегатор во bash покажа дека при проток од 10 Mbit/s и 50% загуба на пакети (најлош случај), баш процесот троши 3-4 пати повеќе CPU од самиот процес на tsp. Ова сценарио е неприфатливо. Всушност, дел од овој прототип е подолу

Тестенини на баша

#!/usr/bin/env bash

missingPackets=0
ccErrorSeconds=0
regexMissPackets='^* (.+) - continuity:.*missing ([0-9]+) packets$'
missingPacketsTime=""

ip netns exec P tsp --realtime -t -I ip -b 8388608 "239.0.0.1:1234" -O drop -P bitrate_monitor -p 1 -t 1  -P continuity 2>&1 | 
while read i
do
    #line example:* 2019/12/28 23:41:14 - continuity: packet index: 6,078, PID: 0x0100, missing 5 packets
    #line example 2: * 2019/12/28 23:55:11 - bitrate_monitor: 2019/12/28 23:55:11, TS bitrate: 4,272,864 bits/s
    if [[ "$i" == *continuity:* ]] 
    then
        if [[ "$i" =~ $regexMissPackets ]]
        then
            missingPacketsTimeNew="${BASH_REMATCH[1]}" #timestamp (seconds)
            if [[ "$missingPacketsTime" != "$missingPacketsTimeNew" ]] #new second with CC error
            then
                ((ccErrorSeconds += 1))
            fi
            missingPacketsTime=$missingPacketsTimeNew
            packets=${BASH_REMATCH[2]} #TS missing packets
            ((missingPackets += packets))
        fi
    elif [[ "$i" == *bitrate_monitor:* ]]
    then
        : #...
    fi
done

Покрај тоа што ова работи неприфатливо бавно, нема нормални нишки во bash, баш работните задачи се независни процеси и морав да ја напишам вредноста на missingPackets еднаш во секунда на несаканиот ефект (при примање пораки со брзина на битови што доаѓаат секоја секунда). Како резултат на тоа, баш остана сам и беше одлучено да се напише обвивка (парсер + агрегатор) во голанг. Потрошувачката на процесорот на сличен код во голанг е 4-5 пати помала од самиот процес на лажиче. Забрзувањето на обвивката со замена на баш со голанг беше приближно 16 пати и севкупниот резултат е прифатлив (надмор на процесорот за 25% во најлош случај). Се наоѓа изворната датотека голанг тука.

Стартување на обвивката

За стартување на обвивката, направен е едноставен образец за услуга за systemd (тука). Се претпоставува дека самиот обвивка е компајлиран во бинарна датотека (go build tsduck-stat.go), сместена во /opt/tsduck-stat/. Се претпоставува дека голангот се користи со монотона поддршка на часовникот (>=1.9).

За да креирате сервисен пример, треба да ја извршите командата systemctl enable [заштитена по е-пошта]:1234, а потоа стартувајте со systemctl start [заштитена по е-пошта]: 1234.

Откритие од Zabbix

За да може zabbix да открие што работи на услуги, генератор на групна листа (discovery.sh), во форматот потребен за откривање на Zabbix, се претпоставува дека се наоѓа на истото место - во /opt/tsduck-stat. За да го извршите откривањето преку zabbix-agent, треба да додадете .conf датотека во директориумот со конфигурации на zabbix-agent за да додадете кориснички параметар.

Шаблон Zabbix

Создаден шаблон (tsduck_stat_template.xml) содржи правило за автоматско откривање, елемент, график и прототипови за активирање.

Кратка листа за проверка (што ако некој одлучи да ја користи)

  1. Осигурајте се дека tsp не испушта пакети во „идеални“ услови (генераторот и анализаторот се директно поврзани), ако има падови, видете точка 2 или текстот на статијата за ова прашање.
  2. Направете подесување на максималниот бафер на приклучокот (net.core.rmem_max=8388608).
  3. Компајлирај tsduck-stat.go (оди изгради tsduck-stat.go).
  4. Ставете го шаблонот за услугата во /lib/systemd/system.
  5. Започнете ги услугите користејќи systemctl, проверете дали бројачите почнале да се појавуваат (grep "" /dev/shm/tsduck-stat/*). Број на услуги по број на повеќекратни преноси. Овде можеби ќе треба да креирате маршрута до мултикаст групата, можеби оневозможете rp_filter или креирајте рута до изворната IP адреса.
  6. Стартувај го discovery.sh, проверете дали генерира json.
  7. Поставете ја конфигурацијата на агентот zabbix, рестартирајте го агентот zabbix.
  8. Поставете го шаблонот на zabbix, применете го на домаќинот на кој се врши мониторинг и е инсталиран zabbix-agent, почекајте околу 5 минути, видете дека се појавиле нови податочни елементи, графикони и предизвикувачи.

Резултира

Користење на TSDuck за следење на тековите на IP(TS).

За задачата да се идентификува загубата на пакети, тоа е речиси доволно, барем е подобро отколку без следење.

Всушност, „загубите“ на CC може да се појават при спојување на видео фрагменти (колку што знам, вака се прават инсерти во локалните телевизиски центри во Руската Федерација, т.е. без повторно пресметување на бројачот на CC), ова мора да се запомни. Во сопствените решенија, овој проблем делумно се заобиколува со откривање на ознаки SCTE-35 (ако се додадени од генераторот на поток).

Од гледна точка на следење на квалитетот на транспортот, мониторингот со нервоза (IAT) не е доволен, бидејќи Телевизиската опрема (без разлика дали се модулатори или крајни уреди) има барања за овој параметар и не е секогаш возможно да се надува jitbuffer на неодредено време. И треперењето може да лебди кога транзитот користи опрема со големи бафери и QoS не е конфигуриран или не е доволно добро конфигуриран за да пренесува таков сообраќај во реално време.

Извор: www.habr.com

Додадете коментар