Օգտագործելով TSDuck IP (TS) հոսքերը մոնիտորինգի համար

Այսօր կան IP(TS) հոսքերի մոնիտորինգի պատրաստի (գույքային) լուծումներ, օրինակ. VB и iQ, նրանք ունեն բավականին հարուստ գործառույթներ և սովորաբար հեռուստատեսային ծառայություններով զբաղվող խոշոր օպերատորներն ունեն նման լուծումներ։ Այս հոդվածը նկարագրում է լուծում, որը հիմնված է բաց կոդով նախագծի վրա TSDuck, նախատեսված է IP(TS) հոսքերի նվազագույն վերահսկման համար CC (շարունակականության հաշվիչի) հաշվիչի և բիթերի արագության միջոցով: Հնարավոր կիրառություն է վերահսկել փաթեթների կորուստը կամ ամբողջ հոսքը վարձակալված L2 ալիքով (որը չի կարող սովորաբար վերահսկվել, օրինակ՝ հերթերում կորուստների հաշվիչները կարդալով):

Շատ հակիրճ TSDuck-ի մասին

TSDuck-ը բաց կոդով (2 կետ BSD լիցենզիա) ծրագրային ապահովում է (վահանակով կոմունալ ծառայությունների մի շարք և անհատական ​​կոմունալ ծառայություններ կամ պլագիններ մշակելու գրադարան) TS հոսքերը շահարկելու համար: Որպես մուտքագրում, այն կարող է աշխատել IP-ով (multicast/unicast), http, hls, dvb թյուներներով, dektec dvb-asi դեմոդուլյատորով, կա ներքին TS-stream գեներատոր և ֆայլերից ընթերցում: Արդյունքը կարող է լինել ֆայլի վրա գրել, IP (multicast/unicast), hls, dektec dvb-asi և HiDes մոդուլատորներ, նվագարկիչներ (mplayer, vlc, xine) և թողնել: Տարբեր երթևեկության պրոցեսորներ կարող են ներառվել մուտքի և ելքի միջև, օրինակ՝ PID remapping, scrambling/descrambling, CC հաշվիչի վերլուծություն, բիթային արագության հաշվարկ և այլ բնորոշ գործողություններ TS հոսքերի համար:

Այս հոդվածում IP հոսքերը (multicast) կօգտագործվեն որպես մուտքագրում, կօգտագործվեն պրոցեսորները bitrate_monitor (անունից պարզ է, թե ինչ է դա) և շարունակականությունը (CC հաշվիչների վերլուծություն): Դուք կարող եք հեշտությամբ փոխարինել IP multicast-ը TSDuck-ի կողմից աջակցվող մուտքագրման այլ տեսակով:

Հասանելի է պաշտոնական կառուցումներ/փաթեթներ TSDuck ընթացիկ օպերացիոն համակարգերի մեծ մասի համար: Դրանք հասանելի չեն Debian-ի համար, բայց մենք կարողացանք դրանք կառուցել debian 8-ի և debian 10-ի տակ առանց որևէ խնդիրների:

Հաջորդը, օգտագործվում է TSDuck 3.19-1520 տարբերակը, Linux-ն օգտագործվում է որպես ՕՀ (լուծումը պատրաստելու համար օգտագործվել է debian 10, իրական օգտագործման համար օգտագործվել է CentOS 7)

TSDuck-ի և OS-ի պատրաստում

Նախքան իրական հոսքերի մոնիտորինգը, դուք պետք է համոզվեք, որ TSDuck-ը ճիշտ է աշխատում, և ցանցային քարտի կամ ՕՀ-ի (վարդակից) մակարդակում անկումներ չկան: Սա պահանջվում է, որպեսզի հետագայում չկռահեք, թե որտեղ են տեղի ունեցել անկումները՝ ցանցում կամ «սերվերի ներսում»: Դուք կարող եք ստուգել կաթիլները ցանցային քարտի մակարդակում ethtool -S ethX հրամանով, թյունինգը կատարվում է նույն ethtool-ի միջոցով (սովորաբար, դուք պետք է մեծացնեք RX բուֆերը (-G) և երբեմն անջատեք որոշ բեռնաթափումներ (-K)): Որպես ընդհանուր առաջարկ, կարելի է խորհուրդ տալ օգտագործել առանձին նավահանգիստ վերլուծված թրաֆիկը ստանալու համար, եթե դա հնարավոր է, դա նվազագույնի է հասցնում կեղծ դրական տվյալները, որոնք կապված են այն փաստի հետ, որ անկումը տեղի է ունեցել հենց անալիզատորի նավահանգստի վրա՝ այլ տրաֆիկի առկայության պատճառով: Եթե ​​դա հնարավոր չէ (օգտագործվում է մեկ պորտով մինի-համակարգիչ/NUC), ապա շատ ցանկալի է կարգավորել վերլուծված տրաֆիկի առաջնահերթությունը մնացածի նկատմամբ սարքի վրա, որին միացված է անալիզատորը: Ինչ վերաբերում է վիրտուալ միջավայրերին, ապա այստեղ դուք պետք է զգույշ լինեք և կարողանաք գտնել փաթեթների կաթիլներ՝ սկսած ֆիզիկական պորտից և վերջացրած հավելվածով վիրտուալ մեքենայի ներսում:

Հոսքի ստեղծում և ընդունում հաղորդավարի ներսում

Որպես TSDuck-ի պատրաստման առաջին քայլ՝ մենք կստեղծենք և կստանանք տրաֆիկ մեկ հոսթի ներսում՝ օգտագործելով ցանցերը:

Շրջակա միջավայրի պատրաստում.

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

Միջավայրը պատրաստ է։ Մենք սկսում ենք երթևեկության անալիզատորը.

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

որտեղ «-p 1 -t 1» նշանակում է, որ դուք պետք է հաշվարկեք բիթային արագությունը ամեն վայրկյան և ցուցադրեք տեղեկատվություն բիթերի արագության մասին ամեն վայրկյան:
Մենք գործարկում ենք երթևեկության գեներատորը 10 Մբ/վ արագությամբ.

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

որտեղ «-p 7 -e» նշանակում է, որ դուք պետք է փաթեթավորեք 7 TS փաթեթ 1 IP փաթեթի մեջ և դա անեք դժվար (-e), այսինքն. Միշտ սպասեք 7 TS փաթեթ վերջին պրոցեսորից մինչև IP փաթեթ ուղարկելը:

Անալիզատորը սկսում է թողարկել սպասվող հաղորդագրությունները.

* 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

Այժմ ավելացրեք մի քանի կաթիլ.

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

և հայտնվում են այսպիսի հաղորդագրություններ.

* 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 

որը սպասվում է. Անջատեք փաթեթների կորուստը (ip netns exec P iptables -F) և փորձեք բարձրացնել գեներատորի բիթային արագությունը մինչև 100 Մբիթ/վրկ: Անալիզատորը հաղորդում է CC սխալների մի փունջ և մոտ 75 Մբիթ/վրկ՝ 100-ի փոխարեն: Մենք փորձում ենք պարզել, թե ով է մեղավոր. գեներատորը ժամանակ չունի, կամ խնդիրը դրա մեջ չէ, դրա համար մենք սկսում ենք ֆիքսված քանակի արտադրություն: փաթեթներ (700000 TS փաթեթ = 100000 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

Ինչպես տեսնում եք, գեներացվել է ուղիղ 100000 IP փաթեթ (151925460-151825460): Այսպիսով, եկեք պարզենք, թե ինչ է կատարվում անալիզատորի հետ, դրա համար մենք ստուգում ենք RX հաշվիչով veth1-ի վրա, այն խստորեն հավասար է veth0-ի TX հաշվիչին, այնուհետև մենք նայում ենք, թե ինչ է տեղի ունենում վարդակից մակարդակում.

# 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 

Այստեղ դուք կարող եք տեսնել կաթիլների թիվը = 24355: TS փաթեթներում սա 170485 է կամ 24.36-ի 700000%-ը, ուստի մենք տեսնում ենք, որ կորցրած բիթերի նույն 25%-ը կաթիլներ են udp վարդակից: UDP վարդակից անկումներ սովորաբար տեղի են ունենում բուֆերի բացակայության պատճառով, դիտեք լռելյայն վարդակից բուֆերի չափը և վարդակից բուֆերի առավելագույն չափը.

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

Այսպիսով, եթե հավելվածները բացահայտորեն չեն պահանջում բուֆերի չափ, վարդակներ են ստեղծվում 208 ԿԲ բուֆերով, բայց եթե նրանք ավելի շատ պահանջեն, նրանք դեռ չեն ստանա այն, ինչ պահանջվել է: Քանի որ դուք կարող եք սահմանել բուֆերի չափը tsp-ով IP մուտքագրման համար (-buffer-size), մենք չենք շոշափի լռելյայն վարդակի չափը, այլ միայն կսահմանենք բուֆերի առավելագույն չափը և հստակորեն նշեք բուֆերի չափը 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

Socket buffer-ի այս թյունինգով այժմ հաղորդված բիթային արագությունը մոտ 100 Մբ/վ է, CC սխալներ չկան:

Համաձայն ինքնին tsp հավելվածի պրոցեսորի սպառման: Մեկ միջուկային i5-4260U CPU @ 1.40GHz-ի համեմատ, 10Mbps հոսքի վերլուծությունը կպահանջի 3-4% CPU, 100Mbps՝ 25%, 200Mbps՝ 46%: % Packet Loss-ը սահմանելիս պրոցեսորի բեռը գործնականում չի ավելանում (բայց կարող է նվազել):

Ավելի արդյունավետ սարքավորումների վրա հնարավոր եղավ առանց որևէ խնդիրների առաջացնել և վերլուծել 1 Գբ/վ-ից ավելի հոսքեր:

Փորձարկում իրական ցանցային քարտերի վրա

Veth զույգի վրա փորձարկումից հետո դուք պետք է վերցնեք երկու հոսթ կամ մեկ հոսթի երկու պորտ, միացնեք պորտերը միմյանց, գործարկեք գեներատորը մեկի վրա, իսկ անալիզատորը երկրորդի վրա: Այստեղ անակնկալներ չկային, բայց իրականում ամեն ինչ կախված է երկաթից, որքան թույլ, այնքան հետաքրքիր կլինի այստեղ։

Մոնիտորինգի համակարգի կողմից ստացված տվյալների օգտագործումը (Zabbix)

tsp-ն չունի մեքենայաընթեռնելի API, ինչպիսին է SNMP-ը կամ նմանատիպը: CC հաղորդագրությունները պետք է հավաքվեն առնվազն 1 վայրկյանի ընթացքում (փաթեթների կորստի բարձր տոկոսի դեպքում կարող են լինել հարյուր/հազարներ/տասնյակ հազարներ վայրկյանում՝ կախված բիթերի արագությունից):

Այսպիսով, ինչպես տեղեկատվությունը պահպանելու, այնպես էլ CC սխալների և բիթերի արագության գրաֆիկներ գծելու և ինչ-որ տեսակի վթարներ կատարելու համար կարող են լինել հետևյալ տարբերակները.

  1. Վերլուծեք և համախմբեք (ըստ CC) թեյի գդալի ելքը, այսինքն. փոխարկել այն ցանկալի ձևին:
  2. Ավարտեք tsp ինքնին և/կամ պրոցեսորի պլագինները bitrate_monitor և continuity, որպեսզի արդյունքը տրվի մեքենայական ընթեռնելի ձևով, որը հարմար է մոնիտորինգի համակարգի համար:
  3. Գրեք ձեր դիմումը tsduck գրադարանի վերևում:

Ակնհայտ է, որ 1-ին տարբերակը ամենահեշտն է աշխատուժի ծախսերի առումով, հատկապես հաշվի առնելով, որ tsduck-ն ինքնին գրված է ցածր մակարդակի (ժամանակակից չափանիշներով) լեզվով (C ++)

Պարզ bash վերլուծիչ+ագրեգատորի նախատիպը ցույց տվեց, որ 10 Մբիթ/վրկ հոսքի և 50% փաթեթի կորստի դեպքում (վատագույն դեպքում), bash պրոցեսը սպառում է 3-4 անգամ ավելի շատ CPU, քան բուն tsp պրոցեսը: Այս սցենարն անընդունելի է. Իրականում այս նախատիպի մի կտոր ստորև

Լապշա վերևում

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

Բացի անընդունելի դանդաղ լինելուց, bash-ում նորմալ թելեր չկան, bash-ի աշխատանքները առանձին պրոցեսներ են, և ես ստիպված էի վայրկյանը մեկ անգամ գրել missingPackets-ի արժեքը կողմնակի էֆեկտի վրա (երբ ամեն վայրկյան գալիս են բիթային հաղորդագրություններ): Արդյունքում բաշը մնաց մենակ և որոշվեց գոլանգով գրել փաթաթան (վերլուծիչ + ագրեգատոր): Նմանատիպ գոլանգի կոդերի պրոցեսորի սպառումը 4-5 անգամ ավելի քիչ է, քան թեյի գդալ պրոցեսը: Բաշը գոլանգով փոխարինելու պատճառով փաթաթման արագացումը մոտ 16 անգամ է ստացվել և ընդհանուր առմամբ արդյունքը ընդունելի է (Վատագույն դեպքում պրոցեսորի գերբեռնվածությունը 25%-ով): Գոլանգի աղբյուրի ֆայլը գտնվում է այստեղ.

Run փաթաթան

Փաթաթումը սկսելու համար ստեղծվել է systemd-ի սպասարկման ամենապարզ ձևանմուշը (այստեղ) Ենթադրվում է, որ փաթաթանն ինքնին պետք է կազմվի երկուական ֆայլի մեջ (go build tsduck-stat.go), որը գտնվում է /opt/tsduck-stat/-ում: Ենթադրվում է, որ դուք օգտագործում եք գոլանգ՝ միատոն ժամացույցի աջակցությամբ (>=1.9):

Ծառայության օրինակ ստեղծելու համար անհրաժեշտ է գործարկել systemctl enable հրամանը [էլեկտրոնային փոստով պաշտպանված]:1234, ապա գործարկեք systemctl start-ով [էլեկտրոնային փոստով պաշտպանված]: 1234.

Հայտնագործություն Zabbix-ից

Որպեսզի zabbix-ը կարողանա բացահայտել գործող ծառայությունները, դա արված է խմբային ցուցակի գեներատոր (discovery.sh), Zabbix-ի հայտնաբերման համար անհրաժեշտ ձևաչափով ենթադրվում է, որ այն գտնվում է նույն տեղում՝ /opt/tsduck-stat-ում: Զաբբիքս գործակալի միջոցով հայտնաբերումը գործարկելու համար անհրաժեշտ է ավելացնել .conf ֆայլ zabbix-agent-ի կազմաձևման գրացուցակին` օգտվողի պարամետրը ավելացնելու համար:

Zabbix ձևանմուշ

Ստեղծված ձևանմուշ (tsduck_stat_template.xml) պարունակում է ինքնաբացահայտման կանոնը, տարրերի նախատիպերը, գրաֆիկները և գործարկիչները:

Համառոտ ստուգաթերթ (դե ինչ, եթե ինչ-որ մեկը որոշի օգտագործել այն)

  1. Համոզվեք, որ tsp-ը փաթեթներ չի գցում «իդեալական» պայմաններում (գեներատորը և անալիզատորը ուղղակիորեն միացված են), եթե կաթիլներ կան, տես 2-րդ պարբերությունը կամ այս հարցի վերաբերյալ հոդվածի տեքստը:
  2. Կարգավորեք առավելագույն վարդակից բուֆերը (net.core.rmem_max=8388608):
  3. Կազմել tsduck-stat.go (գնալ կառուցել tsduck-stat.go):
  4. Տեղադրեք ծառայության ձևանմուշը /lib/systemd/system-ում:
  5. Սկսեք ծառայությունները օգտագործելով systemctl, ստուգեք, որ հաշվիչներն սկսել են հայտնվել (grep "" /dev/shm/tsduck-stat/*): Ծառայությունների քանակը բազմակի հեռարձակման հոսքերի քանակով: Այստեղ կարող է անհրաժեշտ լինել ստեղծել երթուղի դեպի multicast խումբ, միգուցե անջատել rp_filter-ը կամ ստեղծել երթուղի դեպի աղբյուրի ip:
  6. Գործարկեք Discovery.sh-ը, համոզվեք, որ այն առաջացնում է json:
  7. Ավելացնել zabbix agent config, վերագործարկել zabbix գործակալը:
  8. Վերբեռնեք ձևանմուշը zabbix-ում, կիրառեք այն հոսթի վրա, որը վերահսկվում է, և zabbix-agent-ը տեղադրված է, սպասեք մոտ 5 րոպե, տեսեք, թե արդյոք կան նոր տարրեր, գրաֆիկներ և գործարկիչներ:

Արդյունք

Օգտագործելով TSDuck IP (TS) հոսքերը մոնիտորինգի համար

Փաթեթների կորուստը հայտնաբերելու համար դա գրեթե բավարար է, համենայնդեպս դա ավելի լավ է, քան մոնիտորինգի բացակայությունը:

Իրոք, CC «կորուստները» կարող են առաջանալ վիդեո դրվագների միաձուլման ժամանակ (որքանով ես գիտեմ, այսպես են ներդիրները պատրաստվում Ռուսաստանի Դաշնության տեղական հեռուստակենտրոններում, այսինքն՝ առանց CC հաշվիչը վերահաշվարկելու), սա պետք է հիշել: Սեփական լուծումները մասամբ շրջանցում են այս խնդիրը՝ հայտնաբերելով SCTE-35 պիտակները (եթե ավելացվել է հոսքի գեներատորի կողմից):

Տրանսպորտի որակի մոնիթորինգի առումով պակասում է jitter monitoring-ը (IAT): Հեռուստատեսային սարքավորումները (լինի դա մոդուլյատորներ կամ վերջնական սարքեր) ունի պահանջներ այս պարամետրի համար, և միշտ չէ, որ հնարավոր է ջիթբուֆերը փչել մինչև անսահմանություն: Եվ ջիթերը կարող է լողալ, երբ մեծ բուֆերներով սարքավորումն օգտագործվում է տարանցման ժամանակ, և QoS-ը կազմաձևված չէ կամ այնքան լավ կազմաձևված չէ, որպեսզի փոխանցի նման իրական ժամանակի տրաֆիկը:

Source: www.habr.com

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