Menggunakan TSDuck untuk Memantau Strim IP(TS).

Hari ini, terdapat penyelesaian siap sedia (proprietari) untuk memantau aliran IP(TS), contohnya VB ΠΈ iQ, mereka mempunyai set fungsi yang agak kaya dan biasanya pengendali besar yang berurusan dengan perkhidmatan TV mempunyai penyelesaian sedemikian. Artikel ini menerangkan penyelesaian berdasarkan projek sumber terbuka TSDuck, direka untuk kawalan minimum strim IP(TS) oleh pembilang CC(kontinuitas) dan kadar bit. Permohonan yang mungkin adalah untuk mengawal kehilangan paket atau keseluruhan aliran melalui saluran L2 yang dipajak (yang tidak boleh dipantau secara normal, contohnya, dengan membaca kaunter kerugian dalam baris gilir).

Secara ringkas tentang TSDuck

TSDuck ialah perisian sumber terbuka (lesen BSD 2 Klausa) (satu set utiliti konsol dan perpustakaan untuk membangunkan utiliti atau pemalam tersuai) untuk memanipulasi strim TS. Sebagai input, ia boleh berfungsi dengan IP (multicast/unicast), http, hls, dvb tuners, dektec dvb-asi demodulator, terdapat penjana TS-stream dalaman dan membaca daripada fail. Output boleh menulis ke fail, IP (multicast/unicast), hls, dektec dvb-asi dan modulator HiDes, pemain (mplayer, vlc, xine) dan drop. Pelbagai pemproses trafik boleh disertakan di antara input dan output, contohnya, pemetaan semula PID, berebut / menyahbongkar, analisis pembilang CC, pengiraan kadar bit dan operasi tipikal lain untuk aliran TS.

Dalam artikel ini, aliran IP (multicast) akan digunakan sebagai input, pemproses bitrate_monitor (dari nama jelas apa itu) dan kesinambungan (analisis pembilang CC) digunakan. Anda boleh menggantikan IP multicast dengan mudah dengan jenis input lain yang disokong oleh TSDuck.

Terdapat binaan/pakej rasmi TSDuck untuk kebanyakan sistem pengendalian semasa. Ia tidak tersedia untuk Debian, tetapi kami berjaya membinanya di bawah debian 8 dan debian 10 tanpa sebarang masalah.

Seterusnya, versi TSDuck 3.19-1520 digunakan, Linux digunakan sebagai OS (debian 10 digunakan untuk menyediakan penyelesaian, CentOS 7 digunakan untuk kegunaan sebenar)

Menyediakan TSDuck dan OS

Sebelum memantau aliran sebenar, anda perlu memastikan bahawa TSDuck berfungsi dengan betul dan tiada kejatuhan pada tahap kad rangkaian atau OS (soket). Ini diperlukan agar tidak meneka kemudian di mana kejatuhan berlaku - pada rangkaian atau "di dalam pelayan". Anda boleh menyemak penurunan pada tahap kad rangkaian dengan perintah ethtool -S ethX, penalaan dilakukan oleh ethtool yang sama (biasanya, anda perlu meningkatkan penampan RX (-G) dan kadangkala melumpuhkan beberapa offload (-K)). Sebagai cadangan umum, anda boleh dinasihatkan untuk menggunakan port yang berasingan untuk menerima trafik yang dianalisis, jika boleh, ini meminimumkan positif palsu yang dikaitkan dengan fakta bahawa penurunan berlaku tepat pada port penganalisis disebabkan oleh kehadiran trafik lain. Jika ini tidak mungkin (komputer mini/NUC dengan satu port digunakan), maka adalah sangat wajar untuk menetapkan keutamaan trafik yang dianalisis berhubung dengan yang lain pada peranti yang penganalisis disambungkan. Mengenai persekitaran maya, di sini anda perlu berhati-hati dan dapat mencari titisan paket bermula dari port fizikal dan berakhir dengan aplikasi di dalam mesin maya.

Penjanaan dan penerimaan aliran dalam hos

Sebagai langkah pertama dalam menyediakan TSDuck, kami akan menjana dan menerima trafik dalam satu hos menggunakan jaring.

Menyediakan persekitaran:

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

Persekitaran sudah siap. Kami memulakan penganalisis trafik:

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

di mana "-p 1 -t 1" bermakna anda perlu mengira kadar bit setiap saat dan memaparkan maklumat tentang kadar bit setiap saat
Kami memulakan penjana trafik dengan kelajuan 10Mbps:

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

di mana "-p 7 -e" bermakna anda perlu membungkus 7 paket TS ke dalam 1 paket IP dan melakukannya dengan keras (-e), i.e. sentiasa tunggu 7 paket TS daripada pemproses terakhir sebelum menghantar paket IP.

Penganalisis mula mengeluarkan mesej yang dijangkakan:

* 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

Sekarang tambahkan beberapa titisan:

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

dan mesej seperti ini muncul:

* 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 

yang dijangka. Lumpuhkan kehilangan paket (ip netns exec P iptables -F) dan cuba tingkatkan kadar bit penjana kepada 100Mbps. Penganalisis melaporkan sekumpulan ralat CC dan kira-kira 75 Mbps dan bukannya 100. Kami cuba memikirkan siapa yang harus dipersalahkan - penjana tidak mempunyai masa atau masalahnya tidak ada, untuk ini kami mula menjana nombor tetap paket (700000 paket TS = 100000 paket 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

Seperti yang anda lihat, tepat 100000 paket IP telah dihasilkan (151925460-151825460). Jadi mari kita fikirkan apa yang berlaku dengan penganalisis, untuk ini kita semak dengan kaunter RX pada veth1, ia sama dengan kaunter TX pada veth0, kemudian kami melihat apa yang berlaku pada tahap soket:

# 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 

Di sini anda boleh melihat bilangan titisan = 24355. Dalam paket TS, ini ialah 170485 atau 24.36% daripada 700000, jadi kami melihat bahawa 25% daripada kadar bit yang hilang adalah titisan dalam soket udp. Penurunan dalam soket UDP biasanya berlaku kerana kekurangan penimbal, lihat saiz penimbal soket lalai dan saiz penimbal soket maksimum:

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

Oleh itu, jika aplikasi tidak meminta saiz penimbal secara eksplisit, soket dicipta dengan penimbal 208 KB, tetapi jika mereka meminta lebih banyak, mereka masih tidak akan menerima apa yang diminta. Memandangkan anda boleh menetapkan saiz penimbal dalam tsp untuk input IP (-saiz penimbal), kami tidak akan menyentuh saiz soket lalai, tetapi hanya menetapkan saiz penimbal soket maksimum dan menentukan saiz penimbal secara eksplisit melalui hujah 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

Dengan penalaan penimbal soket ini, kini kadar bit yang dilaporkan ialah kira-kira 100Mbps, tiada ralat CC.

Mengikut penggunaan CPU aplikasi tsp itu sendiri. Berbanding dengan satu teras CPU i5-4260U @ 1.40GHz, analisis aliran 10Mbps akan memerlukan 3-4% CPU, 100Mbps - 25%, 200Mbps - 46%. Apabila menetapkan % Kehilangan Paket, beban pada CPU boleh dikatakan tidak meningkat (tetapi mungkin berkurangan).

Pada perkakasan yang lebih produktif, adalah mungkin untuk menjana dan menganalisis aliran lebih daripada 1Gb / s tanpa sebarang masalah.

Ujian pada kad rangkaian sebenar

Selepas menguji pada pasangan veth, anda perlu mengambil dua hos atau dua port satu hos, sambungkan port antara satu sama lain, mulakan penjana pada satu, dan penganalisis pada yang kedua. Tidak ada kejutan di sini, tetapi sebenarnya semuanya bergantung pada besi, semakin lemah, semakin menarik ia akan berada di sini.

Menggunakan data yang diterima oleh sistem pemantauan (Zabbix)

tsp tidak mempunyai API yang boleh dibaca mesin seperti SNMP atau yang serupa. Mesej CC mesti diagregatkan selama sekurang-kurangnya 1 saat (dengan peratusan kehilangan paket yang tinggi, mungkin terdapat ratusan/ribu/puluhan ribu sesaat, bergantung pada kadar bit).

Oleh itu, untuk menyimpan kedua-dua maklumat dan melukis graf untuk ralat CC dan kadar bit serta membuat beberapa jenis kemalangan, mungkin terdapat pilihan berikut:

  1. Parsing dan agregat (mengikut CC) keluaran tsp, i.e. menukarkannya kepada bentuk yang dikehendaki.
  2. Selesaikan tsp sendiri dan/atau pemalam pemproses bitrate_monitor dan kesinambungan supaya hasilnya diberikan dalam bentuk yang boleh dibaca mesin yang sesuai untuk sistem pemantauan.
  3. Tulis aplikasi anda di atas perpustakaan tsduck.

Jelas sekali, pilihan 1 adalah yang paling mudah dari segi usaha, terutamanya memandangkan tsduck itu sendiri ditulis dalam bahasa peringkat rendah (mengikut piawaian moden) (C ++)

Prototaip bash parser+agregator ringkas menunjukkan bahawa pada aliran 10Mbps dan 50% kehilangan paket (kes terburuk), proses bash menggunakan CPU 3-4 kali lebih banyak daripada proses tsp itu sendiri. Senario ini tidak boleh diterima. Sebenarnya sekeping prototaip ini di bawah

Mee di atas

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

Di samping menjadi sangat perlahan, tiada benang biasa dalam bash, kerja bash adalah proses yang berasingan, dan saya terpaksa menulis nilai missingPackets sekali sesaat pada kesan sampingan (apabila menerima mesej kadar bit yang datang setiap saat). Akibatnya, bash dibiarkan bersendirian dan diputuskan untuk menulis pembungkus (penghurai + pengagregat) dalam golang. Penggunaan CPU kod golang yang serupa adalah 4-5 kali kurang daripada proses tsp itu sendiri. Kelajuan pembungkus kerana penggantian bash dengan golang ternyata kira-kira 16 kali ganda dan secara umum hasilnya boleh diterima (overhed CPU sebanyak 25% dalam kes terburuk). Fail sumber golang terletak di sini.

Jalankan pembalut

Untuk memulakan pembungkus, templat perkhidmatan paling mudah untuk systemd telah dibuat (di sini). Pembalut itu sendiri sepatutnya disusun ke dalam fail binari (pergi bina tsduck-stat.go) yang terletak di /opt/tsduck-stat/. Diandaikan bahawa anda menggunakan golang dengan sokongan untuk jam monoton (>=1.9).

Untuk membuat contoh perkhidmatan, anda perlu menjalankan perintah systemctl enable [e-mel dilindungi]:1234 kemudian jalankan dengan systemctl start [e-mel dilindungi]: 1234.

Penemuan dari Zabbix

Agar zabbix dapat menemui perkhidmatan yang sedang berjalan, ia dilakukan penjana senarai kumpulan (discovery.sh), dalam format yang diperlukan untuk penemuan Zabbix, diandaikan bahawa ia terletak di tempat yang sama - dalam /opt/tsduck-stat. Untuk menjalankan penemuan melalui zabbix-agent, anda perlu menambah fail .conf ke direktori konfigurasi ejen-zabbix untuk menambah parameter pengguna.

Templat Zabbix

Templat yang dibuat (tsduck_stat_template.xml) mengandungi peraturan penemuan automatik, prototaip item, graf dan pencetus.

Senarai semak ringkas (baik, bagaimana jika seseorang memutuskan untuk menggunakannya)

  1. Pastikan tsp tidak menjatuhkan paket di bawah keadaan "ideal" (penjana dan penganalisis disambungkan terus), jika terdapat titisan, lihat perenggan 2 atau teks artikel mengenai perkara ini.
  2. Jadikan penalaan penimbal soket maksimum (net.core.rmem_max=8388608).
  3. Susun tsduck-stat.go (pergi bina tsduck-stat.go).
  4. Letakkan templat perkhidmatan dalam /lib/systemd/system.
  5. Mulakan perkhidmatan dengan systemctl, semak sama ada kaunter telah mula muncul (grep "" /dev/shm/tsduck-stat/*). Bilangan perkhidmatan mengikut bilangan aliran multicast. Di sini anda mungkin perlu mencipta laluan ke kumpulan multicast, mungkin melumpuhkan rp_filter atau mencipta laluan ke ip sumber.
  6. Jalankan discovery.sh, pastikan ia menjana json.
  7. Tambah konfigurasi ejen zabbix, mulakan semula ejen zabbix.
  8. Muat naik templat ke zabbix, gunakannya pada hos yang sedang dipantau dan ejen zabbix dipasang, tunggu kira-kira 5 minit, lihat jika terdapat item, graf dan pencetus baharu.

Keputusan

Menggunakan TSDuck untuk Memantau Strim IP(TS).

Untuk tugas mengesan kehilangan paket, ia hampir mencukupi, sekurang-kurangnya ia lebih baik daripada tiada pemantauan.

Sesungguhnya, "kerugian" CC boleh berlaku apabila menggabungkan serpihan video (setahu saya, ini adalah cara sisipan dibuat di pusat TV tempatan di Persekutuan Rusia, iaitu tanpa mengira semula kaunter CC), ini mesti diingat. Penyelesaian proprietari sebahagiannya memintas masalah ini dengan mengesan label SCTE-35 (jika ditambah oleh penjana aliran).

Dari segi pemantauan kualiti pengangkutan, terdapat kekurangan pemantauan jitter (IAT). Peralatan TV (sama ada modulator atau peranti akhir) mempunyai keperluan untuk parameter ini dan tidak selalu mungkin untuk mengembang jitbuffer ke infiniti. Dan jitter boleh terapung apabila peralatan dengan penimbal besar digunakan dalam transit dan QoS tidak dikonfigurasikan atau tidak cukup dikonfigurasikan untuk menghantar trafik masa nyata tersebut.

Sumber: www.habr.com

Tambah komen