Praegu on olemas valmis (patenditud) lahendused IP(TS)-voogude jälgimiseks, näiteks ja , need pakuvad üsna laia funktsioonide valikut ja sellised lahendused on tavaliselt suurte operaatorite käsutuses, kes tegelevad TV-teenustega. Selles artiklis käsitletakse avatud lähtekoodiga projektil põhinevat lahendust , mis on mõeldud IP(TS)-voogude minimaalseteks jälgimiseks CC (continuity counter) ja bitikiiruselt. Üks võimalik rakendusala on pakettide või voogude kadumise kontrollimine renditud L2-kanali kaudu (mida ei saa normaalselt jälgida, näiteks kaotuse arvestite lugemise kaudu järjekordades).
TSDuckist lühidalt
TSDuck on avatud lähtekoodiga (2-Clause BSD litsents) tarkvara (konsol utiliitide komplekt ja raamatukogu oma utiliitide või pluginite arendamiseks) TS-voogude manipuleerimiseks. Sisendina suudab see töötada IP (multicast/unicast), http, hls, dvb-tuunerite, dektec dvb-asi demodulaatoriga, sisaldab sisseehitatud TS-voo generaatorit ja faili lugemist. Väljundina saab see salvestada faili, IP (multicast/unicast), hls, dektec dvb-asi ja HiDes modulaatoritesse, mängijatesse (mplayer, vlc, xine) ja drop. Sisse- ja väljundide vahel saab kasutada erinevaid liiklustöötlejaid, näiteks PID-de ümberkaardistamine, krüptimine/dekrüptimine, CC-loendurite analüüs, bitikiirusetabeli arvutamine ja teised tüüpilised TS-voogude toimingud.
Selles artiklis kasutatakse sisendina IP-vooge (multicast), kasutades bitrate_monitor (nimest on selge, mis see on) ja continuity (CC-loendurite analüüs) töötlejat. Probleemideta saab IP multicast vahetada mõne muu TSDucki toetatud sisendiviisi vastu.
On olemas TSDuck enamikule kaasaegsetele opsüsteemidele. Debianile neid ei ole, kuid Debian 8 ja Debian 10 jaoks õnnestus need probleemideta kokku panna.
Kasutatakse TSDuck versiooni 3.19-1520, opsüsteemina on Linux (lahenduse ettevalmistamiseks kasutati debian 10, tõeliseks kasutamiseks — CentOS 7)
TSDucki ja opsüsteemi ettevalmistamine
Enne kui hakkate jälgima reaalseid vooge, veenduge, et TSDuck töötab korralikult ning et võrgukaardi või operatsioonisüsteemi (soketi) tasemel ei esine katkestusi. See on vajalik, et hiljem ei peaks arutama, kus katkestused toimusid — kas võrgus või "serveri sees". Katkestusi võrgu tasemel saab kontrollida käsuga ethtool -S ethX, häälestust teostatakse sama ethtooliga (tavaliselt tuleb suurendada RX-puhvrit (-G) ja mõnikord keelata mõned offload'id (-K)). Ühe üldise soovitusena võiks soovitada kasutada analüüsitava liikluse vastuvõtmiseks eraldi porti, kui see on võimalik, see minimeerib valehäireid, mis võivad tekkida, kui katkestus toimub analüsaatori pordis teiste liikluse tõttu. Kui sellist võimalust ei ole (kasutatakse miniarvutit/NUC-d ühe pordiga), siis on väga soovitatav seadistada analüüsitava liikluse prioriteet muudele seadmel, kuhu analüsaator on ühendatud. Virtuaalsete keskkondade osas tuleb olla ettevaatlik ja osata leida katkestusi, alustades füüsilisest pordist ja lõpetades rakendusega virtuaalmajas.
Voogude genereerimine ja vastuvõtt hosti sees
Esimese sammuna TSDuck'i ettevalmistamisel genereerime ja võtame vastu liiklust ühe hosti sees, kasutades netns.
Valmistame keskkonna ette:
ip netns add P #loome netns P, kus toimub liikluse analüüs
ip link add type veth #loome veth-paar - veth0 jääb vaikimisi netns-i (sellele liidesele genereeritakse liiklus)
ip link set dev veth1 netns P #veth1 - paigutame netns P-sse (sellel liidesele toimub liikluse vastuvõtt)
ip netns exec P ifconfig veth1 192.0.2.1/30 up #tõstame IP veth1-le, pole oluline, mis see on
ip netns exec P ip ro add default via 192.0.2.2 #seame vaikimisi marsruudi netns P sees
sysctl net.ipv6.conf.veth0.disable_ipv6=1 #lülitame IPv6 välja veth0-l - see tehakse, et TX loendisse ei satuks kõrvaline müra
ifconfig veth0 up #tõstame liidese veth0
ip route add 239.0.0.1 dev veth0 #loome marsruudi, et OS suunaks liikluse 239.0.0.1 suunas veth0-leKeskkond on valmis. Käivitame liikluse analüsaatori:
ip netns exec P tsp --realtime -t
-I ip 239.0.0.1:1234
-P continuity
-P bitrate_monitor -p 1 -t 1
-O dropkus „-p 1 -t 1” tähendab, et bitikiirus arvutatakse iga sekundi tagant ja bitikiirusest teave kuvatakse iga sekundi tagant
Käivitame liikluse generaatori kiirusel 10 Mbit/s:
tsp -I craft
-P regulate -b 10000000
-O ip -p 7 -e --local-port 6000 239.0.0.1:1234kus «-p 7 -e» tähendab, et tuleb pakkida 7 TS-paketti 1 IP-paketiks ja teha seda range seadistusega (-e), st alati oodata viimase protsessori käest 7 TS-paketti enne IP-paketi saatmist.
Analüsaator hakkab kuvama oodatud teateid:
* 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/sNüüd lisame veidi katkestusi:
ip netns exec P iptables -I INPUT -d 239.0.0.1 -m statistic --mode random --probability 0.001 -j DROPja ilmnevad sellised teated:
* 2020/01/03 14:57:11 - continuity: paket indeks: 80,745, PID: 0x0000, 7 paketti puuduvad
* 2020/01/03 14:57:11 - continuity: paket indeks: 83,342, PID: 0x0000, 7 paketti puuduvad mis on oodatud. Lülitame katkestuste kaotamise välja (ip netns exec P iptables -F) ja proovime suurendada generaatori bitrate'i 100 Mbit/s. Analüsaator teatab hulgaliselt CC- vigu ja umbes 75 Mbit/s asemel 100. Proovime välja selgitada, kas süüdi on generaator või on probleem mujal, selleks käivitame fikseeritud arvu paketid (700000 TS-paketti = 100000 IP-paketti):
# 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 0Nagu näha, on genereeritud täpselt 100000 IP-paketti (151925460-151825460). Seega uurime, mis toimub analüsaatoriga, selleks võrreldes RX loenduri väärtusega veth1-l, mis on täpselt võrdne TX loenduri väärtusega veth0-l, ja seejärel vaatame, mis toimub soketitasemel:
# 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 Siin on nähtav kadude arv = 24355. TS-pakettides on see 170485 ehk 24,36% 700000-st, seega näeme, et need 25% kadunud bittide voogus on kadud UDP-soketis. Kadud UDP-soketis tekivad tavaliselt mälu puuduse tõttu, vaatame, kui suur on vaikimisi soketi puhver ja maksimaalne soketi puhver:
# sysctl net.core.rmem_default
net.core.rmem_default = 212992
# sysctl net.core.rmem_max
net.core.rmem_max = 212992Seega, kui rakendused ei küsi puhvri suurust selgelt, luuakse soketid puhvri suurusega 208 Kb, kuid kui küsitakse rohkem, siis ei saada ikkagi soovitud suurust. Kuna tsp jaoks IP-sisendi puhul on võimalik määrata puhvri suurus (—buffer-size), siis ei puuduta vaikimisi soketi suurust, vaid määrame vaid maksimaalse soketi puhvri suuruse ja määrame puhvri suuruse selgelt tsp argumentide kaudu:
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 dropSellise soketi puhvri häälestamisega on nüüd raporteeritud bittide voog umbes 100 Mbit/s, CC-vigu ei esine.
TSP rakenduse poolt CPU kasutamine. Ühe i5-4260U CPU @ 1,40 GHz tuuma puhul 10 Mbit/s voogude analüüsimiseks kulub 3-4% CPU, 100 Mbit/s — 25%, 200 Mbit/s — 46%. Pakettide kaotusprotsendi määramisel CPU koormus praktiliselt ei suurene (aga võib väheneda).
Tõhusamal riistvaral on probleemideta suudetud genereerida ja analüüsida vooge üle 1 Gbit/s.
Testimine reaalsel võrgukaardil
Pärast testimist veth-paaril tuleb võtta kaks hosti või ühe hosti kaks porti, ühendada portidega omavahel, ühel käivitada generaator, teisel analüsaator. Siin ei juhtunud üllatusi, kuid tegelikult sõltub see kõik riistvarast — mida nõrgem, seda huvitavam see siin on.
Saadud andmete kasutamine monitooringusüsteemis (Zabbix)
TSP-l ei ole mingit masinloetavat API-d nagu SNMP või sarnast. CC-sõnumeid tuleb koondada vähemalt 1 sekundi kaupa (kui pakettide kaotusprotsent on kõrge, võivad neid olla sadades, tuhandes või kümnetes tuhandetes sekundis, sõltuvalt bitimäärast).
Seega, et säilitada nii teavet kui ka joonistada graafikud CC-vigadest ja bitimäärast ning teha mõningaid avariid, võivad järgmised variandid olla:
- Parse ja koguda (CC järgi) tsp väljundit, st muuta see vajaliku vormi.
- Täiendada ise tsp ja/või protsessoripluginaid bitrate_monitor ja continuity, et tulemus oleks masinloetaval kujul, mis sobib monitooringusüsteemile.
- Kirjutada oma rakendus tsduck raamatukogu peal.
Ilmselgelt on töömahtude aspektist variant 1 kõige lihtsam, eriti arvestades, et ise tsduck on kirjutatud madala taseme (kaasaegsete mõõdikute järgi) keeles (C++).
Lihtne parser+agregaatori prototüüp bashis näitas, et 10Mbit/s voolul ja 50% pakettide kadumise (halvim variant) korral tarbis bashiprotsess 3-4 korda rohkem CPU-d kui tsp protsess ise. Selline arengu variant on vastuvõetamatu. Siin on osa sellest prototüübist.
Bashi nuudlid
#!/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
doneLisaks sellele, et see töötab ebanormaalselt aeglaselt, puuduvad bash'is normaalsed lõimed, bash tööd on iseseisvad protsessid ja tuli iga sekundi jooksul salvestada väärtus missingPackets külgefektina (saades iga sekundi jooksul bittide kiirusest teateid). Lõpuks jäeti bash rahule ja otsustati kirjutada golang’is wrapper (parser + agregaat). CPU tarbimine sarnase koodi puhul golang’is on 4-5 korda väiksem kui tsp protsessi puhul. Wrapperi kiirus golang’i kasutamise tõttu paraneb ligikaudu 16 korda ja üldiselt on tulemus vastuvõetav (CPU ülejääk kõige halvemal juhul 25%). Algne fail golang'is asub .
Wrapperi käivitamine
Wrapperi käivitamiseks on loodud lihtne teenusemall systemd jaoks (). Eeldatakse, et wrapper on kompileeritud binaarfailiks (go build tsduck-stat.go), mis on paigutatud /opt/tsduck-stat/. Eeldatakse, et kasutatakse golang’i, mis toetab monotonic kellale (>=1.9).
Teenuse eksemplari loomiseks tuleb käivitada käsk systemctl enable tsduck-stat@239.0.0.1:1234, seejärel algatada kasutades systemctl start tsduck-stat@239.0.0.1:1234.
Discovery Zabbixist
Kuna zabbix peab suunatud teenuste avastamiseks looma (discovery.sh), Zabbixi avastamiseks vajalikus formaadis, eeldatakse, et see on seal samas — /opt/tsduck-stat. Avasta Zabbix-agentiga seotud käivitamiseks tuleb lisada zabbix-agendi konfigureerimise kausta, et lisada user-parameeter.
Zabbixi mall
(tsduck_stat_template.xml) sisaldab automaatavastamise reeglit, andmeelementide, diagrammide ja signaalide prototüüpe.
Lühike kontrollnimekiri (juhuks kui keegi soovib kasutada)
- Veendu, et tsp ei kukuta pakette 'ideaalses' keskkonnas (generaator ja analüsaator on otse ühendatud), kui kukkumisi on, vaata p.2 või artikli teksti selle kohta.
- Tee maksimum soketi puhvri häälestamine (net.core.rmem_max=8388608).
- Kompileeri tsduck-stat.go (go build tsduck-stat.go).
- Aseta teenuse mall /lib/systemd/system.
- Käivita teenused systemctl abil, kontrolli, et loendurid hakkavad ilmuma (grep «» /dev/shm/tsduck-stat/*). Teenuste arv peab vastama multicasti voogude arvule. Siin võib olla vajalik luua marsruut multicasti gruppi, võib-olla deaktiveerida rp_filter või luua marsruut source ip jaoks.
- Käivita discovery.sh, veendu, et see genereerib json.
- Sisesta zabbix-agendi konfiguratsioon, taaskäivita zabbix-agent.
- Laadi mall fail zabbix, rakenda see hostile, kus toimub jälgimine ja on installitud zabbix-agent, oota umbes 5 minutit, vaata, et uued andmeelemendid, graafikud ja triggarid on ilmunud.
Tulemus

Pakettide kaotuse tuvastamiseks on see peaaegu piisav, parem on kui mitte mingit jälgimist.
Tõepoolest, CC-"kaotused" võivad tekkida videofragmente ühendades (kui ma õigesti tean, nii tehakse sisestusi kohalikes telejaamades Venemaal, st CC-arvesti ei arvestata), seda tuleb meeles pidada. Proprietaarsetes lahendustes on see probleem osaliselt mööda hiilimiseks SCTE-35 märkide tuvastamine (kui need lisatakse voogedastuse generaatoriga).
Transpordi kvaliteedi jälgimise seisukohalt puudub jitter (IAT) jälgimine, kuna TV-seadmed (olgu need modulaatorid või lõppseadmed) vajavad seda parameetrit ning jitbufferit ei saa alati lõpmatuseni suurendada. Jitter võib muutuda, kui ülekandel kasutatakse suurte puhverdatud seadmeid ja QoS ei ole sarnase reaalajas liikluse edastamiseks seadistatud või pole piisavalt hästi seadistatud.
Allikas: habr.com
