Menggunakan TSDuck untuk Memantau Aliran IP(TS).

Saat ini, ada solusi siap pakai (eksklusif) untuk memantau aliran IP(TS), misalnya VB ΠΈ iQ, mereka memiliki serangkaian fungsi yang cukup kaya dan biasanya operator besar yang menangani layanan TV memiliki solusi seperti itu. Artikel ini menjelaskan solusi berdasarkan proyek sumber terbuka TSDuck, dirancang untuk kontrol minimal aliran IP(TS) dengan penghitung CC(penghitung kontinuitas) dan kecepatan bit. Penerapan yang mungkin adalah untuk mengontrol hilangnya paket atau seluruh aliran melalui saluran L2 yang disewa (yang tidak dapat dipantau secara normal, misalnya dengan membaca penghitung kehilangan dalam antrian).

Secara singkat tentang TSDuck

TSDuck adalah perangkat lunak sumber terbuka (lisensi 2-Klausul BSD) (seperangkat utilitas konsol dan perpustakaan untuk mengembangkan utilitas atau plugin khusus) untuk memanipulasi aliran TS. Sebagai input, dapat bekerja dengan IP (multicast/unicast), http, hls, dvb tuner, dektec dvb-asi demodulator, ada generator aliran TS internal dan membaca dari file. Outputnya dapat berupa penulisan ke file, IP (multicast/unicast), hls, dektec dvb-asi dan modulator HiDes, pemutar (mplayer, vlc, xine) dan drop. Anda dapat mengaktifkan berbagai pemroses lalu lintas antara input dan output, misalnya, pemetaan ulang PID, pengacakan/penguraian, analisis penghitung CC, penghitungan kecepatan bit, dan operasi umum lainnya untuk aliran TS.

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

Ada bangunan/paket resmi TSDuck untuk sebagian besar sistem operasi terkini. Mereka tidak tersedia untuk Debian, tapi kami berhasil membangunnya di debian 8 dan debian 10 tanpa masalah.

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

Mempersiapkan TSDuck dan OS

Sebelum memantau aliran nyata, Anda perlu memastikan bahwa TSDuck berfungsi dengan benar dan tidak ada penurunan pada tingkat kartu jaringan atau OS (soket). Ini diperlukan agar nantinya tidak menebak di mana penurunan terjadi - di jaringan atau "di dalam server". Anda dapat memeriksa penurunan pada level kartu jaringan dengan perintah ethtool -S ethX, penyetelan dilakukan dengan ethtool yang sama (biasanya, Anda perlu meningkatkan buffer RX (-G) dan terkadang menonaktifkan beberapa offload (-K)). Sebagai rekomendasi umum, disarankan untuk menggunakan port terpisah untuk menerima lalu lintas yang dianalisis, jika memungkinkan, ini meminimalkan kesalahan positif yang terkait dengan fakta bahwa penurunan terjadi tepat pada port penganalisis karena adanya lalu lintas lain. Jika hal ini tidak memungkinkan (komputer mini/NUC dengan satu port digunakan), maka sangat diinginkan untuk mengatur prioritas lalu lintas yang dianalisis dibandingkan dengan yang lain pada perangkat yang terhubung dengan penganalisis. Mengenai lingkungan virtual, di sini Anda perlu berhati-hati dan dapat menemukan paket drop 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 dalam satu host menggunakan netns.

Mempersiapkan lingkungan:

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 penganalisis 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 perlu menghitung bitrate setiap detik dan menampilkan informasi tentang bitrate setiap detik
Kami memulai generator lalu lintas dengan kecepatan 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" berarti Anda perlu mengemas 7 paket TS ke dalam 1 paket IP dan melakukannya dengan keras (-e), yaitu. selalu tunggu 7 paket TS dari prosesor terakhir sebelum mengirim paket IP.

Penganalisis mulai mengeluarkan 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 

yang diharapkan. Nonaktifkan packet loss (ip netns exec P iptables -F) dan coba tingkatkan bitrate generator menjadi 100Mbps. Penganalisis melaporkan banyak kesalahan CC dan sekitar 75 Mbps, bukan 100. Kami mencoba mencari tahu siapa yang harus disalahkan - generator tidak punya waktu atau masalahnya bukan di dalamnya, untuk ini kami mulai menghasilkan sejumlah 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 cari tahu apa yang terjadi dengan penganalisis, untuk ini kita periksa dengan penghitung RX di veth1, sama persis dengan penghitung TX di veth0, lalu kita lihat apa yang terjadi di level 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 penurunan = 24355. Dalam paket TS, ini adalah 170485 atau 24.36% dari 700000, jadi kita melihat bahwa 25% dari bitrate yang hilang adalah penurunan di soket udp. Drop pada soket UDP biasanya terjadi karena kurangnya buffer, lihat ukuran buffer soket default dan ukuran buffer soket maksimum:

# 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 sebesar 208 KB, namun jika meminta lebih, mereka tetap tidak akan menerima apa yang diminta. Karena Anda dapat mengatur ukuran buffer dalam tsp untuk input IP (-buffer-size), kami tidak akan menyentuh ukuran soket default, tetapi hanya mengatur ukuran buffer soket maksimum 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, sekarang bitrate yang dilaporkan sekitar 100Mbps, tidak ada kesalahan CC.

Menurut konsumsi CPU dari aplikasi tsp itu sendiri. Dibandingkan dengan satu CPU inti i5-4260U @ 1.40GHz, analisis aliran 10Mbps akan memerlukan 3-4% CPU, 100Mbps - 25%, 200Mbps - 46%. Saat mengatur % Packet Loss, beban pada CPU praktis tidak bertambah (tetapi bisa berkurang).

Pada perangkat keras yang lebih produktif, aliran lebih dari 1Gb/s dapat dibuat dan dianalisis tanpa masalah apa pun.

Menguji pada kartu jaringan nyata

Setelah menguji pada pasangan veth, Anda perlu mengambil dua host atau dua port dari satu host, menghubungkan port satu sama lain, memulai generator di satu host, dan penganalisis di host kedua. Tidak ada kejutan di sini, tapi sebenarnya itu semua tergantung besinya, semakin lemah, semakin menarik di sini.

Menggunakan data yang diterima oleh sistem pemantauan (Zabbix)

tsp tidak memiliki API yang dapat dibaca mesin seperti SNMP atau sejenisnya. Pesan CC harus dikumpulkan setidaknya selama 1 detik (dengan persentase kehilangan paket yang tinggi, bisa mencapai ratusan/ribuan/puluhan ribu per detik, tergantung pada bitrate).

Jadi, untuk menyimpan informasi dan menggambar grafik untuk kesalahan CC dan bitrate serta membuat beberapa jenis kecelakaan, mungkin ada opsi berikut:

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

Tentunya opsi 1 adalah yang paling mudah dari segi usaha, apalagi mengingat tsduck sendiri ditulis dalam bahasa tingkat rendah (menurut standar modern) (C++)

Prototipe parser+agregator bash sederhana menunjukkan bahwa pada aliran 10Mbps dan kehilangan paket 50% (kasus terburuk), proses bash menghabiskan CPU 3-4 kali lebih banyak daripada proses tsp itu sendiri. Skenario ini tidak bisa diterima. Sebenarnya sebagian dari prototipe di bawah ini

Mie di atasnya

#!/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 sangat lambat, tidak ada utas normal di bash, pekerjaan bash adalah proses yang terpisah, dan saya harus menulis nilai missingPackets sekali dalam satu detik sebagai efek samping (saat menerima pesan bitrate yang datang setiap detik). Akibatnya, bash dibiarkan saja dan diputuskan untuk menulis wrapper (parser + aggregator) di golang. Konsumsi CPU dari kode golang serupa 4-5 kali lebih sedikit dibandingkan proses sdt itu sendiri. Kecepatan wrapper akibat penggantian bash dengan golang ternyata sekitar 16 kali lipat dan secara umum hasilnya dapat diterima (overhead CPU sebesar 25% dalam kasus terburuk). File sumber golang berada di sini.

Jalankan pembungkus

Untuk memulai pembungkus, templat layanan paling sederhana untuk systemd dibuat (di sini). Pembungkusnya sendiri seharusnya dikompilasi menjadi file biner (go build tsduck-stat.go) yang terletak di /opt/tsduck-stat/. Diasumsikan Anda menggunakan golang dengan dukungan jam monotonik (>=1.9).

Untuk membuat instance layanan, Anda perlu menjalankan perintah systemctl aktifkan [email dilindungi]:1234 lalu jalankan dengan systemctl start [email dilindungi]: 1234.

Penemuan dari Zabbix

Agar zabbix dapat menemukan layanan yang sedang berjalan, hal itu dilakukan pembuat daftar grup (discovery.sh), dalam format yang diperlukan untuk penemuan Zabbix, diasumsikan terletak di tempat yang sama - di /opt/tsduck-stat. Untuk menjalankan penemuan melalui zabbix-agent, Anda perlu menambahkan berkas .conf ke direktori konfigurasi zabbix-agent untuk menambahkan parameter pengguna.

Templat Zabbix

Templat yang dibuat (tsduck_stat_template.xml) berisi aturan penemuan otomatis, prototipe item, grafik, dan pemicu.

Daftar periksa singkat (bagaimana jika seseorang memutuskan untuk menggunakannya)

  1. Pastikan sdt tidak menjatuhkan paket dalam kondisi "ideal" (generator dan penganalisis terhubung langsung), jika ada penurunan lihat paragraf 2 atau teks artikel tentang hal ini.
  2. Lakukan penyetelan buffer soket maksimum (net.core.rmem_max=8388608).
  3. Kompilasi tsduck-stat.go (go build tsduck-stat.go).
  4. Letakkan templat layanan di /lib/systemd/system.
  5. Mulai layanan dengan systemctl, periksa apakah penghitung sudah mulai muncul (grep "" /dev/shm/tsduck-stat/*). Jumlah layanan dengan jumlah aliran multicast. Di sini Anda mungkin perlu membuat rute ke grup multicast, mungkin menonaktifkan rp_filter atau membuat rute ke ip sumber.
  6. Jalankan Discovery.sh, pastikan itu menghasilkan json.
  7. Tambahkan konfigurasi agen zabbix, mulai ulang agen zabbix.
  8. Upload template ke zabbix, terapkan pada host yang dimonitor dan zabbix-agent sudah terinstall, tunggu sekitar 5 menit, lihat apakah ada item, grafik dan trigger baru.

Hasil

Menggunakan TSDuck untuk Memantau Aliran IP(TS).

Untuk tugas mendeteksi packet loss hampir cukup, setidaknya lebih baik daripada tidak ada monitoring.

Memang, β€œkerugian” CC dapat terjadi saat menggabungkan fragmen video (sejauh yang saya tahu, ini adalah cara penyisipan dilakukan di pusat TV lokal di Federasi Rusia, yaitu tanpa menghitung ulang penghitung CC), ini harus diingat. Solusi eksklusif mengatasi sebagian masalah ini dengan mendeteksi label SCTE-35 (jika ditambahkan oleh generator aliran).

Dalam hal pemantauan kualitas transportasi, terdapat kekurangan dalam pemantauan jitter (IAT). Peralatan TV (baik modulator atau perangkat akhir) memiliki persyaratan untuk parameter ini dan tidak selalu memungkinkan untuk meningkatkan jitbuffer hingga tak terbatas. Dan jitter dapat mengambang ketika peralatan dengan buffer besar digunakan dalam transit dan QoS tidak dikonfigurasi atau dikonfigurasi dengan cukup baik untuk mengirimkan lalu lintas real-time tersebut.

Sumber: www.habr.com

Tambah komentar