Այսօր արդեն գոյություն ունեն պատրաստի (պրոպրիետար) լուծումներ IP(TS) հոսքերի մոնիթորինգի համար, օրինակ, և ։ Դրանք ունեն բավականին հարուստ ֆունկցիոնալություն, և նման լուծումները սովորաբար առաջարկում են մեծ օպերատորները, որոնք աշխատում են հեռուստա ծառայությունների վրա։ Այս հոդվածում նկարագրվում է բաց աղբյուրի նախագծի վրա հիմնված լուծում, ։ Այն նախատեսված է IP(TS) հոսքերի նվազագույն վերահսկողության համար՝ CC (continuity counter) հաշվիչով և բիթռեյթով վերահսկելու համար։ Օգտագործման հնարավոր տարբերակը՝ փ paketներ կամ ամբողջ հոսքը վերահսկել վարձակալված L2 ալիքով (որն ակնհայտորեն հնարավոր չէ պատշաճ մոնիթորինգ անել, օրինակ, կորստի հաշվիչներն ընթերցելով ճանապարհներին):
Շատ կարճ տեղեկատվություն TSDuck-ի մասին
TSDuck-ը բաց կոդով (2-Clause BSD լիցենզիայով) ծրագիր է (կոնսոլային օգտակար ծրագրերի հավաքածու և սեփական օգտակար ծրագրերի կամ պլագինների մշակման գրադարան) TS հոսքերի հետ աշխատելու համար։ Այն կարող է ընդունել IP (multicast/unicast), http, hls, dvb-թալարներ, dektec dvb-asi դեմոդուլատորը, ունի ներքին TS հոսքի գեներատոր և հանված ֆայլերից ընթերցման հնարավորություն։ Արտահոսքը կարող է լինել գրություն ֆայլում, IP (multicast/unicast), hls, dektec dvb-asi և HiDes մոդուլատորներ, խաղացողներ (mplayer, vlc, xine) և drop: Ներդրման և արտահոսի միջև կարելի է ներդնել տարբեր երթի վերամատուցողներ, օրինակ, PID-ների վերամուտ, սքրեմբլավորում/դեսքրեմբլավորում, CC հաշվիչների վերլուծություն, բիթռեյթի հաշվարկի համարը և մյուս ավանդական TS հոսքերի գործողությունները։
Այս հոդվածում որպես մուտք օգտագործվելու են IP հոսքեր (multicast), օգտագործվում են bitrate_monitor (անգամ անունից պարզ է, թե ինչ է) և continuity (CC հաշվիչների վերլուծություն) պրոցեսորները։ Ինտեգրված խնդիրների մեծամասնությունը կարելի է հեշտությամբ փոխարինել IP multicast-ով այլ մուտքային տեսակով, որը TSDuck-ը աջակցում է։
Կա TSDuck-ի համար հիմնական գործող համակարգերի համար։ Debian-ի համար չկա, բայց առանց խնդիրների հաջողվեց հավաքել debian 8 և debian 10-ի համար։
Հետագայում օգտագործվում է TSDuck 3.19-1520 տարբերակը, որպես OS օգտագործվում է Linux (լուծման պատրաստման համար օգտագործվել է debian 10, իսկ իրական օգտագործման համար՝ CentOS 7)
TSDuck և OS պատրաստում
Նախքան իրական հոսքերի մոնիտորինգը, պետք է համոզվեք, որ TSDuck-ը կոռեկտ գործում է և ցանցային քարտի կամ OS-ի (սոկետի) մակարդակում չկա բաժանումներ: Սա անհրաժեշտ է, որպեսզի այնուհետև չսպասեք, թե որտեղ են կատարվել բաժանումները՝ ցանցում թե «ծանրաբեռնված» սերվերում: Ցանցային քարտի մակարդակում բաժանումները ստուգելու համար կարելի է օգտագործել ethtool -S ethX հրամանը, կարգավորումներն արեք նույն ethtool-ով (անհրաժեշտ է մեծացնել RX-բուֆերը (-G) և երբեմն անջատել որոշ offloads (-K)): Ընդհանուր խորհուրդը կարող է լինել, որ օգտագործեք առանձին պորտ՝ վերլուծվող տրաֆիկի ընդունման համար, եթե այդպիսի հնարավորություն կա, սա կնվազեցնի հFalse alarms, որոնք կապված են միաժամանակյա վերլուծողի պորտում մյուս տրաֆիկի ներկայության պատճառով: Եթե այսպիսի հնարավորություն չկա (օգտագործվում է մինի-համակարգիչ/NUC մեկ պորտով), ապա շատ ցանկալի է կարգավորել վերլուծվող տրաֆիկի գերակայությունը այլ տրաֆիկի նկատմամբ այդ устройстве, որը միանում է վերլուծիչին: Վիրտուալ միջավայրերի մասին պետք է լինել զգույշ և իմանալ՝ ինչպես գտնել փաթեթի բաժանումները ֆիզիկական պորտից սկսած մինչև վիրտուալ մեքենայի ներսում գտնվող հավելվածը:
Հոսքի արտադրություն և ընդունում հոսթի ներսում
TSDuck-ի նախապատրաստման առաջին քայլով մենք կարտադրենք և կընդունենք տրաֆիկը մեկ հոսթում՝ օգտագործելով netns:
Պատրաստում ենք միջավայրը:
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 #կարգավորում ենք կանխորոշված երթուղին netns 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 #ստեղծում ենք երթուղի, որպեսզի OS-ը ուղղի տրաֆիկը 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, он строго равен счётчику TX на veth0, далее смотрим что происходит на уровне сокета:
# 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Այսպիսի բուֆերային կարգավորումով այժմ հաղորդվող битрейт-ը կազմում է մոտ 100Մբիտ/վրկ, CC-սխալներ չկան:
CPU սպառումը ինչպես նաև tsp ծրագրի կողմից: i5-4260U CPU @ 1.40GHz-ի մեկ ядրի համար, 10Մբիտ/վրկ հոսքի վերլուծության համար պահանջվում է 3-4% CPU, 100 Մբիտ/վրկ — 25%, 200Մբիտ/վրկ — 46%: Փաթեթների կորուստի % սահմանելով CPU-ի բեռը զուտ չի ավելանում (բայց կարող է նվազել):
Բարձր արտադրողական մեքենաների մեջ առանց խնդիրներ ստեղծելու հաջողվում էր արտադրել և վերլուծել հոսքեր նույնպես 1Գբ/վրկ-ից:
Բ reais сетевые карты тестирование
veth-զույգով փորձարկումից հետո հարկավոր է վերցնել երկու հոսանք կամ մեկ հոսանքի երկու պորտ, միացնել պորտերը իրար, մեկում սկսել գեներատոր, մյուսում՝ վերլուծիչ: Այստեղ անսպասելի բաներ տեղի չունեցան, բայց իրականում ամեն բան կախված է տեխնիկայից, որքան իսպաներեն ընտրանքային է, այնքան ավելի հետաքրքիր կլինի այստեղ:
Ամփոփման տված տեղեկությունները դիտարկման համակարգով (Zabbix)
tsp-ում չունի որևէ machine-readable API, օրինակ՝ SNMP կամ նման մի բան: CC հաղորդագրությունները անհրաժեշտ է հավաքել գոնե 1 վարկյանի համար (բարձր կորուստների դեպքում դրանք կարող են լինել հարյուրների/հազարավոր/տասնյակ հազարավոր վարկյան մեկ, կախված битрейт-ից):
Այսպիսով, CC-գործողությունների և բիթռեյթի մասին տեղեկատվություն պահպանելու և գրաֆիկներ նկարելու համար հնարավոր են հետևյալ տարբերակները:
- Վերլուծել և հավաքագրել (CC-ի միջոցով) tsp-ի դարձրը, սովորական ձևի փոխակերպումը:
- Բազմակողմանի լրացնել tsp-ը և/կամ բիթռեյթի մոնիթոր և շարունակական ծրագրակազմերը, որպեսզի արդյունքը ստացվի մեքենայական ընթերցման ձևով, որ հնարավոր լինի մոնիթորինգի համակարգում:
- Հ écrire ինքնուրույն ծրագիր 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-ը թողեց հանգիստ և որոշվեց գրել wrapper (ապահով և հավաքագրող) golang-ում: CPU-ի սպառման նման կոդը golang-ում 4-5 անգամ քիչ է կախված ամենամեծ tsp պրոցեսից: Wrapper-ի արագացումը փոխարինելով bash-ը golang-ով մոտ 16 անգամ դարձավ և ընդհանուր արդյունքը ընդունելի է (CPU-ի ավելաքանակը 25% ամենափոքր իրավիճակում): Նախնական ֆայլը golang-ում գտնվում է: .
Wrapper-ի գործարկում
Wrapper-ի գործարկման համար պարզ սերվիսի ձևանմուշ է պատրաստվել systemd-ի համար (). Հնարավոր է, որ wrapper-ը կոմպիլացվել է բինարային ֆայլի (go build tsduck-stat.go) մեջ, որը տեղադրված է /opt/tsduck-stat/: Հնարավոր է, որ օգտագործվում է golang, որը աջակցում է monotonic ժամացույցի (>=1.9):
Ապահովելու համար, որ ծառայության օրինակ ստեղծելու համար պետք է կատարեք systemctl enable tsduck-stat@239.0.0.1:1234 հրամանը, ապա սկսել systemctl start tsduck-stat@239.0.0.1:1234 միջոցով:
Zabbix-ի հայտնաբերում
Որպեսզի zabbix-ը կարողանա հայտնաբերել աշխատող ծառայությունները, պատրաստել է (discovery.sh), որը Zabbix-ի յուրօրինակ թույլտվության ձևն է, ենթադրվում է, որ այն տեղադրված է նույն տեղում — /opt/tsduck-stat-ում: Ձևավորելու համար հայտնաբերման zabbix-agent-ի միջոցով, պետք է ավելացնել zabbix-agent-ի կոնֆիգուրացման տարրերում, որպեսզի ավելացնել user-parametրը:
Zabbix-ի ձևանմուշ
(tsduck_stat_template.xml) պարունակում է ավտո-հայտնաբերման կանոն, տվյալների տարրերի, գրաֆիկների և առաջացումների նախատիպեր:
Հակիրճ վերահսկիչ ցուցակ (նվազագույնը, եթե մեկ անձ ուզում է օգտագործել)
- Հավաստիանալ, որ tsp-ն չդորաբերում բռնկումներ «հիանալի» պայմաններում (աստվածաշնչները և վերլուծողը միանգամայն ուղղակիորեն լուծված են), եթե կան բռնկումներ, տեսեք համար 2 կամ այդ մասին հոդվածը:
- Արտահանել մաքսիմալ սոկետի բուֆերի (net.core.rmem_max=8388608) կարգավորումը:
- Կոմպիլացնել tsduck-stat.go (go build tsduck-stat.go):
- Տրանսֆերել ծառայության շաբլոնը դեպի /lib/systemd/system:
- Անչափել ծառայությունները systemctl-ով, ստուգել, որ թվիչները հայտնվում են (grep «» /dev/shm/tsduck-stat/*): Ծառայությունների քանակը լինում է մուլտիկաստական հոսքերի քանակով: Այստեղ հնարավոր է, որ պետք լինի ստեղծել երթուղի դեպի մուլտիկաստային խումբ, հնարավոր է отключить rp_filter կամ ստեղծել երթուղի դեպի source ip:
- Սկսել discovery.sh, համոզվել, որ այն ստեղծում է json:
- Բեռնել zabbix-ագենց, նորից սկսեք zabbix-ագենտը.
- Բեռնել շաբլոնը zabbix-ում, կիրառել այն այն հոստի վրա, որտեղ կատարվում է մոնիտորինգ և տեղադրված է zabbix-agent, սպասել մոտ 5 րոպե, դիտել, թե արդյոք նոր տվյալների տարրեր, գալարներ և հեծանիվներ են հայտնվում:
Արդյունք

Փաթսյակներ կորցնելու խնդրի համար դա գրեթե բավարար է, առնվազն դա ավելի լավ է, քան մոնիտորինգի բացակայությունը:
Իրոք, CC-«կորուստները» կարող են առաջանալ վիդեո ֆրագմենտների միացման ժամանակ (ինչպես ինձ հայտնի է, այդ գործելակերպը կիրառում են տեղի հեռուստադիտարաններում ՌԴ-ում, այսինքն, CC-հաշվիչի հաշվումներ չի արվում), սա պետք է հիշել: նվիրված լուծումներում այս խնդիրը մասնակիորեն շրջանցվում է SCTE-35 լոգոների հայտնաբերումով (եթե դրանք ավելացվում են հոսքի արտադրողի կողմից):
Տրանսպորտի որակի մոնիտորինգի տեսանկյունից, չի хватает jitter( IAT) մոնիտորինգի, քանի որ հեռուստատեսային սարքերը (ապա լինի մոդուլատորներ կամ վերջնական սարքեր) ունեն այս պարամետրի պահանջներ և միշտ չի կարելի ամբարշնել jitter բուֆերը անվերջ: Իսկ jitter-ը կարող է խաթարվել, երբ տեղափոխման ժամանակ օգտագործվում են մեծ բուֆերներ ունեցող սարքավորումներ և QoS-ն, որը նախատեսված է նման real-time երթևեկություն փոխանցելու համար, լավ չի կարգավորվում կամ բավարար չի կարգավորվել:
Ընտանիք: habr.com
