Përdorimi i TSDuck për të monitoruar transmetimet IP(TS).

Sot, ekzistojnë zgjidhje të gatshme (të pronarit) për monitorimin e flukseve IP (TS), për shembull VB и iQ, ata kanë një grup mjaft të pasur funksionesh dhe zakonisht operatorët e mëdhenj që merren me shërbime televizive kanë zgjidhje të ngjashme. Ky artikull përshkruan një zgjidhje të bazuar në një projekt me burim të hapur TSDuck, i projektuar për kontroll minimal të flukseve IP(TS) duke përdorur numëruesin CC (kontinuiteti numërues) dhe shpejtësinë e biteve. Një aplikim i mundshëm është monitorimi i humbjes së paketave ose i gjithë rrjedhës përmes një kanali L2 me qira (i cili nuk mund të monitorohet normalisht, për shembull, duke lexuar numëruesit e humbjeve në radhë).

Shumë shkurt për TSDuck

TSDuck është softuer me burim të hapur (licencë BSD me 2 klauzola) (një grup shërbimesh të konsolës dhe një bibliotekë për zhvillimin e shërbimeve ose shtojcave tuaja) për manipulimin e transmetimeve TS. Si hyrje, mund të funksionojë me IP (multicast/unicast), http, hls, akordues dvb, demodulator dektec dvb-asi, ekziston një gjenerator i brendshëm i transmetimit TS dhe leximi nga skedarët. Dalja mund të jetë regjistrimi në një skedar, IP (multicast/unicast), hls, modulatorë dektec dvb-asi dhe HiDes, lojtarë (mplayer, vlc, xine) dhe drop. Midis hyrjes dhe daljes, mund të aktivizoni procesorë të ndryshëm trafiku, për shembull, rimarrëveshjen e PID-ve, bërjen e gërvishtjeve/përfshirjes, analizimin e numëruesve CC, llogaritjen e shpejtësisë së biteve dhe operacione të tjera tipike për transmetimet TS.

Në këtë artikull, IP streams (multicast) do të përdoren si hyrje, procesorë bitrate_monitor (nga emri është e qartë se çfarë është kjo) dhe procesorë të vazhdimësisë (CC counter analysis). Pa asnjë problem, mund të zëvendësoni IP multicast me një lloj tjetër hyrje të mbështetur nga TSDuck.

Në dispozicion ndërtime/pako zyrtare TSDuck për shumicën e OS aktuale. Nuk ka asnjë për Debian, por ne arritëm t'i përpilojmë ato për Debian 8 dhe Debian 10 pa asnjë problem.

Më pas, përdoret versioni TSDuck 3.19-1520, Linux përdoret si OS (debian 10 u përdor për të përgatitur zgjidhjen, CentOS 7 u përdor për përdorim aktual)

Përgatitja e TSDuck dhe OS

Përpara se të monitoroni flukset reale, duhet të siguroheni që TSDuck funksionon si duhet dhe që rëniet të mos ndodhin në nivelin e kartës së rrjetit ose të sistemit operativ (fole). Kjo kërkohet në mënyrë që të mos keni nevojë të merrni me mend më vonë se ku kanë ndodhur rëniet - në rrjet ose "brenda serverit". Mund të kontrolloni rëniet në nivelin e kartës së rrjetit me komandën ethtool -S ethX, akordimi bëhet nga i njëjti ethtool (zakonisht ju duhet të rritni bufferin RX (-G) dhe ndonjëherë të çaktivizoni disa shkarkime (-K)). Si rekomandim i përgjithshëm, këshillohet përdorimi i një porti të veçantë për të marrë trafikun e analizuar, nëse është e mundur, kjo do të minimizojë rezultatet false për faktin se rënia ka ndodhur njëkohësisht në portën e analizuesit për shkak të pranisë së trafikut tjetër. Nëse kjo nuk është e mundur (ju jeni duke përdorur një mini-kompjuter/NUC me një portë), atëherë është shumë e këshillueshme që të konfiguroni përparësinë e trafikut të analizuar në lidhje me pjesën tjetër në pajisjen në të cilën është lidhur analizuesi. Për sa i përket mjediseve virtuale, këtu duhet të jeni të kujdesshëm dhe të mund të gjeni paketat duke filluar nga porti fizik dhe duke përfunduar me aplikacionin brenda makinës virtuale.

Gjenerimi dhe marrja e një transmetimi brenda hostit

Si hap i parë në përgatitjen e TSDuck, ne do të gjenerojmë dhe marrim trafik brenda një hosti duke përdorur rrjeta.

Përgatitja e mjedisit:

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

Ambienti eshte gati. Hapni analizuesin e trafikut:

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

ku "-p 1 -t 1" do të thotë që ju duhet të llogaritni shpejtësinë e biteve çdo sekondë dhe të shfaqni informacione rreth shpejtësisë së biteve çdo sekondë
Ne lëshojmë një gjenerator trafiku me një shpejtësi prej 10 Mbit/s:

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

ku "-p 7 -e" do të thotë që ju duhet të paketoni 7 pako TS në 1 paketë IP dhe ta bëni atë me vështirësi (-e), d.m.th. gjithmonë prisni 7 pako TS nga procesori i fundit përpara se të dërgoni formimin e një pakete IP.

Analizuesi fillon të shfaqë mesazhet e pritura:

* 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

Tani le të shtojmë disa pika:

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

dhe shfaqen mesazhe si ky:

* 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 

që pritet. Ne çaktivizojmë humbjen e paketave (ip netns exec P iptables -F) dhe përpiqemi të rrisim shpejtësinë e biteve të gjeneratorit në 100 Mbit/s. Analizuesi raporton një sërë gabimesh CC dhe rreth 75 Mbit/s në vend të 100. Ne po përpiqemi të kuptojmë se kush është fajtori - gjeneratori nuk po vazhdon ose problemi nuk është në të, për ta bërë këtë fillojmë të gjenerojmë një numër fiks i paketave (700000 pako TS = 100000 paketa IP):

# 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

Siç mund ta shihni, u krijuan saktësisht 100000 paketa IP (151925460-151825460). Pra, kuptojmë se çfarë po ndodh me analizuesin, për ta bërë këtë kontrollojmë me numëruesin RX në veth1, është rreptësisht i barabartë me numëruesin TX në veth0, pastaj shikojmë se çfarë po ndodh në nivelin e prizës:

# 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 

Këtu mund të shihni numrin e rënieve = 24355. Në paketat TS kjo është 170485 ose 24.36% e 700000, kështu që ne shohim që të njëjtat 25% të shpejtësisë së humbur të biteve janë pika në folenë UDP. Rënia në një prizë UDP zakonisht ndodh për shkak të mungesës së tamponit, shikoni se cila është madhësia e paracaktuar e buferit të prizës dhe madhësia maksimale e buferit të prizës:

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

Kështu, nëse aplikacionet nuk kërkojnë në mënyrë eksplicite madhësinë e buferit, bazat krijohen me një bufer 208 KB, por nëse kërkojnë më shumë, ata përsëri nuk do të marrin atë që kërkuan. Meqenëse në tsp mund të vendosni madhësinë e buferit për hyrjen IP (--buffer-size), ne nuk do të prekim madhësinë e parazgjedhur të prizës, por do të vendosim vetëm madhësinë maksimale të buferit dhe do të specifikojmë madhësinë e buferit në mënyrë eksplicite përmes argumenteve tsp:

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

Me këtë akordim të tamponit të prizës, shpejtësia e biteve të raportuara tani është afërsisht 100 Mbps, nuk ka gabime CC.

Bazuar në konsumin e CPU-së nga vetë aplikacioni tsp. Për sa i përket një CPU me bërthamë i5-4260U @ 1.40 GHz, për të analizuar një rrjedhë 10 Mbit/s, do të kërkohet 3-4% e CPU-së, 100 Mbit/s - 25%, 200 Mbit/s - 46%. Kur vendosni % humbje të paketës, ngarkesa e CPU praktikisht nuk rritet (por mund të ulet).

Në pajisje më produktive, ishte e mundur të gjeneroheshin dhe analizoheshin rryma më shumë se 1 Gb/s pa asnjë problem.

Testimi në kartat reale të rrjetit

Pas testimit në një palë veth, duhet të merrni dy pritës ose dy porte të një hosti, të lidhni portat me njëra-tjetrën, të drejtoni gjeneratorin në një dhe analizuesin në të dytën. Këtu nuk kishte surpriza, por në fakt gjithçka varet nga hardueri, sa më i dobët të jetë, aq më interesant do të jetë këtu.

Përdorimi i të dhënave të marra nga sistemi i monitorimit (Zabbix)

tsp nuk ka ndonjë API të lexueshme nga makina si SNMP ose të ngjashme. Mesazhet CC duhet të grumbullohen të paktën 1 sekondë në të njëjtën kohë (me një përqindje të lartë të humbjes së paketave, mund të ketë qindra/mijëra/dhjetëra mijëra në sekondë, në varësi të shpejtësisë së biteve).

Kështu, për të ruajtur informacionin dhe për të vizatuar grafikë për gabimet CC dhe shpejtësinë e biteve dhe për të bërë disa lloj aksidentesh më tej, mund të ketë opsionet e mëposhtme:

  1. Analizoni dhe grumbulloni (nga CC) prodhimin e tsp, d.m.th. ta shndërrojë atë në formën e dëshiruar.
  2. Shto vetë lugën dhe/ose shtojcat bitrate_monitor dhe procesor të vazhdimësisë në mënyrë që rezultati të dalë në një formë të lexueshme nga makina, e përshtatshme për sistemin e monitorimit.
  3. Shkruani aplikacionin tuaj në krye të bibliotekës tsduck.

Natyrisht, për sa i përket kostove të punës, opsioni 1 është më i thjeshti, veçanërisht duke pasur parasysh që vetë tsduck është shkruar në një gjuhë të nivelit të ulët (sipas standardeve moderne) (C++)

Një prototip i thjeshtë i një analizuesi + grumbulluesi në bash tregoi se me një fluks prej 10 Mbit/s dhe 50% humbje të paketave (rasti më i keq), procesi bash konsumonte 3-4 herë më shumë CPU sesa vetë procesi i tsp. Ky skenar është i papranueshëm. Në fakt një pjesë e këtij prototipi është më poshtë

Petë mbi basha

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

Përveç faktit që kjo funksionon në mënyrë të papranueshme ngadalë, nuk ka fije normale në bash, punët e bash janë procese të pavarura dhe më duhej të shkruaja vlerën e missingPackets një herë në sekondë në efektin anësor (kur merrja mesazhe të shpejtësisë së biteve që vijnë çdo sekondë). Si rezultat, bash mbeti vetëm dhe u vendos që të shkruhet një mbështjellës (parser + grumbullues) në golang. Konsumi i CPU-së i kodit të ngjashëm në golang është 4-5 herë më pak se vetë procesi i tsp. Përshpejtimi i mbështjellësit duke zëvendësuar bash-in me golang ishte afërsisht 16 herë dhe në përgjithësi rezultati është i pranueshëm (përmbushja e CPU-së me 25% në rastin më të keq). Skedari burimor golang ndodhet këtu.

Lëshimi i mbështjellësit

Për të nisur mbështjellësin, u krijua një model i thjeshtë shërbimi për systemd (këtu). Supozohet se vetë mbështjellësi është përpiluar në një skedar binar (shko ndërto tsduck-stat.go), i vendosur në /opt/tsduck-stat/. Supozohet se golang përdoret me mbështetje monotonike të orës (>=1.9).

Për të krijuar një shembull shërbimi, duhet të ekzekutoni komandën systemctl enable [email mbrojtur]:1234, pastaj ekzekuto me systemctl start [email mbrojtur]: 1234.

Zbulimi nga Zabbix

Kështu që zabbix mund të bëjë një zbulim të shërbimeve të funksionimit, gjenerator i listës së grupeve (discovery.sh), në formatin e kërkuar për zbulimin e Zabbix, supozohet se ndodhet në të njëjtin vend - në /opt/tsduck-stat. Për të ekzekutuar zbulimin nëpërmjet zabbix-agent, duhet të shtoni skedar .conf në drejtorinë me konfigurime zabbix-agent për të shtuar një parametër përdoruesi.

Shablloni Zabbix

Modeli i krijuar (tsduck_stat_template.xml) përmban rregullin e zbulimit automatik, elementin, grafikun dhe prototipet e aktivizimit.

Një listë kontrolli e shkurtër (po nëse dikush vendos ta përdorë atë)

  1. Sigurohuni që tsp të mos lëshojë paketa në kushte "ideale" (gjeneratori dhe analizuesi janë të lidhur drejtpërdrejt), nëse ka pika, shihni pikën 2 ose tekstin e artikullit për këtë çështje.
  2. Bëni akordim të bufferit maksimal të prizës (net.core.rmem_max=8388608).
  3. Përpiloni tsduck-stat.go (shko ndërto tsduck-stat.go).
  4. Vendosni shabllonin e shërbimit në /lib/systemd/system.
  5. Filloni shërbimet duke përdorur systemctl, kontrolloni që numëruesit kanë filluar të shfaqen (grep "" /dev/shm/tsduck-stat/*). Numri i shërbimeve sipas numrit të transmetimeve multicast. Këtu mund t'ju duhet të krijoni një rrugë drejt grupit multicast, ndoshta çaktivizoni rp_filter ose krijoni një rrugë drejt IP-së së burimit.
  6. Ekzekutoni Discovery.sh, sigurohuni që të gjenerojë json.
  7. Vendosni konfigurimin e agjentit zabbix, rinisni agjentin zabbix.
  8. Ngarkoni shabllonin në zabbix, aplikojeni atë te hosti në të cilin kryhet monitorimi dhe është instaluar zabbix-agent, prisni rreth 5 minuta, shikoni që janë shfaqur elementë të rinj të të dhënave, grafikë dhe aktivizues.

Result

Përdorimi i TSDuck për të monitoruar transmetimet IP(TS).

Për detyrën e identifikimit të humbjes së paketave, është pothuajse e mjaftueshme, të paktën është më mirë se pa monitorim.

Në fakt, "humbjet" e CC mund të ndodhin kur bashkohen fragmente video (me sa di unë, kështu bëhen futjet në qendrat televizive lokale në Federatën Ruse, d.m.th. pa rillogaritur numëruesin CC), kjo duhet mbajtur mend. Në zgjidhjet e pronarit, ky problem anashkalohet pjesërisht duke zbuluar etiketat SCTE-35 (nëse ato shtohen nga gjeneratori i transmetimit).

Nga pikëpamja e monitorimit të cilësisë së transportit, monitorimi i nervozizmit (IAT) nuk mjafton, sepse Pajisjet televizive (qofshin modulatorët apo pajisjet fundore) kanë kërkesa për këtë parametër dhe nuk është gjithmonë e mundur të fryhet jitbuffer për një kohë të pacaktuar. Dhe nervozizmi mund të notojë kur transporti përdor pajisje me bufera të mëdhenj dhe QoS nuk është i konfiguruar ose nuk është konfiguruar mjaftueshëm për të transmetuar një trafik të tillë në kohë reale.

Burimi: www.habr.com

Shto një koment