Gebruik TSDuck om IP(TS)-strome te monitor

Vandag is daar klaargemaakte (eiendoms) oplossings vir die monitering van IP(TS)-strome, byvoorbeeld VB и iQ, hulle het 'n redelike ryk stel funksies en gewoonlik het groot operateurs wat met TV-dienste te doen het, sulke oplossings. Hierdie artikel beskryf 'n oplossing gebaseer op 'n oopbronprojek TSDuck, ontwerp vir minimale beheer van IP (TS) strome deur CC (kontinuïteit teller) teller en bitrate. 'n Moontlike toepassing is om die verlies van pakkies of die hele vloei deur 'n gehuurde L2-kanaal te beheer (wat nie normaalweg gemonitor kan word nie, byvoorbeeld deur verliestellers in rye te lees).

Baie kortliks oor TSDuck

TSDuck is 'n oopbron (2-klousule BSD-lisensie) sagteware ('n stel konsolehulpmiddels en 'n biblioteek vir die ontwikkeling van pasgemaakte hulpmiddels of inproppe) om TS-strome te manipuleer. As 'n inset, kan dit werk met IP (multicast/unicast), http, hls, dvb tuners, dektec dvb-asi demodulator, daar is 'n interne TS stroom generator en lees van lêers. Die uitvoer kan skryf na 'n lêer, IP (multicast/unicast), hls, dektec dvb-asi en HiDes modulators, spelers (mplayer, vlc, xine) en drop. U kan verskeie verkeersverwerkers tussen invoer en uitvoer aktiveer, byvoorbeeld PID-herkartering, deurmekaar- / descrambling, CC-telleranalise, bitrate-berekening en ander tipiese bewerkings vir TS-strome.

In hierdie artikel sal IP-strome (multicast) as 'n inset gebruik word, die verwerkers bitrate_monitor (van die naam is dit duidelik wat dit is) en kontinuïteit (analise van CC tellers) word gebruik. Jy kan maklik IP multicast vervang met 'n ander invoertipe wat deur TSDuck ondersteun word.

Beskikbaar amptelike bouwerk/pakkette TSDuck vir die meeste huidige bedryfstelsels. Hulle is nie beskikbaar vir Debian nie, maar ons het daarin geslaag om hulle sonder enige probleme onder debian 8 en debian 10 te bou.

Vervolgens word weergawe TSDuck 3.19-1520 gebruik, Linux word as die bedryfstelsel gebruik (debian 10 is gebruik om die oplossing voor te berei, CentOS 7 is vir werklike gebruik gebruik)

Berei TSDuck en OS voor

Voordat u werklike vloeie monitor, moet u seker maak dat TSDuck korrek werk en dat daar geen druppels op die netwerkkaart of OS (sok) vlak is nie. Dit is nodig om nie later te raai waar die druppels plaasgevind het nie - op die netwerk of "binne die bediener". Jy kan druppels op die netwerkkaartvlak nagaan met die ethtool -S ethX-opdrag, tuning word deur dieselfde ethtool gedoen (gewoonlik moet jy die RX-buffer (-G) verhoog en soms sommige aflaaie (-K) deaktiveer). As 'n algemene aanbeveling, kan dit aangeraai word om 'n aparte poort te gebruik vir die ontvangs van die ontleed verkeer, indien moontlik, dit verminder vals positiewe wat verband hou met die feit dat die daling presies op die ontlederpoort plaasgevind het as gevolg van die teenwoordigheid van ander verkeer. As dit nie moontlik is nie ('n mini-rekenaar/NUC met een poort word gebruik), dan is dit hoogs wenslik om die prioritisering van die geanaliseerde verkeer op te stel in verhouding tot die res op die toestel waaraan die ontleder gekoppel is. Met betrekking tot virtuele omgewings, hier moet jy versigtig wees en in staat wees om pakkie druppels te vind wat begin vanaf 'n fisiese poort en eindig met 'n toepassing binne 'n virtuele masjien.

Generering en ontvangs van 'n stroom binne die gasheer

As 'n eerste stap in die voorbereiding van TSDuck, sal ons verkeer genereer en ontvang binne 'n enkele gasheer met behulp van netns.

Voorbereiding van die omgewing:

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

Die omgewing is gereed. Ons begin die verkeersontleder:

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

waar "-p 1 -t 1" beteken dat jy die bitrate elke sekonde moet bereken en inligting oor die bitrate elke sekonde moet vertoon
Ons begin die verkeersgenerator met 'n spoed van 10Mbps:

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

waar "-p 7 -e" beteken dat jy 7 TS-pakkies in 1 IP-pakkie moet pak en dit moeilik moet doen (-e), m.a.w. wag altyd 7 TS-pakkies van die laaste verwerker af voordat 'n IP-pakkie gestuur word.

Die ontleder begin die verwagte boodskappe uitstuur:

* 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

Voeg nou 'n paar druppels by:

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

en boodskappe soos hierdie verskyn:

* 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 

wat verwag word. Deaktiveer pakkieverlies (ip netns exec P iptables -F) en probeer om die kragopwekker se bitsnelheid na 100Mbps te verhoog. Die ontleder rapporteer 'n klomp CC-foute en ongeveer 75 Mbps in plaas van 100. Ons probeer uitvind wie die skuld kry - die kragopwekker het nie tyd nie of die probleem is nie daarin nie, hiervoor begin ons 'n vaste aantal pakkies (700000 100000 TS-pakkies = XNUMX XNUMX IP-pakkies):

# 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

Soos u kan sien, is presies 100000 151925460 IP-pakkies gegenereer (151825460-1). Laat ons dus uitvind wat met die ontleder gebeur, hiervoor kyk ons ​​met die RX-teller op veth0, dit is streng gelyk aan die TX-teller op vethXNUMX, dan kyk ons ​​na wat op die sokvlak gebeur:

# 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 

Hier kan jy die aantal druppels sien = 24355. In TS-pakkies is dit 170485 of 24.36% van 700000, so ons sien dat dieselfde 25% van die verlore bitsnelheid druppels in die udp-sok is. Dalings in 'n UDP-sok kom gewoonlik voor as gevolg van 'n gebrek aan buffer, kyk na die verstek-sokbuffergrootte en die maksimum sokbuffergrootte:

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

Dus, as toepassings nie uitdruklik 'n buffergrootte versoek nie, word voetstukke geskep met 'n buffer van 208 KB, maar as hulle meer versoek, sal hulle steeds nie ontvang wat versoek is nie. Aangesien u die buffergrootte in tsp vir die IP-invoer (-buffer-grootte) kan stel, sal ons nie die verstek-sokgrootte raak nie, maar slegs die maksimum sok-buffergrootte stel en die buffergrootte eksplisiet spesifiseer deur die tsp-argumente:

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

Met hierdie verstelling van die sokbuffer, nou is die gerapporteerde bitsnelheid ongeveer 100 Mbps, is daar geen CC-foute nie.

Volgens die SVE-verbruik van die tsp-toepassing self. Relatief tot een kern i5-4260U SVE @ 1.40GHz, sal 10 Mbps vloeianalise 3-4% SVE, 100 Mbps - 25%, 200 Mbps - 46% vereis. Wanneer die % Pakketverlies ingestel word, neem die las op die SVE feitlik nie toe nie (maar kan afneem).

Op meer produktiewe hardeware was dit moontlik om strome van meer as 1Gb/s sonder enige probleme te genereer en te ontleed.

Toets op regte netwerkkaarte

Nadat jy op 'n veth-paar getoets het, moet jy twee gashere of twee poorte van een gasheer neem, die poorte aan mekaar koppel, die kragopwekker op een begin en die ontleder op die tweede. Hier was geen verrassings nie, maar eintlik hang dit alles af van die yster, hoe swakker, hoe interessanter sal dit hier wees.

Gebruik die ontvangde data deur die moniteringstelsel (Zabbix)

tsp het geen masjienleesbare API soos SNMP of soortgelyke nie. CC-boodskappe moet vir ten minste 1 sekonde saamgevoeg word (met 'n hoë persentasie pakkieverlies kan daar honderde/duisende/tienduisende per sekonde wees, afhangend van die bitsnelheid).

Dus, om beide inligting te stoor en grafieke vir CC-foute en bitrate te teken en 'n soort ongelukke te maak, kan daar die volgende opsies wees:

  1. Ontleed en aggreer (deur CC) die uitset van tsp, d.w.s. omskep dit na die verlangde vorm.
  2. Voltooi tsp self en/of verwerker-inproppe bitrate_monitor en kontinuïteit sodat die resultaat gegee word in 'n masjienleesbare vorm wat geskik is vir die moniteringstelsel.
  3. Skryf jou aansoek bo-op die tsduck-biblioteek.

Uiteraard is opsie 1 die maklikste in terme van moeite, veral as in ag geneem word dat tsduck self in 'n laevlak (volgens moderne standaarde) taal (C ++) geskryf is.

'n Eenvoudige bash-parser+aggregator-prototipe het getoon dat op 'n 10Mbps-stroom en 50% pakkieverlies (ergste geval), die bash-proses 3-4 keer meer SVE verbruik as die tsp-proses self. Hierdie scenario is onaanvaarbaar. Eintlik 'n stukkie van hierdie prototipe hieronder

Noedels bo-op

#!/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

Benewens die feit dat dit onaanvaarbaar stadig is, is daar geen normale drade in bash nie, bash-take is afsonderlike prosesse en ek moes die waarde van missingPackets een keer per sekonde op die newe-effek skryf (wanneer ek bitrate-boodskappe ontvang wat elke sekonde kom). Gevolglik is bash alleen gelaat en daar is besluit om 'n omhulsel (parser + aggregator) in golang te skryf. Die SVE-verbruik van soortgelyke golang-kode is 4-5 keer minder as die tsp-proses self. Die versnelling van die omhulsel as gevolg van die vervanging van bash met golang blyk ongeveer 16 keer te wees en oor die algemeen is die resultaat aanvaarbaar (CPU-bokoste met 25% in die ergste geval). Die golang-bronlêer is geleë hier.

Loop omhulsel

Om die omhulsel te begin, is die eenvoudigste dienssjabloon vir systemd gemaak (hier). Die omhulsel self is veronderstel om saamgestel te word in 'n binêre lêer (gaan bou tsduck-stat.go) geleë in /opt/tsduck-stat/. Daar word aanvaar dat jy golang gebruik met ondersteuning vir monotoniese klok (>=1.9).

Om 'n instansie van die diens te skep, moet jy die systemctl enable-opdrag uitvoer [e-pos beskerm]:1234 hardloop dan met systemctl start [e-pos beskerm]: 1234.

Ontdekking van Zabbix

Om vir zabbix in staat te wees om lopende dienste te ontdek, word dit gedoen groep lys generator (discovery.sh), in die formaat wat benodig word vir Zabbix-ontdekking, word aanvaar dat dit op dieselfde plek geleë is - in /opt/tsduck-stat. Om ontdekking via zabbix-agent uit te voer, moet jy byvoeg .conf lêer na die zabbix-agent-konfigurasiegids om die gebruikerparameter by te voeg.

Zabbix sjabloon

Sjabloon geskep (tsduck_stat_template.xml) bevat die outo-ontdekkingsreël, itemprototipes, grafieke en snellers.

Kort kontrolelys (wel, wat as iemand besluit om dit te gebruik)

  1. Maak seker dat tsp nie pakkies onder "ideale" toestande laat val nie (generator en ontleder is direk gekoppel), as daar druppels is, sien paragraaf 2 of die teks van die artikel oor hierdie saak.
  2. Verstel die maksimum sokbuffer (net.core.rmem_max=8388608).
  3. Stel tsduck-stat.go saam (gaan bou tsduck-stat.go).
  4. Plaas die dienssjabloon in /lib/systemd/system.
  5. Begin dienste met systemctl, maak seker dat tellers begin verskyn het (grep "" /dev/shm/tsduck-stat/*). Die aantal dienste volgens die aantal multicast-strome. Hier moet jy dalk 'n roete na die multicast-groep skep, dalk rp_filter deaktiveer of 'n roete na die bron-ip skep.
  6. Begin discovery.sh, maak seker dat dit json genereer.
  7. Voeg zabbix agent config by, herbegin zabbix agent.
  8. Laai die sjabloon op na zabbix, pas dit toe op die gasheer wat gemonitor word en die zabbix-agent is geïnstalleer, wag ongeveer 5 minute, kyk of daar nuwe items, grafieke en snellers is.

Gevolg

Gebruik TSDuck om IP(TS)-strome te monitor

Vir die taak om pakkieverlies op te spoor, is dit amper genoeg, ten minste is dit beter as geen monitering.

Inderdaad, CC "verliese" kan voorkom wanneer videofragmente saamgevoeg word (sover ek weet, is dit hoe invoegings by plaaslike TV-sentrums in die Russiese Federasie gemaak word, dit wil sê sonder om die CC-teller te herbereken), dit moet onthou word. Eiendomsoplossings omseil hierdie probleem gedeeltelik deur SCTE-35-etikette op te spoor (indien bygevoeg deur die stroomopwekker).

Wat vervoergehaltemonitering betref, is daar 'n gebrek aan jittermonitering (IAT). TV-toerusting (of dit nou modulators of eindtoestelle is) het vereistes vir hierdie parameter en dit is nie altyd moontlik om die jitbuffer tot oneindig op te blaas nie. En jitter kan dryf wanneer toerusting met groot buffers in vervoer gebruik word en QoS nie gekonfigureer of nie goed gekonfigureer genoeg is om sulke intydse verkeer oor te dra nie.

Bron: will.com

Voeg 'n opmerking