Idag finns det färdiga (proprietära) lösningar för övervakning av till exempel IP(TS)-strömmar
Mycket kortfattat om TSDuck
TSDuck är en programvara med öppen källkod (2-klausul BSD-licens) (en uppsättning konsolverktyg och ett bibliotek för att utveckla anpassade verktyg eller plugins) för att manipulera TS-strömmar. Som ingång kan den fungera med IP (multicast/unicast), http, hls, dvb tuners, dektec dvb-asi demodulator, det finns en intern TS-stream generator och läsning från filer. Utdata kan vara att skriva till en fil, IP (multicast/unicast), hls, dektec dvb-asi och HiDes-modulatorer, spelare (mplayer, vlc, xine) och drop. Olika trafikprocessorer kan inkluderas mellan ingång och utdata, till exempel PID-ommappning, kryptering/avkodning, CC-räknaranalys, bithastighetsberäkning och andra typiska operationer för TS-strömmar.
I den här artikeln kommer IP-strömmar (multicast) att användas som ingång, processorerna bitrate_monitor (från namnet är det tydligt vad det är) och kontinuitet (analys av CC-räknare). Du kan enkelt ersätta IP multicast med en annan ingångstyp som stöds av TSDuck.
Det finns
Därefter används version TSDuck 3.19-1520, Linux används som operativsystem (debian 10 användes för att förbereda lösningen, CentOS 7 användes för verklig användning)
Förbereder TSDuck och OS
Innan du övervakar verkliga flöden måste du se till att TSDuck fungerar korrekt och att det inte finns några fall på nätverkskorts- eller OS-nivå (socket). Detta krävs för att inte senare gissa var fallen inträffade - på nätverket eller "inne i servern". Du kan kontrollera fall på nätverkskortsnivå med ethtool -S ethX-kommandot, inställningen görs av samma ethtool (vanligtvis måste du öka RX-bufferten (-G) och ibland inaktivera vissa avlastningar (-K)). Som en allmän rekommendation kan det rekommenderas att använda en separat port för att ta emot den analyserade trafiken, om möjligt, detta minimerar falska positiva resultat förknippade med det faktum att fallet inträffade exakt på analysatorns port på grund av närvaron av annan trafik. Om detta inte är möjligt (en minidator/NUC med en port används) så är det mycket önskvärt att sätta upp prioriteringen av den analyserade trafiken i förhållande till resten på enheten som analysatorn är ansluten till. Angående virtuella miljöer, här måste du vara försiktig och kunna hitta paketdroppar som börjar från en fysisk port och slutar med en applikation inuti en virtuell maskin.
Generering och mottagning av en ström inuti värden
Som ett första steg i att förbereda TSDuck kommer vi att generera och ta emot trafik inom en enda värd med hjälp av netns.
Förbereda miljön:
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ön är redo. Vi startar trafikanalysatorn:
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
där "-p 1 -t 1" betyder att du behöver beräkna bithastigheten varje sekund och visa information om bithastigheten varje sekund
Vi startar trafikgeneratorn 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
där "-p 7 -e" betyder att du behöver packa 7 TS-paket i 1 IP-paket och göra det hårt (-e), d.v.s. vänta alltid 7 TS-paket från den sista processorn innan du skickar ett IP-paket.
Analysatorn börjar mata ut de förväntade meddelandena:
* 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
Lägg nu till några droppar:
ip netns exec P iptables -I INPUT -d 239.0.0.1 -m statistic --mode random --probability 0.001 -j DROP
och meddelanden som detta visas:
* 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
vilket förväntas. Inaktivera paketförlust (ip netns exec P iptables -F) och försök öka generatorns bithastighet till 100 Mbps. Analysatorn rapporterar ett gäng CC-fel och cirka 75 Mbps istället för 100. Vi försöker ta reda på vem som är skyldig - generatorn har inte tid eller problemet finns inte i den, för detta börjar vi generera ett fast antal paket (700000 100000 TS-paket = XNUMX XNUMX IP-paket):
# 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 genererades exakt 100000 151925460 IP-paket (151825460-1). Så låt oss ta reda på vad som händer med analysatorn, för detta kontrollerar vi med RX-räknaren på veth0, den är strikt lika med TX-räknaren på vethXNUMX, sedan tittar vi på vad som händer på sockelnivån:
# 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
Här kan du se antalet droppar = 24355. I TS-paket är detta 170485 eller 24.36% av 700000, så vi ser att samma 25% av den förlorade bithastigheten är droppar i udp-socket. Fall i en UDP-socket uppstår vanligtvis på grund av brist på buffert, titta på standardsockets buffertstorlek och den maximala socketbuffertstorleken:
# sysctl net.core.rmem_default
net.core.rmem_default = 212992
# sysctl net.core.rmem_max
net.core.rmem_max = 212992
Således, om applikationer inte uttryckligen begär en buffertstorlek, skapas sockets med en buffert på 208 KB, men om de begär mer kommer de fortfarande inte att få det som efterfrågades. Eftersom du kan ställa in buffertstorleken i tsp för IP-ingången (-buffert-storlek), kommer vi inte att röra standardsocketstorleken, utan endast ställa in den maximala sockets buffertstorlek och specificera buffertstorleken explicit genom tsp-argumenten:
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 denna inställning av socketbufferten, nu den rapporterade bithastigheten är cirka 100 Mbps, finns det inga CC-fel.
Enligt processorförbrukningen för själva tsp-applikationen. I förhållande till en kärna i5-4260U CPU @ 1.40 GHz, 10 Mbps flödesanalys kommer att kräva 3-4% CPU, 100 Mbps - 25%, 200 Mbps - 46%. När du ställer in % Packet Loss ökar belastningen på CPU:n praktiskt taget inte (men kan minska).
På mer produktiv hårdvara var det möjligt att generera och analysera strömmar på mer än 1Gb/s utan problem.
Testar på riktiga nätverkskort
Efter att ha testat på ett veth-par måste du ta två värdar eller två portar på en värd, ansluta portarna till varandra, starta generatorn på den ena och analysatorn på den andra. Det var inga överraskningar här, men i själva verket beror allt på järnet, ju svagare, desto mer intressant blir det här.
Använda mottagna data av övervakningssystemet (Zabbix)
tsp har inget maskinläsbart API som SNMP eller liknande. CC-meddelanden måste aggregeras i minst 1 sekund (med en hög procentandel av paketförlust kan det finnas hundratals/tusentals/tiotusentals per sekund, beroende på bithastigheten).
För att spara både information och rita grafer för CC-fel och bithastighet och göra någon form av olyckor kan det alltså finnas följande alternativ:
- Analysera och aggregera (med CC) produktionen av tsp, dvs. konvertera den till önskad form.
- Slutför tsp själv och/eller processorplugin bitrate_monitor och kontinuitet så att resultatet ges i en maskinläsbar form lämplig för övervakningssystemet.
- Skriv din ansökan ovanpå tsduck-biblioteket.
Uppenbarligen är alternativ 1 det enklaste när det gäller ansträngning, särskilt med tanke på att tsduck i sig är skrivet på ett lågnivåspråk (enligt moderna standarder) (C ++)
En enkel prototyp för bash-parser+aggregator visade att på en ström på 10 Mbps och 50 % paketförlust (i värsta fall) förbrukade bash-processen 3-4 gånger mer CPU än själva tsp-processen. Detta scenario är oacceptabelt. Egentligen en del av denna prototyp nedan
Nudlar 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
Förutom att det är oacceptabelt långsamt finns det inga normala trådar i bash, bash-jobb är separata processer, och jag var tvungen att skriva värdet av missingPackets en gång i sekunden på bieffekten (när jag tar emot bithastighetsmeddelanden som kommer varje sekund). Som ett resultat lämnades bash ifred och det beslutades att skriva ett omslag (parser + aggregator) i golang. CPU-förbrukningen av liknande golang-kod är 4-5 gånger mindre än själva tsp-processen. Hastigheten på omslaget på grund av att bash ersatts med golang visade sig vara cirka 16 gånger och i allmänhet är resultatet acceptabelt (CPU-overhead med 25% i värsta fall). Golang-källfilen finns
Kör omslag
För att starta omslaget gjordes den enklaste servicemallen för systemd (
För att skapa en instans av tjänsten måste du köra kommandot systemctl enable [e-postskyddad]:1234 kör sedan med systemctl start [e-postskyddad]: 1234.
Upptäckt från Zabbix
För att zabbix ska kunna upptäcka löpande tjänster görs det
Zabbix mall
Kort checklista (tja, tänk om någon bestämmer sig för att använda den)
- Se till att tsp inte tappar paket under "ideala" förhållanden (generator och analysator är anslutna direkt), om det finns droppar, se punkt 2 eller artikeltexten om denna fråga.
- Ställ in den maximala sockelbufferten (net.core.rmem_max=8388608).
- Kompilera tsduck-stat.go (bygg tsduck-stat.go).
- Lägg tjänstmallen i /lib/systemd/system.
- Starta tjänster med systemctl, kontrollera att räknare har börjat dyka upp (grep "" /dev/shm/tsduck-stat/*). Antalet tjänster efter antalet multicastströmmar. Här kan du behöva skapa en rutt till multicast-gruppen, kanske inaktivera rp_filter eller skapa en rutt till käll-ip.
- Kör discovery.sh, se till att det genererar json.
- Lägg till zabbix agent config, starta om zabbix agent.
- Ladda upp mallen till zabbix, applicera den på värden som övervakas och zabbix-agenten är installerad, vänta ca 5 minuter, se om det finns nya objekt, grafer och triggers.
Resultat
För uppgiften att upptäcka paketförlust räcker det nästan, åtminstone är det bättre än ingen övervakning.
Faktum är att CC-"förluster" kan uppstå vid sammanslagning av videofragment (så vitt jag vet är det så här insatser görs på lokala TV-center i Ryska federationen, d.v.s. utan att räkna om CC-räknaren), detta måste komma ihåg. Proprietära lösningar kringgår delvis detta problem genom att detektera SCTE-35-etiketter (om de läggs till av strömgeneratorn).
När det gäller övervakning av transportkvalitet saknas jitterövervakning (IAT). TV-utrustning (vare sig det är modulatorer eller slutenheter) har krav på denna parameter och det är inte alltid möjligt att blåsa upp jitbuffern till oändligheten. Och jitter kan flyta när utrustning med stora buffertar används i transit och QoS inte är konfigurerat eller inte tillräckligt välkonfigurerat för att överföra sådan realtidstrafik.
Källa: will.com