Danas postoje gotova (vlastita) rješenja za praćenje IP(TS) tokova, npr.
Vrlo kratko o TSDucku
TSDuck je softver otvorenog koda (2-klauzula BSD licence) (skup konzolnih uslužnih programa i biblioteka za razvoj prilagođenih uslužnih programa ili dodataka) za manipuliranje TS streamovima. Kao ulaz može raditi s IP (multicast/unicast), http, hls, dvb tunerima, dektec dvb-asi demodulatorom, postoji interni TS-stream generator i čitanje iz datoteka. Izlaz može biti pisanje u datoteku, IP (multicast/unicast), hls, dektec dvb-asi i HiDes modulatori, playeri (mplayer, vlc, xine) i drop. Između ulaza i izlaza mogu se uključiti različiti procesori prometa, na primjer, remapiranje PID-a, kodiranje/dekodiranje, analiza CC brojača, izračun brzine prijenosa i druge tipične operacije za TS tokove.
U ovom članku će se kao ulaz koristiti IP streamovi (multicast), korišteni su procesori bitrate_monitor (iz naziva je jasno o čemu se radi) i kontinuitet (analiza CC brojača). IP multicast možete jednostavno zamijeniti drugom vrstom unosa koju podržava TSDuck.
Postoje
Zatim se koristi verzija TSDuck 3.19-1520, kao OS se koristi Linux (za pripremu rješenja korišten je debian 10, za stvarnu upotrebu CentOS 7)
Priprema TSDuck i OS
Prije praćenja stvarnih protoka, morate se uvjeriti da TSDuck radi ispravno i da nema padova na razini mrežne kartice ili OS-a (socket). Ovo je potrebno kako se kasnije ne bi nagađalo gdje su se padovi dogodili - na mreži ili "unutar poslužitelja". Možete provjeriti padove na razini mrežne kartice pomoću naredbe ethtool -S ethX, podešavanje se vrši istim ethtool-om (obično trebate povećati RX međuspremnik (-G) i ponekad onemogućiti neka opterećenja (-K)). Kao opću preporuku, može se savjetovati korištenje zasebnog priključka za primanje analiziranog prometa, ako je moguće, ovo minimizira lažne pozitivne rezultate povezane s činjenicom da se pad dogodio točno na priključku analizatora zbog prisutnosti drugog prometa. Ukoliko to nije moguće (koristi se mini-računalo/NUC s jednim portom), tada je vrlo poželjno postaviti prioritet analiziranog prometa u odnosu na ostatak na uređaju na koji je analizator spojen. Što se tiče virtualnih okruženja, ovdje morate biti oprezni i moći pronaći ispuštanje paketa počevši od fizičkog priključka do aplikacije unutar virtualnog stroja.
Generiranje i prijem toka unutar hosta
Kao prvi korak u pripremi TSDucka, mi ćemo generirati i primati promet unutar jednog hosta koristeći netns.
Priprema okoline:
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
Okolina je spremna. Pokrećemo analizator prometa:
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
gdje "-p 1 -t 1" znači da trebate izračunati brzinu prijenosa svake sekunde i prikazati informacije o brzini prijenosa svake sekunde
Pokrećemo generator prometa brzinom od 10Mbps:
tsp -I craft
-P regulate -b 10000000
-O ip -p 7 -e --local-port 6000 239.0.0.1:1234
gdje "-p 7 -e" znači da morate spakirati 7 TS paketa u 1 IP paket i to učiniti teško (-e), tj. uvijek pričekajte 7 TS paketa od zadnjeg procesora prije slanja IP paketa.
Analizator počinje ispisivati očekivane poruke:
* 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
Sada dodajte nekoliko kapi:
ip netns exec P iptables -I INPUT -d 239.0.0.1 -m statistic --mode random --probability 0.001 -j DROP
i pojavljuju se poruke poput ove:
* 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
što se očekuje. Onemogućite gubitak paketa (ip netns exec P iptables -F) i pokušajte povećati bitrate generatora na 100 Mbps. Analizator javlja hrpu CC grešaka i oko 75 Mbps umjesto 100. Pokušavamo otkriti tko je kriv - generator nema vremena ili problem nije u njemu, za ovo počinjemo generirati fiksni broj paketi (700000 TS paketa = 100000 IP paketa):
# 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
Kao što vidite, generirano je točno 100000 IP paketa (151925460-151825460). Dakle, shvatimo što se događa s analizatorom, za ovo provjeravamo s RX brojačem na veth1, on je strogo jednak TX brojaču na veth0, zatim gledamo što se događa na razini utičnice:
# 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
Ovdje možete vidjeti broj dropova = 24355. U TS paketima to je 170485 ili 24.36% od 700000, tako da vidimo da su tih istih 25% izgubljenog bitratea dropovi u udp socketu. Do pada u UDP utičnici obično dolazi zbog nedostatka međuspremnika, pogledajte zadanu veličinu međuspremnika utičnice i maksimalnu veličinu međuspremnika utičnice:
# sysctl net.core.rmem_default
net.core.rmem_default = 212992
# sysctl net.core.rmem_max
net.core.rmem_max = 212992
Stoga, ako aplikacije izričito ne zahtijevaju veličinu međuspremnika, utičnice se stvaraju s međuspremnikom od 208 KB, ali ako zatraže više, još uvijek neće dobiti traženo. Budući da možete postaviti veličinu međuspremnika u tsp za IP ulaz (-buffer-size), nećemo dirati zadanu veličinu utičnice, već samo postaviti maksimalnu veličinu međuspremnika i odrediti veličinu međuspremnika eksplicitno kroz 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
S ovim podešavanjem međuspremnika utičnice, sada je prijavljena brzina prijenosa oko 100 Mbps, nema CC pogrešaka.
Prema CPU potrošnji same tsp aplikacije. U odnosu na jedan jezgreni i5-4260U CPU na 1.40 GHz, analiza protoka od 10 Mbps zahtijevat će 3-4% CPU-a, 100 Mbps - 25%, 200 Mbps - 46%. Prilikom postavljanja % gubitka paketa, opterećenje CPU-a praktički se ne povećava (ali se može smanjiti).
Na produktivnijem hardveru bilo je moguće generirati i analizirati tokove veće od 1Gb/s bez ikakvih problema.
Testiranje na pravim mrežnim karticama
Nakon testiranja na veth paru, trebate uzeti dva hosta ili dva porta jednog hosta, spojiti portove jedan s drugim, pokrenuti generator na jednom, a analizator na drugom. Tu nije bilo iznenađenja, ali zapravo sve ovisi o željezu, što je slabije, to će ovdje biti zanimljivije.
Korištenje primljenih podataka od strane sustava za nadzor (Zabbix)
tsp nema nikakav strojno čitljiv API poput SNMP-a ili sličnog. CC poruke moraju biti agregirane najmanje 1 sekundu (s visokim postotkom gubitka paketa, može ih biti na stotine/tisuće/desetke tisuća u sekundi, ovisno o brzini prijenosa).
Stoga, kako biste spremili informacije i nacrtali grafikone za CC pogreške i bitrate i napravili neku vrstu nezgoda, mogu postojati sljedeće opcije:
- Raščlanite i agregirajte (pomoću CC) izlaz tsp, tj. pretvoriti u željeni oblik.
- Dovršite sam tsp i/ili procesorske dodatke bitrate_monitor i kontinuitet tako da se rezultat daje u strojno čitljivom obliku prikladnom za sustav nadzora.
- Napišite svoju aplikaciju na vrhu tsduck biblioteke.
Očito je da je opcija 1 najlakša u smislu napora, posebno imajući u vidu da je sam tsduck napisan na jeziku niske razine (po modernim standardima) (C ++)
Jednostavan prototip bash parser+agregatora pokazao je da na streamu od 10 Mbps i 50% gubitka paketa (u najgorem slučaju), bash proces troši 3-4 puta više CPU-a nego sam tsp proces. Ovaj scenarij je neprihvatljiv. Zapravo dio ovog prototipa ispod
Rezanci na vrhu
#!/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
Osim što je neprihvatljivo spor, u bashu nema normalnih niti, bash poslovi su odvojeni procesi, a ja sam morao pisati vrijednost missingPackets jednom u sekundi zbog nuspojave (prilikom primanja bitrate poruka koje dolaze svake sekunde). Kao rezultat toga, bash je ostao sam i odlučeno je da se omot (parser + agregator) napiše u golangu. CPU potrošnja sličnog golang koda je 4-5 puta manja od samog tsp procesa. Ubrzanje omotača zbog zamjene basha golangom pokazalo se oko 16 puta i općenito je rezultat prihvatljiv (preopterećenje CPU-a za 25% u najgorem slučaju). Golang izvorna datoteka je locirana
Pokreni omot
Za pokretanje wrappera napravljen je najjednostavniji servisni predložak za systemd (
Da biste kreirali instancu usluge, morate pokrenuti naredbu systemctl enable [e-pošta zaštićena]:1234 zatim pokrenite s systemctl start [e-pošta zaštićena]: 1234.
Otkriće Zabbixa
Da bi zabbix mogao otkriti pokrenute usluge, to je učinjeno
Zabbix predložak
Kratki kontrolni popis (dobro, što ako ga netko odluči koristiti)
- Provjerite da tsp ne ispušta pakete pod "idealnim" uvjetima (generator i analizator su povezani izravno), ako ima ispuštanja, pogledajte paragraf 2 ili tekst članka o ovom pitanju.
- Izvršite podešavanje maksimalnog međuspremnika utičnice (net.core.rmem_max=8388608).
- Prevedi tsduck-stat.go (idi izgradi tsduck-stat.go).
- Stavite predložak usluge u /lib/systemd/system.
- Pokrenite usluge s systemctl, provjerite jesu li se počeli pojavljivati brojači (grep "" /dev/shm/tsduck-stat/*). Broj usluga prema broju multicast tokova. Ovdje ćete možda morati stvoriti rutu do multicast grupe, možda onemogućiti rp_filter ili stvoriti rutu do izvorne ip adrese.
- Pokrenite discovery.sh, provjerite generira li json.
- Dodajte konfiguraciju zabbix agenta, ponovno pokrenite zabbix agenta.
- Učitajte predložak na zabbix, primijenite ga na host koji se prati i zabbix-agent je instaliran, pričekajte oko 5 minuta, pogledajte ima li novih stavki, grafikona i okidača.
Rezultirati
Za zadatak otkrivanja gubitka paketa, to je gotovo dovoljno, barem je bolje od nikakvog praćenja.
Doista, kod spajanja video fragmenata može doći do "gubitaka" CC-a (koliko ja znam, tako se rade umetci u lokalnim TV centrima u Ruskoj Federaciji, tj. bez ponovnog izračunavanja CC brojača), to se mora zapamtiti. Vlasnička rješenja djelomično zaobilaze ovaj problem otkrivanjem SCTE-35 oznaka (ako ih je dodao generator toka).
Što se tiče praćenja kvalitete prijevoza, nedostaje praćenje podrhtavanja (IAT). TV oprema (bilo da se radi o modulatorima ili krajnjim uređajima) ima zahtjeve za ovaj parametar i nije uvijek moguće napuhati jitbuffer do beskonačnosti. I podrhtavanje može plutati kada se oprema s velikim međuspremnicima koristi u prijenosu, a QoS nije konfiguriran ili nije dovoljno dobro konfiguriran za prijenos takvog prometa u stvarnom vremenu.
Izvor: www.habr.com