Menggunakan TSDuck untuk Memantau Streaming IP (TS)

Saat ini, ada solusi siap pakai (proprietary) untuk memantau aliran IP (TS), misalnya, VB dan iQ , mereka memiliki serangkaian fungsi yang cukup kaya dan biasanya solusi tersebut tersedia untuk operator besar yang berurusan dengan layanan TV. Artikel ini menjelaskan solusi yang didasarkan pada proyek open source TSDuck , yang dirancang untuk meminimalkan kontrol aliran IP (TS) oleh counter CC (kontinuitas konter) dan bit rate. Aplikasi yang mungkin adalah untuk mengontrol kehilangan paket atau seluruh aliran melalui saluran L2 sewaan (yang tidak dapat dipantau secara normal, misalnya, dengan membaca penghitung kerugian dalam antrian).


Sangat singkat tentang TSDuck


TSDuck adalah perangkat lunak sumber terbuka (lisensi 2-Clause BSD) (satu set utilitas konsol dan perpustakaan untuk mengembangkan utilitas atau plug-in) untuk memanipulasi aliran TS. Sebagai input ia dapat bekerja dengan IP (multicast / unicast), http, hls, dvb tuner, dektec dvb-asi demodulator, ada generator aliran TS internal dan membaca dari file. Outputnya bisa berupa file, IP (multicast / unicast), hls, dektec dvb-asi dan modulator HiDes, pemain (mplayer, vlc, xine) dan drop. Antara input dan output, Anda dapat mengaktifkan berbagai prosesor lalu lintas, misalnya, pemetaan ulang PID, pengacakan / penguraian ulang, analisis penghitung CC, perhitungan bitrate, dan operasi lain yang khas untuk TS-stream.


Dalam artikel ini, aliran IP (multicast) akan digunakan sebagai input, prosesor bitrate_monitor digunakan (dari namanya jelas apa itu) dan kontinuitas (analisis penghitung CC). Tanpa masalah, Anda dapat mengganti IP multicast dengan jenis input lain yang didukung oleh TSDuck.


Ada build / paket resmi TSDuck untuk sebagian besar OS saat ini. Untuk Debian, mereka tidak, tetapi dimungkinkan untuk berkumpul tanpa masalah di bawah debian 8 dan debian 10.


Selanjutnya, TSDuck versi 3.19-1520 digunakan, Linux digunakan sebagai OS (debian 10 digunakan untuk menyiapkan solusi, CentOS 7 digunakan untuk penggunaan nyata)


Mempersiapkan TSDuck dan OS


Sebelum memantau arus nyata, Anda perlu memastikan bahwa TSDuck berfungsi dengan benar dan tidak ada tetes pada level kartu jaringan atau OS (soket). Ini diperlukan agar tidak menebak nanti di mana tetes terjadi - di jaringan atau "di dalam server". Anda dapat memeriksa tetes pada tingkat kartu jaringan dengan perintah ethtool -S ethX, penyetelan dilakukan dengan ethtool yang sama (biasanya, Anda perlu meningkatkan buffer RX (-G) dan terkadang menonaktifkan beberapa pembebanan (-K)). Sebagai rekomendasi umum, Anda dapat merekomendasikan menggunakan port terpisah untuk menerima lalu lintas yang dianalisis, jika mungkin, ini meminimalkan positif palsu yang terkait dengan fakta bahwa penurunan terjadi secara koheren pada port analyzer karena adanya lalu lintas lainnya. Jika ini tidak memungkinkan (komputer mini / NUC dengan satu port digunakan), maka sangat diinginkan untuk memprioritaskan lalu lintas yang dianalisis relatif terhadap yang lain pada perangkat di mana penganalisa terhubung. Mengenai lingkungan virtual, di sini Anda harus berhati-hati dan dapat menemukan paket tetes mulai dari port fisik dan diakhiri dengan aplikasi di dalam mesin virtual.


Pembuatan dan penerimaan aliran di dalam host


Sebagai langkah pertama dalam mempersiapkan TSDuck, kami akan menghasilkan dan menerima lalu lintas di dalam host yang sama menggunakan jaringan.


Lingkungan memasak:


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 

Lingkungan sudah siap. Kami memulai penganalisa lalu lintas:


 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" berarti Anda harus menghitung bitrate setiap detik dan menampilkan informasi tentang bitrate setiap detik
Kami memulai generator lalu lintas dengan kecepatan 10 Mbps:


 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" berarti Anda harus mengemas 7 paket TS ke dalam 1 paket IP dan melakukannya dengan keras (-e), yaitu selalu menunggu 7 paket TS dari prosesor terakhir sebelum mengirim paket IP.


Penganalisis mulai menampilkan pesan yang diharapkan:


 * 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 tetes:


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

dan pesan 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 

apa yang diharapkan. Nonaktifkan packet loss (ip netns exec P iptables -F) dan coba tingkatkan bitrate generator menjadi 100 Mbps. Penganalisa melaporkan banyak kesalahan CC dan sekitar 75 Mbit / s, bukan 100. Kami mencoba mencari tahu siapa yang harus disalahkan - generator tidak punya waktu atau masalahnya tidak ada, untuk ini kami mulai menghasilkan jumlah paket yang tetap (700.000 paket TS = 100.000 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 100.000 paket IP dihasilkan (151925460-151825460). Jadi kami memahami apa yang terjadi dengan alat analisis, untuk ini kami memeriksa dengan penghitung RX pada veth1, itu benar-benar sama dengan penghitung TX pada veth0, kemudian kita melihat apa yang terjadi pada tingkat 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 dapat melihat jumlah tetes = 24355. Dalam paket TS itu adalah 170485 atau 24,36% dari 700.000, jadi kami melihat bahwa 25% dari bitrate yang hilang adalah tetes dalam soket udp. Penurunan pada soket UDP biasanya terjadi karena kurangnya buffer, lihat ukuran buffer socket default dan ukuran maksimum buffer socket:


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

Jadi, jika aplikasi tidak secara eksplisit meminta ukuran buffer, soket dibuat dengan buffer 208 KB, tetapi jika mereka meminta lebih dari itu, mereka masih tidak akan menerima apa yang diminta. Karena di tsp Anda dapat mengatur ukuran buffer (--buffer-size) untuk input IP, kami tidak akan menyentuh ukuran socket secara default, kami hanya mengatur ukuran maksimum buffer socket dan menentukan ukuran buffer secara eksplisit melalui argumen 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 penyetelan buffer soket ini, bitrate yang sekarang dilaporkan adalah sekitar 100 Mbit / s, tidak ada kesalahan CC.


Oleh konsumsi CPU oleh aplikasi tsp itu sendiri. Sehubungan dengan satu inti dari CPU i5-4260U @ 1.40GHz, analisis aliran 10Mbit / s memerlukan CPU 3-4%, 100Mbit / s - 25%, 200Mbit / s - 46%. Saat mengatur% packet loss, beban pada CPU secara praktis tidak meningkat (tetapi dapat berkurang).


Pada perangkat keras yang lebih produktif, dimungkinkan untuk menghasilkan dan menganalisis aliran lebih dari 1 Gb / s tanpa masalah.


Menguji kartu jaringan nyata


Setelah menguji pada pasangan veth, Anda perlu mengambil dua host atau dua port dari satu host, menghubungkan port satu sama lain, menjalankan generator pada satu, dan analisa pada yang kedua. Tidak ada kejutan, tetapi pada kenyataannya itu semua tergantung pada besi, semakin lemah semakin menarik.


Penggunaan data yang diterima oleh sistem pemantauan (Zabbix)


Tsp tidak memiliki API yang dapat dibaca mesin seperti SNMP atau sejenisnya. Pesan-pesan CC harus dikumpulkan setidaknya 1 detik (dengan persentase paket yang tinggi, mungkin ada ratusan / ribuan / puluhan ribu per detik, tergantung pada bitrate).


Jadi, untuk menyimpan informasi dan menggambar grafik kesalahan CC dan bit rate dan membuat semacam kecelakaan, opsi berikut mungkin lebih lanjut:


  1. Parsing dan agregat (menurut CC) output dari tsp, mis. mengubahnya menjadi bentuk yang diinginkan.
  2. Tambahkan tsp dan / atau plugin prosesor bitrate_monitor dan kontinuitas itu sendiri sehingga hasilnya ditampilkan dalam bentuk yang dapat dibaca mesin yang cocok untuk sistem pemantauan.
  3. Tulis aplikasi Anda di atas perpustakaan tsduck.

Jelas, dari sudut biaya tenaga kerja, opsi 1 adalah yang paling sederhana, terutama mengingat bahwa tsduck sendiri ditulis dalam bahasa tingkat rendah (menurut standar modern) (C ++)


Prototipe sederhana dari pengurai + pengurai pada bash menunjukkan bahwa pada aliran 10Mbit / s dan paket loss 50% (kasus terburuk), proses bash mengkonsumsi CPU 3-4 kali lebih banyak daripada proses tsp itu sendiri. Skenario ini tidak dapat diterima. Sebenarnya sepotong prototipe di bawah ini


Mie di pesta
 #!/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 

Selain fakta bahwa ia bekerja sangat lambat, tidak ada utas normal dalam bash, pekerjaan bash adalah proses yang independen, dan saya harus mencatat nilai missingPackets pada efek samping satu detik sekali (ketika saya menerima pesan bitrate yang datang setiap detik). Akibatnya, bash ditinggalkan sendirian dan diputuskan untuk menulis pembungkus (pengurai + pengumpul) di golang. Konsumsi CPU dari kode golang serupa adalah 4-5 kali lebih sedikit dari proses tsp itu sendiri. Mempercepat pembungkus dengan mengganti bash dengan golang ternyata sekitar 16 kali dan secara keseluruhan hasilnya dapat diterima (overhead pada CPU sebesar 25% dalam kasus terburuk). File sumber di golang ada di sini .


Peluncuran wrapper


Untuk menjalankan wrapper, templat layanan paling sederhana untuk systemd dibuat (di sini ). Diasumsikan bahwa pembungkus itu sendiri dikompilasi menjadi file biner (go build tsduck-stat.go), yang terletak di / opt / tsduck-stat /. Diasumsikan bahwa golang digunakan dengan dukungan untuk jam monoton (> = 1.9).


Untuk membuat turunan dari layanan, Anda perlu menjalankan perintah systemctl aktifkan tsduck-stat@239.0.0.1: 1234, kemudian mulai gunakan systemctl start tsduck-stat@239.0.0.1: 1234.


Penemuan Zabbix


Agar zabbix dapat melakukan penemuan layanan yang sedang berjalan, generator daftar grup (discovery.sh) dibuat, dalam format yang diperlukan untuk penemuan Zabbix, diasumsikan bahwa ia terletak di sana - di / opt / tsduck-stat. Untuk memulai penemuan melalui agen zabbix, Anda perlu menambahkan file .conf ke direktori dengan konfigurasi agen zabbix untuk menambahkan parameter pengguna.


Template Zabbix


Template yang dibuat (tsduck_stat_template.xml) berisi aturan autodiscover, prototipe elemen data, grafik, dan pemicu.


Daftar singkat (bagaimana jika seseorang memutuskan untuk menggunakannya)


  1. Pastikan tsp tidak menjatuhkan paket dalam kondisi "ideal" (generator dan penganalisa terhubung langsung), jika ada tetes, lihat bagian 2 atau teks artikel tentang hal ini.
  2. Lakukan penyetelan buffer soket maksimum (net.core.rmem_max = 8388608).
  3. Kompilasi tsduck-stat.go (buka build tsduck-stat.go).
  4. Masukkan templat layanan di / lib / systemd / system.
  5. Mulai layanan menggunakan systemctl, periksa bahwa penghitung mulai muncul (grep "" / dev / shm / tsduck-stat / *). Jumlah layanan dengan jumlah aliran multicast. Di sini Anda mungkin perlu membuat rute ke grup multicast, mungkin mematikan rp_filter atau membuat rute ke sumber ip.
  6. Jalankan discovery.sh, pastikan itu menghasilkan json.
  7. Pasang konfigurasi agen zabbix, restart agen zabbix.
  8. Unduh template ke zabbix, terapkan pada host di mana agen-zabbix dimonitor dan diinstal, tunggu sekitar 5 menit, lihat bahwa elemen data baru, grafik dan pemicu telah muncul.

Hasil


Bagan dengan bitrate dan kesalahan CC


Untuk tugas mendeteksi packet loss hampir cukup, setidaknya lebih baik daripada kurangnya pemantauan.


Faktanya, β€œkerugian” CC dapat terjadi ketika menempelkan klip video (sejauh yang saya tahu, penyisipan dilakukan di telecenter lokal di Federasi Rusia, yaitu, tanpa menghitung konter CC), ini harus diingat. Dalam solusi berpemilik, masalah ini sebagian dilewati dengan mendeteksi label tag SCTE-35 (jika ditambahkan oleh generator aliran).
UPD: menambahkan dukungan untuk tag SCTE-35 ke bungkus dan template zabbix


Dari sudut pandang pemantauan kualitas transportasi, tidak ada cukup pemantauan jitter (IAT), karena Peralatan TV (apakah modulator atau perangkat akhir) memiliki persyaratan untuk parameter ini dan tidak selalu mungkin untuk mengembang jitbuffer hingga tak terbatas. Dan jitter dapat mengambang ketika peralatan dengan buffer besar digunakan dalam perjalanan dan QoS tidak dikonfigurasi atau tidak dikonfigurasi dengan baik untuk mengirimkan lalu lintas waktu nyata tersebut.

Source: https://habr.com/ru/post/id482736/


All Articles