TSDuck naudojimas IP (TS) srautams stebėti

Šiandien, pavyzdžiui, yra paruoštų (patentuotų) sprendimų IP (TS) srautams stebėti VB и iQ, jie turi gana gausų funkcijų rinkinį ir dažniausiai tokius sprendimus turi dideli operatoriai, užsiimantys televizijos paslaugomis. Šiame straipsnyje aprašomas sprendimas, pagrįstas atvirojo kodo projektu TSDuck, skirtas minimaliam IP (TS) srautų valdymui naudojant CC (tęstinumo skaitiklį) ir bitų dažnį. Galima taikymas yra kontroliuoti paketų praradimą arba visą srautą per išsinuomotą L2 kanalą (kurio negalima normaliai stebėti, pavyzdžiui, nuskaitant nuostolių skaitiklius eilėse).

Labai trumpai apie TSDuck

„TSDuck“ yra atvirojo kodo (2-jų BSD licencijų) programinė įranga (konsolės paslaugų rinkinys ir biblioteka, skirta tinkintoms programoms arba papildiniams kurti), skirta manipuliuoti TS srautais. Kaip įvestis gali dirbti su IP (multicast/unicast), http, hls, dvb imtuvais, dektec dvb-asi demoduliatoriumi, yra vidinis TS srauto generatorius ir skaitymas iš failų. Išvestis gali būti įrašymas į failą, IP (multicast/unicast), hls, dektec dvb-asi ir HiDes moduliatoriai, grotuvai (mplayer, vlc, xine) ir drop. Tarp įvesties ir išvesties galima įtraukti įvairius srauto procesorius, pvz., PID pertvarkymą, kodavimą / iššifravimą, CC skaitiklio analizę, bitų spartos skaičiavimą ir kitas tipines TS srautų operacijas.

Šiame straipsnyje kaip įvestis bus naudojami IP srautai (multicast), naudojami procesoriai bitrate_monitor (iš pavadinimo aišku kas tai) ir tęstinumas (CC skaitiklių analizė). Galite lengvai pakeisti IP multicast į kitą įvesties tipą, palaikomą TSDuck.

Yra oficialios konstrukcijos / paketai TSDuck daugumai dabartinių operacinių sistemų. Jie neprieinami Debian'ui, bet mums pavyko be jokių problemų juos sukurti naudojant debian 8 ir debian 10.

Toliau naudojama versija TSDuck 3.19-1520, Linux naudojama kaip OS (sprendimui paruošti naudota Debian 10, realiam naudojimui – CentOS 7)

TSDuck ir OS paruošimas

Prieš stebėdami realius srautus, turite įsitikinti, kad TSDuck veikia tinkamai ir nėra nukritimų tinklo plokštės ar OS (socket) lygyje. Tai reikalinga norint vėliau neatspėti, kur įvyko kritimas - tinkle ar „serverio viduje“. Tinklo plokštės lygio kritimus galite patikrinti su ethtool -S ethX komanda, derinimas atliekamas ta pačia ethtool (paprastai reikia padidinti RX buferį (-G) ir kartais išjungti kai kuriuos iškrovimus (-K)). Kaip bendra rekomendacija, galima patarti naudoti atskirą prievadą analizuojamam srautui priimti, jei įmanoma, taip sumažinant klaidingus teigiamus atvejus, susijusius su tuo, kad kritimas įvyko būtent analizatoriaus prievade dėl kito srauto. Jei tai neįmanoma (naudojamas mini kompiuteris / NUC su vienu prievadu), labai pageidautina nustatyti analizuojamo srauto prioritetus, palyginti su likusiu įrenginiu, prie kurio prijungtas analizatorius. Kalbant apie virtualią aplinką, čia reikia būti atsargiems ir mokėti rasti paketų kritimus, pradedant nuo fizinio prievado ir baigiant programa virtualioje mašinoje.

Srauto generavimas ir priėmimas pagrindinio kompiuterio viduje

Pirmuoju žingsniu ruošiant TSDuck generuosime ir priimsime srautą viename pagrindiniame kompiuteryje naudodami netns.

Aplinkos paruošimas:

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

Aplinka paruošta. Paleidžiame srauto analizatorių:

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

kur "-p 1 -t 1" reiškia, kad reikia skaičiuoti bitų spartą kas sekundę ir kas sekundę rodyti informaciją apie bitų spartą
Srauto generatorių paleidžiame 10Mbps greičiu:

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

kur "-p 7 -e" reiškia, kad reikia supakuoti 7 TS paketus į 1 IP paketą ir tai padaryti sunkiai (-e), t.y. prieš siųsdami IP paketą visada palaukite 7 TS paketus iš paskutinio procesoriaus.

Analizatorius pradeda išvesti laukiamus pranešimus:

* 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

Dabar pridėkite keletą lašų:

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

ir pasirodo tokie pranešimai:

* 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 

kurio tikimasi. Išjunkite paketų praradimą (ip netns exec P iptables -F) ir pabandykite padidinti generatoriaus bitų spartą iki 100 Mbps. Analizatorius praneša apie krūvą CC klaidų ir apie 75 Mbps vietoj 100. Bandome išsiaiškinti, kas kaltas - generatorius neturi laiko arba problema ne jame, tam pradedame generuoti fiksuotą skaičių paketai (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

Kaip matote, buvo sugeneruota lygiai 100000 151925460 IP paketų (151825460-1). Taigi išsiaiškinkime, kas vyksta su analizatoriumi, tam mes patikriname naudodami RX skaitiklį veth0, jis yra griežtai lygus TX skaitikliui vethXNUMX, tada žiūrime, kas vyksta lizdo lygyje:

# 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 

Čia galite pamatyti kritimų skaičių = 24355. TS paketuose tai yra 170485 arba 24.36% iš 700000 25, todėl matome, kad tie patys XNUMX% prarasto bitų dažnio yra lašai udp lizde. UDP lizdas paprastai nukrenta dėl buferio trūkumo, pažiūrėkite į numatytąjį lizdo buferio dydį ir didžiausią lizdo buferio dydį:

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

Taigi, jei programos aiškiai neprašo buferio dydžio, lizdai sukuriami su 208 KB buferiu, tačiau jei jos prašo daugiau, jos vis tiek negaus to, ko buvo prašoma. Kadangi galite nustatyti IP įvesties buferio dydį tsp (-buffer-size), mes neliesime numatytojo lizdo dydžio, o tik nustatysime maksimalų lizdo buferio dydį ir aiškiai nurodysime buferio dydį naudodami tsp argumentus:

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

Su šiuo lizdo buferio derinimu dabar pranešama apie 100 Mbps bitų perdavimo spartą, CC klaidų nėra.

Pagal pačios tsp programos procesoriaus suvartojimą. Palyginti su vieno branduolio i5-4260U CPU @ 1.40 GHz, 10Mbps srauto analizei reikės 3-4% procesoriaus, 100Mbps - 25%, 200Mbps - 46%. Nustatant % Packet Loss, procesoriaus apkrova praktiškai nedidėja (bet gali sumažėti).

Naudojant produktyvesnę aparatinę įrangą, buvo galima be jokių problemų generuoti ir analizuoti daugiau nei 1 Gb / s srautus.

Testavimas tikrose tinklo plokštėse

Išbandžius ant veth poros, reikia paimti du pagrindinius kompiuterius arba du vieno pagrindinio kompiuterio prievadus, prijungti prievadus vienas prie kito, viename paleisti generatorių, antrame – analizatorių. Jokių staigmenų čia nebuvo, bet iš tikrųjų viskas priklauso nuo lygintuvo, kuo silpnesnis, tuo čia bus įdomiau.

Gautų duomenų naudojimas stebėjimo sistemoje (Zabbix)

tsp neturi jokios mašininiu būdu nuskaitomos API, pvz., SNMP ar panašios. CC pranešimai turi būti apibendrinti mažiausiai 1 sekundę (esant dideliam paketų praradimo procentui, gali būti šimtai/tūkstančiai/dešimties tūkstančių per sekundę, priklausomai nuo bitų greičio).

Taigi, norint išsaugoti informaciją ir nubraižyti CC klaidų bei bitų dažnio grafikus ir padaryti tam tikras avarijas, gali būti šios parinktys:

  1. Išanalizuoti ir sukaupti (pagal CC) tsp išeigą, t.y. konvertuoti į norimą formą.
  2. Užbaikite patį tsp ir (arba) procesoriaus įskiepius bitrate_monitor ir tęstinumą, kad rezultatas būtų pateiktas kompiuterio skaitoma forma, tinkama stebėjimo sistemai.
  3. Parašykite savo paraišką tsduck bibliotekos viršuje.

Akivaizdu, kad 1 variantas yra lengviausias pastangų požiūriu, ypač turint omenyje, kad pati tsduck yra parašyta žemo lygio (pagal šiuolaikinius standartus) kalba (C ++).

Paprastas bash analizatorius + agregatorius prototipas parodė, kad esant 10 Mbps srautui ir 50% paketų praradimui (blogiausiu atveju), bash procesas sunaudojo 3–4 kartus daugiau procesoriaus nei pats TSP procesas. Šis scenarijus yra nepriimtinas. Tiesą sakant, šio prototipo dalis žemiau

Makaronai ant viršaus

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

Be to, kad jis yra nepriimtinai lėtas, bash nėra normalių gijų, bash darbai yra atskiri procesai, o šalutiniame efekte (gaunant bitrate pranešimus, kurie ateina kas sekundę) turėjau kartą per sekundę įrašyti trūkstamų paketų reikšmę. Dėl to bash liko vienas ir buvo nuspręsta golangu parašyti įvyniotuvą (analizatorius + agregatorius). Panašaus golango kodo procesoriaus suvartojimas yra 4–5 kartus mažesnis nei pats tsp procesas. Apvyniojimo pagreitis dėl bash pakeitimo golangu pasirodė maždaug 16 kartų ir apskritai rezultatas yra priimtinas (blogiausiu atveju procesoriaus apkrova 25%). Golang šaltinio failas yra čia.

Vykdykite įvyniojimą

Norėdami paleisti įvyniojimą, buvo sukurtas paprasčiausias sistemosd paslaugos šablonas (čia). Pats įvynioklis turėtų būti sukompiliuotas į dvejetainį failą (go build tsduck-stat.go), esantį /opt/tsduck-stat/. Daroma prielaida, kad naudojate golangą su monotoninio laikrodžio palaikymu (>=1.9).

Norėdami sukurti paslaugos egzempliorių, turite paleisti komandą systemctl enable [apsaugotas el. paštu]:1234 tada paleiskite su systemctl start [apsaugotas el. paštu]: 1234.

Atradimas iš Zabbix

Kad zabbix galėtų atrasti veikiančias paslaugas, tai daroma grupių sąrašų generatorius (discovery.sh), formatu, reikalingu Zabbix atradimui, daroma prielaida, kad jis yra toje pačioje vietoje - /opt/tsduck-stat. Norėdami paleisti atradimą naudodami „zabbix-agent“, turite pridėti .conf failą į zabbix-agent konfigūracijos katalogą, kad pridėtumėte vartotojo parametrą.

Zabbix šablonas

Sukurtas šablonas (tsduck_stat_template.xml) yra automatinio aptikimo taisyklė, elementų prototipai, grafikai ir aktyvikliai.

Trumpas kontrolinis sąrašas (na, o jei kas nors nuspręs jį naudoti)

  1. Įsitikinkite, kad tsp nepaleidžia paketų „idealiomis“ sąlygomis (generatorius ir analizatorius yra tiesiogiai sujungti), jei yra kritimų, žr. 2 dalį arba straipsnio tekstą šiuo klausimu.
  2. Nustatykite maksimalų lizdo buferį (net.core.rmem_max=8388608).
  3. Sukompiliuokite tsduck-stat.go (sukurkite tsduck-stat.go).
  4. Įdėkite paslaugos šabloną į /lib/systemd/system.
  5. Paleiskite paslaugas naudodami systemctl, patikrinkite, ar pradėjo pasirodyti skaitikliai (grep "" /dev/shm/tsduck-stat/*). Paslaugų skaičius pagal multicast srautų skaičių. Čia gali tekti sukurti maršrutą į multicast grupę, galbūt išjungti rp_filter arba sukurti maršrutą į šaltinio IP.
  6. Paleiskite discovery.sh ir įsitikinkite, kad jis sugeneruoja json.
  7. Pridėkite zabbix agento konfigūraciją, iš naujo paleiskite zabbix agentą.
  8. Įkelkite šabloną į zabbix, pritaikykite jį prie pagrindinio kompiuterio, kuris yra stebimas ir įdiegtas zabbix agentas, palaukite apie 5 minutes, pažiūrėkite, ar nėra naujų elementų, grafikų ir aktyviklių.

Rezultatas

TSDuck naudojimas IP (TS) srautams stebėti

Užduočiai aptikti paketų praradimą to beveik pakanka, bent jau geriau nei jokio stebėjimo.

Išties CC „nuostoliai“ gali atsirasti sujungiant vaizdo fragmentus (kiek žinau, taip daromi intarpai Rusijos Federacijos vietiniuose TV centruose, t.y. neperskaičiavus CC skaitiklio), tai reikia atsiminti. Patentuoti sprendimai iš dalies apeina šią problemą aptikdami SCTE-35 etiketes (jei jas pridėjo srauto generatorius).

Kalbant apie transporto kokybės stebėjimą, trūksta virpesių stebėjimo (IAT). TV įrangai (ar tai būtų moduliatoriai, ar galiniai įrenginiai) yra šio parametro reikalavimai ir ne visada įmanoma išpūsti jitbuferį iki begalybės. Ir drebėjimas gali sklisti, kai tranzitu naudojama įranga su dideliais buferiais, o QoS nėra sukonfigūruotas arba nepakankamai sukonfigūruotas tokiam srautui perduoti realiuoju laiku.

Šaltinis: www.habr.com

Добавить комментарий