TSDuckin käyttäminen IP(TS)-virtojen valvontaan

Nykyään on olemassa valmiita (omistusoikeudellisia) ratkaisuja esimerkiksi IP(TS) -virtojen valvontaan VB и iQ, niillä on melko runsas toimintosarja ja yleensä suurilla tv-palveluita käsittelevillä operaattoreilla on tällaisia ​​ratkaisuja. Tässä artikkelissa kuvataan avoimen lähdekoodin projektiin perustuva ratkaisu TSDuck, suunniteltu IP(TS)-virtojen minimaaliseen hallintaan CC (jatkuvuuslaskuri) -laskurin ja bittinopeuden avulla. Mahdollinen sovellus on ohjata pakettien katoamista tai koko kulkua vuokratun L2-kanavan kautta (jota ei voida normaalisti valvoa esimerkiksi lukemalla jonoissa olevia häviökaskurit).

Hyvin lyhyesti TSDuckista

TSDuck on avoimen lähdekoodin (2-Clause BSD-lisenssi) ohjelmisto (joukko konsoliapuohjelmia ja kirjasto mukautettujen apuohjelmien tai lisäosien kehittämiseen) TS-virtojen manipulointiin. Syöttönä se voi toimia IP:n (multicast/unicast), http, hls, dvb-virittimien, dektec dvb-asi -demodulaattorin kanssa, on sisäinen TS-stream-generaattori ja tiedostoista lukeminen. Tulos voi olla tiedostoon kirjoittaminen, IP (multicast/unicast), hls, dektec dvb-asi ja HiDes-modulaattorit, soittimet (mplayer, vlc, xine) ja drop. Tulon ja lähdön väliin voidaan sisällyttää erilaisia ​​liikenneprosessoreita, esimerkiksi PID-uudelleenkartoitus, sekoitus / salauksen purkaminen, CC-laskurianalyysi, bittinopeuden laskenta ja muut tyypilliset TS-virtojen toiminnot.

Tässä artikkelissa käytetään IP-virtoja (multicast) tulona, ​​prosessoreja bitrate_monitor (nimestä selviää mikä se on) ja jatkuvuutta (CC-laskurien analyysi). Voit helposti korvata IP-monilähetyksen toisella TSDuckin tukemalla tulotyypillä.

Siellä on viralliset rakenteet/paketit TSDuck useimmille nykyisille käyttöjärjestelmille. Ne eivät ole saatavilla Debianille, mutta onnistuimme rakentamaan ne debian 8:n ja debian 10:n alle ilman ongelmia.

Seuraavaksi käytetään versiota TSDuck 3.19-1520, käyttöjärjestelmänä Linux (debian 10 käytettiin ratkaisun valmisteluun, CentOS 7 käytettiin tosikäyttöön)

TSDuckin ja käyttöjärjestelmän valmistelu

Ennen kuin seuraat todellisia virtauksia, sinun on varmistettava, että TSDuck toimii oikein ja ettei verkkokortin tai käyttöjärjestelmän (socket) tasolla ole pudotuksia. Tämä on tarpeen, jotta et arvaa myöhemmin, missä pudotukset tapahtuivat - verkossa vai "palvelimen sisällä". Voit tarkistaa verkkokorttitason putoamiset komennolla ethtool -S ethX, viritys tehdään samalla ethtoolilla (yleensä sinun on lisättävä RX-puskuria (-G) ja joskus poistettava jotkin purkaukset (-K)). Yleisenä suosituksena on suositeltavaa käyttää erillistä porttia analysoidun liikenteen vastaanottamiseen, jos mahdollista, mikä minimoi vääriä positiivisia, jotka liittyvät siihen, että pudotus tapahtui tarkalleen analysaattoriportissa muun liikenteen vuoksi. Jos tämä ei ole mahdollista (käytetään yhden portin minitietokonetta/NUC:tä), on erittäin toivottavaa asettaa analysoitavan liikenteen priorisointi suhteessa muuhun laitteeseen, johon analysaattori on kytketty. Mitä tulee virtuaaliympäristöihin, sinun on oltava varovainen ja pystyttävä löytämään pakettien putoaminen alkaen fyysisestä portista ja päättyen virtuaalikoneen sisällä olevaan sovellukseen.

Virran luominen ja vastaanotto isännän sisällä

Ensimmäisenä askeleena TSDuckin valmistelussa luomme ja vastaanotamme liikennettä yhdessä isännässä netns:n avulla.

Ympäristön valmistelu:

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

Ympäristö on valmis. Käynnistämme liikenneanalysaattorin:

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

jossa "-p 1 -t 1" tarkoittaa, että sinun on laskettava bittinopeus joka sekunti ja näytettävä tiedot bittinopeudesta joka sekunti
Käynnistämme liikennegeneraattorin nopeudella 10 Mbps:

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

jossa "-p 7 -e" tarkoittaa, että sinun täytyy pakata 7 TS-pakettia yhdeksi IP-paketiksi ja tehdä se kovaa (-e), ts. odota aina 1 TS-pakettia viimeiseltä prosessorilta ennen IP-paketin lähettämistä.

Analysaattori alkaa tulostaa odotettuja viestejä:

* 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

Lisää nyt muutama tippa:

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

ja tällaiset viestit tulevat näkyviin:

* 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 

jota odotetaan. Poista pakettihäviö käytöstä (ip netns exec P iptables -F) ja yritä nostaa generaattorin bittinopeus 100 Mbps:iin. Analysaattori raportoi joukon CC-virheitä ja noin 75 Mbps 100 sijasta. Yritämme selvittää, kuka on syyllinen - generaattorilla ei ole aikaa tai ongelma ei ole siinä, tätä varten alamme generoida kiinteän määrän paketit (700000 100000 TS-pakettia = XNUMX XNUMX IP-pakettia):

# 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

Kuten näet, luotiin täsmälleen 100000 151925460 IP-pakettia (151825460-1). Joten selvitetään, mitä tapahtuu analysaattorin kanssa, tarkistamme tätä varten veth0:n RX-laskurilla, se on tiukasti sama kuin vethXNUMX:n TX-laskuri, sitten katsomme mitä tapahtuu liitäntätasolla:

# 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 

Tästä näet pudotuksen määrän = 24355. TS-paketeissa tämä on 170485 eli 24.36 % 700000:sta, joten näemme, että samat 25 % kadonneesta bittinopeudesta ovat pudotuksia udp-socketissa. UDP-socketin pudotukset johtuvat yleensä puskurin puutteesta, katso oletusvastakkeen puskurin koko ja maksimikantapuskurin koko:

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

Jos sovellukset eivät siis nimenomaisesti pyydä puskurin kokoa, socketit luodaan 208 kt:n puskurilla, mutta jos ne pyytävät enemmän, ne eivät silti saa sitä, mitä pyydettiin. Koska voit asettaa puskurin koon tsp IP-tulolle (-buffer-size), emme koske oletusvastakkeen kokoon, vaan asetamme vain pistorasiapuskurin enimmäiskoon ja määritämme puskurin koon nimenomaisesti tsp-argumenttien avulla:

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

Tällä socket-puskurin virityksellä raportoitu bittinopeus on nyt noin 100 Mbps, CC-virheitä ei ole.

Itse tsp-sovelluksen suorittimen kulutuksen mukaan. Suhteessa yhteen ytimeen i5-4260U CPU @ 1.40 GHz, 10 Mbps virtausanalyysi vaatii 3-4 % CPU, 100 Mbps - 25%, 200 Mbps - 46%. Pakettihäviöprosenttia määritettäessä prosessorin kuormitus ei käytännössä kasva (mutta saattaa pienentyä).

Tuottavammalla laitteistolla oli mahdollista luoda ja analysoida yli 1 Gb / s virtauksia ilman ongelmia.

Testaus oikeilla verkkokorteilla

Veth-parilla testaamisen jälkeen sinun on otettava kaksi isäntä tai kaksi yhden isäntäporttia, kytkettävä portit toisiinsa, käynnistettävä generaattori toisessa ja analysaattori toisessa. Täällä ei ollut yllätyksiä, mutta itse asiassa kaikki riippuu raudasta, mitä heikompi, sitä mielenkiintoisempaa täällä tulee olemaan.

Valvontajärjestelmän (Zabbix) vastaanottamien tietojen käyttäminen

tsp:llä ei ole koneellisesti luettavaa API:ta, kuten SNMP tai vastaava. CC-sanomia tulee koota vähintään 1 sekunti (korkealla pakettihäviöprosentilla voi olla satoja/tuhansia/kymmeniä tuhansia sekunnissa, riippuen bittinopeudesta).

Siten, jotta voidaan tallentaa sekä tietoja että piirtää kaavioita CC-virheille ja bittinopeudelle ja tehdä jonkinlaisia ​​onnettomuuksia, voi olla seuraavat vaihtoehdot:

  1. Jäsennä ja aggregoi (CC:llä) tsp:n tuotos, ts. muuntaa sen haluttuun muotoon.
  2. Viimeistele itse tsp ja/tai prosessorilaajennukset bitrate_monitor ja continuity niin, että tulos annetaan valvontajärjestelmään sopivassa koneellisesti luettavassa muodossa.
  3. Kirjoita hakemuksesi tsduck-kirjaston päälle.

Ilmeisesti vaihtoehto 1 on vaivannäön kannalta helpoin, varsinkin kun otetaan huomioon, että tsduck itse on kirjoitettu matalan tason (nykyaikaisten standardien mukaan) kielellä (C ++).

Yksinkertainen bash-jäsennin+aggregaattori-prototyyppi osoitti, että 10 Mbps:n virran ja 50 %:n pakettihäviöllä (pahimmassa tapauksessa) bash-prosessi kulutti 3-4 kertaa enemmän prosessoria kuin itse tsp-prosessi. Tätä skenaariota ei voida hyväksyä. Itse asiassa osa tästä prototyypistä alla

Päälle nuudelit

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

Sen lisäksi, että se on liian hidas, bashissa ei ole normaaleja säikeitä, bash-työt ovat erillisiä prosesseja ja minun piti kirjoittaa puuttuvan paketin arvo kerran sekunnissa sivuvaikutukseen (kun vastaanotin bittinopeusviestejä, jotka tulevat joka sekunti). Tämän seurauksena bash jätettiin rauhaan ja päätettiin kirjoittaa kääre (parser + aggregator) golangilla. Samanlaisen golang-koodin suorittimen kulutus on 4-5 kertaa pienempi kuin itse tsp-prosessi. Käärien nopeuttaminen bashin korvaamisesta golangilla osoittautui noin 16-kertaiseksi ja yleisesti ottaen tulos on hyväksyttävä (prosessorikulut 25% pahimmassa tapauksessa). Golang-lähdetiedosto sijaitsee täällä.

Suorita kääre

Käärityksen käynnistämiseksi tehtiin systemd:n ​​yksinkertaisin palvelumalli (täällä). Itse kääre on oletettavasti käännetty binääritiedostoksi (go build tsduck-stat.go), joka sijaitsee /opt/tsduck-stat/. Oletetaan, että käytät golangia, joka tukee monotonista kelloa (>=1.9).

Luodaksesi palvelun esiintymän, sinun on suoritettava systemctl enable -komento [sähköposti suojattu]:1234 Suorita sitten systemctl startilla [sähköposti suojattu]: 1234.

Löytö Zabbixilta

Jotta zabbix voisi löytää käynnissä olevat palvelut, se on tehty ryhmäluettelogeneraattori (discovery.sh), Zabbix-etsinnän edellyttämässä muodossa, oletetaan, että se sijaitsee samassa paikassa - hakemistossa /opt/tsduck-stat. Jos haluat suorittaa etsinnän zabbix-agentin kautta, sinun on lisättävä .conf-tiedosto zabbix-agentin määrityshakemistoon lisätäksesi käyttäjäparametrin.

Zabbix malli

Luotu malli (tsduck_stat_template.xml) sisältää automaattisen haun säännön, kohteiden prototyypit, kaaviot ja laukaisimia.

Lyhyt tarkistuslista (entä jos joku päättää käyttää sitä)

  1. Varmista, että tsp ei pudota paketteja "ihanteellisissa" olosuhteissa (generaattori ja analysaattori on kytketty suoraan), jos tippoja on, katso kohta 2 tai artikkelin teksti tästä aiheesta.
  2. Tee virityksestä suurin socket-puskuri (net.core.rmem_max=8388608).
  3. Käännä tsduck-stat.go (siirry rakentamaan tsduck-stat.go).
  4. Laita palvelumalli kansioon /lib/systemd/system.
  5. Käynnistä palvelut systemctl:llä, tarkista, että laskurit ovat alkaneet ilmestyä (grep "" /dev/shm/tsduck-stat/*). Palvelujen määrä monilähetysvirtojen lukumäärän mukaan. Täällä sinun on ehkä luotava reitti monilähetysryhmään, ehkä poistettava rp_filter käytöstä tai luotava reitti lähde-ip:hen.
  6. Suorita discovery.sh ja varmista, että se luo jsonin.
  7. Lisää zabbix agentin konfiguraatio, käynnistä zabbix agent uudelleen.
  8. Lataa malli zabbixiin, asenna se valvottavaan isäntään ja zabbix-agent on asennettu, odota noin 5 minuuttia, katso onko uusia kohteita, kaavioita ja triggereitä.

Tulos

TSDuckin käyttäminen IP(TS)-virtojen valvontaan

Pakettihäviön havaitsemiseen se on melkein tarpeeksi, ainakin parempi kuin ei valvontaa.

Todellakin, CC-häviöitä voi tapahtua yhdistettäessä videofragmentteja (sikäli kuin tiedän, näin tehdään liitteitä Venäjän federaation paikallisissa TV-keskuksissa, eli ilman CC-laskurin uudelleenlaskentaa), tämä on muistettava. Omistusoikeudelliset ratkaisut kiertävät osittain tämän ongelman havaitsemalla SCTE-35-tarrat (jos stream-generaattori lisää ne).

Kuljetuksen laadun seurannassa puuttuu jitter-seuranta (IAT). TV-laitteilla (olipa kyseessä sitten modulaattorit tai päätelaitteet) on tälle parametrille vaatimukset, eikä jitpuskuria aina voida täyttää äärettömään. Ja värinä voi kellua, kun siirrossa käytetään suuria puskureita sisältäviä laitteita ja QoS ei ole konfiguroitu tai se ei ole tarpeeksi hyvin konfiguroitu siirtämään tällaista reaaliaikaista liikennettä.

Lähde: will.com

Lisää kommentti