I dag finnes det ferdige (proprietære) løsninger for for eksempel overvåking av IP(TS)-strømmer
Veldig kort om TSDuck
TSDuck er en åpen kildekode (2-klausul BSD-lisens) programvare (et sett med konsollverktøy og et bibliotek for å utvikle tilpassede verktøy eller plugins) for å manipulere TS-strømmer. Som inngang kan den fungere med IP (multicast/unicast), http, hls, dvb tunere, dektec dvb-asi demodulator, det er intern TS-stream generator og lesing fra filer. Utgangen kan være skriving til en fil, IP (multicast/unicast), hls, dektec dvb-asi og HiDes modulatorer, spillere (mplayer, vlc, xine) og drop. Du kan aktivere ulike trafikkprosessorer mellom input og output, for eksempel PID-omtilordning, scrambling / descrambling, CC-telleranalyse, bitrateberegning og andre typiske operasjoner for TS-strømmer.
I denne artikkelen vil IP-strømmer (multicast) brukes som inngang, prosessorene bitrate_monitor (fra navnet er det tydelig hva det er) og kontinuitet (analyse av CC-tellere). Du kan enkelt erstatte IP multicast med en annen inngangstype som støttes av TSDuck.
Det er
Deretter brukes versjon TSDuck 3.19-1520, Linux brukes som OS (debian 10 ble brukt til å forberede løsningen, CentOS 7 ble brukt til reell bruk)
Forbereder TSDuck og OS
Før du overvåker reelle flyter, må du forsikre deg om at TSDuck fungerer riktig og at det ikke er noen fall på nettverkskortet eller OS (socket) nivå. Dette er nødvendig for ikke å gjette senere hvor fallene skjedde - på nettverket eller "inne på serveren". Du kan sjekke fall på nettverkskortnivå med ethtool -S ethX-kommandoen, tuning gjøres av samme ethtool (vanligvis må du øke RX-bufferen (-G) og noen ganger deaktivere noen avlastninger (-K)). Som en generell anbefaling kan det anbefales å bruke en egen port for å motta den analyserte trafikken, hvis mulig, dette minimerer falske positiver knyttet til det faktum at fallet skjedde nøyaktig på analysatorporten på grunn av tilstedeværelsen av annen trafikk. Hvis dette ikke er mulig (det brukes en mini-datamaskin/NUC med én port), så er det svært ønskelig å sette opp prioriteringen av den analyserte trafikken i forhold til resten på enheten som analysatoren er koblet til. Når det gjelder virtuelle miljøer, her må du være forsiktig og kunne finne pakkedråper som starter fra en fysisk port og slutter med en applikasjon inne i en virtuell maskin.
Generering og mottak av en strøm inne i verten
Som et første trinn i å forberede TSDuck, vil vi generere og motta trafikk innenfor en enkelt vert ved å bruke netns.
Forberede miljøet:
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
Miljøet er klart. Vi starter trafikkanalysatoren:
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
der "-p 1 -t 1" betyr at du må beregne bithastigheten hvert sekund og vise informasjon om bithastigheten hvert sekund
Vi starter trafikkgeneratoren med en hastighet på 10 Mbps:
tsp -I craft
-P regulate -b 10000000
-O ip -p 7 -e --local-port 6000 239.0.0.1:1234
der "-p 7 -e" betyr at du må pakke 7 TS-pakker inn i 1 IP-pakke og gjøre det hardt (-e), dvs. vent alltid 7 TS-pakker fra siste prosessor før du sender en IP-pakke.
Analysatoren begynner å sende ut de forventede meldingene:
* 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
Tilsett nå noen dråper:
ip netns exec P iptables -I INPUT -d 239.0.0.1 -m statistic --mode random --probability 0.001 -j DROP
og meldinger som dette vises:
* 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
som er forventet. Deaktiver pakketap (ip netns exec P iptables -F) og prøv å øke generatorens bithastighet til 100 Mbps. Analysatoren rapporterer en haug med CC-feil og omtrent 75 Mbps i stedet for 100. Vi prøver å finne ut hvem som har skylden - generatoren har ikke tid eller problemet er ikke i den, for dette begynner vi å generere et fast antall pakker (700000 100000 TS-pakker = XNUMX XNUMX IP-pakker):
# 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
Som du kan se, ble nøyaktig 100000 151925460 IP-pakker generert (151825460-1). Så la oss finne ut hva som skjer med analysatoren, for dette sjekker vi med RX-telleren på veth0, den er strengt tatt lik TX-telleren på vethXNUMX, så ser vi på hva som skjer på socket-nivå:
# 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
Her kan du se antall drops = 24355. I TS-pakker er dette 170485 eller 24.36% av 700000, så vi ser at de samme 25% av den tapte bithastigheten er fall i udp-socket. Fall i en UDP-socket oppstår vanligvis på grunn av mangel på buffer, se på standard socketbufferstørrelse og maksimal socketbufferstørrelse:
# sysctl net.core.rmem_default
net.core.rmem_default = 212992
# sysctl net.core.rmem_max
net.core.rmem_max = 212992
Således, hvis applikasjoner ikke eksplisitt ber om en bufferstørrelse, opprettes sockets med en buffer på 208 KB, men hvis de ber om mer, vil de fortsatt ikke motta det som ble forespurt. Siden du kan angi bufferstørrelsen i tsp for IP-inngangen (-buffer-størrelse), vil vi ikke berøre standard socket-størrelse, men bare angi maksimal socket-bufferstørrelse og spesifisere bufferstørrelsen eksplisitt gjennom tsp-argumentene:
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
Med denne innstillingen av socketbufferen, nå er den rapporterte bithastigheten omtrent 100 Mbps, er det ingen CC-feil.
I henhold til CPU-forbruket til selve tsp-applikasjonen. I forhold til én kjerne i5-4260U CPU @ 1.40 GHz, vil 10 Mbps flytanalyse kreve 3-4 % CPU, 100 Mbps – 25 %, 200 Mbps – 46 %. Når du angir % Packet Loss, øker ikke belastningen på CPU-en (men kan reduseres).
På mer produktiv maskinvare var det mulig å generere og analysere strømmer på mer enn 1 Gb/s uten problemer.
Testing på ekte nettverkskort
Etter å ha testet på et veth-par, må du ta to verter eller to porter på en vert, koble portene til hverandre, starte generatoren på den ene og analysatoren på den andre. Det var ingen overraskelser her, men faktisk avhenger alt av jernet, jo svakere, jo mer interessant blir det her.
Bruke de mottatte dataene fra overvåkingssystemet (Zabbix)
tsp har ikke noe maskinlesbart API som SNMP eller lignende. CC-meldinger må aggregeres i minst 1 sekund (med en høy prosentandel av pakketap kan det være hundrevis/tusenvis/ titusenvis per sekund, avhengig av bithastigheten).
For å lagre både informasjon og tegne grafer for CC-feil og bitrate og gjøre noen slags ulykker, kan det være følgende alternativer:
- Parse og aggreger (ved CC) produksjonen av tsp, dvs. konverter den til ønsket form.
- Fullfør tsp selv og/eller prosessorplugin bitrate_monitor og kontinuitet slik at resultatet blir gitt i en maskinlesbar form som passer for overvåkingssystemet.
- Skriv søknaden din på toppen av tsduck-biblioteket.
Åpenbart er alternativ 1 det enkleste når det gjelder innsats, spesielt med tanke på at tsduck i seg selv er skrevet på et lavt nivå (etter moderne standarder) språk (C ++)
En enkel bash-parser+aggregator-prototype viste at på en 10Mbps-strøm og 50 % pakketap (verste fall), forbrukte bash-prosessen 3-4 ganger mer CPU enn selve tsp-prosessen. Dette scenariet er uakseptabelt. Faktisk en del av denne prototypen nedenfor
Nudler på toppen
#!/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
I tillegg til å være uakseptabelt treg, er det ingen normale tråder i bash, bash-jobber er separate prosesser og jeg måtte skrive verdien av missingPackets en gang i sekundet på bieffekten (når jeg mottar bitrate-meldinger som kommer hvert sekund). Som et resultat ble bash stående i fred og det ble besluttet å skrive en wrapper (parser + aggregator) i golang. CPU-forbruket av lignende golang-kode er 4-5 ganger mindre enn selve tsp-prosessen. Hastigheten på innpakningen på grunn av utskifting av bash med golang viste seg å være omtrent 16 ganger, og generelt er resultatet akseptabelt (CPU-overhead med 25 % i verste fall). Golang-kildefilen er lokalisert
Kjør wrapper
For å starte innpakningen ble den enkleste tjenestemalen for systemd laget (
For å opprette en forekomst av tjenesten, må du kjøre kommandoen systemctl enable [e-postbeskyttet]:1234 kjør deretter med systemctl start [e-postbeskyttet]: 1234.
Oppdagelse fra Zabbix
For at zabbix skal kunne oppdage løpende tjenester, er det gjort
Zabbix mal
Kort sjekkliste (vel, hva om noen bestemmer seg for å bruke den)
- Pass på at tsp ikke slipper pakker under "ideelle" forhold (generator og analysator er koblet direkte), hvis det er fall, se avsnitt 2 eller teksten i artikkelen om denne saken.
- Foreta innstilling av maksimal socketbuffer (net.core.rmem_max=8388608).
- Kompiler tsduck-stat.go (gå og bygg tsduck-stat.go).
- Sett tjenestemalen i /lib/systemd/system.
- Start tjenester med systemctl, sjekk at tellere har begynt å vises (grep "" /dev/shm/tsduck-stat/*). Antall tjenester etter antall multicast-strømmer. Her må du kanskje lage en rute til multicast-gruppen, kanskje deaktivere rp_filter eller lage en rute til kilde-ip.
- Kjør discovery.sh, sørg for at den genererer json.
- Legg til zabbix agent config, start zabbix agent på nytt.
- Last opp malen til zabbix, bruk den på verten som overvåkes og zabbix-agenten er installert, vent ca. 5 minutter, se om det er nye elementer, grafer og triggere.
Resultat
For oppgaven med å oppdage pakketap er det nesten nok, i det minste er det bedre enn ingen overvåking.
Faktisk kan CC-"tap" oppstå ved sammenslåing av videofragmenter (så vidt jeg vet, er dette hvordan innlegg lages på lokale TV-sentre i Russland, dvs. uten å beregne CC-telleren på nytt), dette må huskes. Proprietære løsninger omgår delvis dette problemet ved å oppdage SCTE-35-etiketter (hvis lagt til av strømgeneratoren).
Når det gjelder overvåking av transportkvalitet, er det mangel på jitterovervåking (IAT). TV-utstyr (det være seg modulatorer eller sluttenheter) har krav til denne parameteren og det er ikke alltid mulig å blåse opp jitbufferen til det uendelige. Og jitter kan flyte når utstyr med store buffere brukes i transitt og QoS ikke er konfigurert eller ikke godt konfigurert nok til å overføre slik sanntidstrafikk.
Kilde: www.habr.com