IP(TS) Akışlarını İzlemek için TSDuck Kullanma

Bugün, örneğin IP(TS) akışlarını izlemek için hazır (özel) çözümler bulunmaktadır. VB и iQ, oldukça zengin işlevlere sahiptirler ve genellikle TV hizmetleriyle uğraşan büyük operatörlerin bu tür çözümleri vardır. Bu makalede, açık kaynaklı bir projeye dayalı bir çözüm açıklanmaktadır. TSDuck, CC (süreklilik sayacı) sayacı ve bit hızı ile IP(TS) akışlarının minimum kontrolü için tasarlanmıştır. Muhtemel bir uygulama, paketlerin kaybını veya kiralık bir L2 kanalı üzerinden tüm akışı kontrol etmektir (bu, örneğin kuyruklardaki kayıp sayaçlarını okuyarak normal olarak izlenemez).

TSDuck hakkında çok kısaca

TSDuck, TS akışlarını manipüle etmek için açık kaynaklı (2-Maddeli BSD lisansı) bir yazılımdır (bir dizi konsol yardımcı programı ve özel yardımcı programlar veya eklentiler geliştirmek için bir kitaplık). Giriş olarak IP (multicast/unicast), http, hls, dvb tuner, dektec dvb-asi demodulator ile çalışabilir, dahili bir TS-stream oluşturucu ve dosyalardan okuma vardır. Çıktı bir dosyaya yazma, IP (multicast/unicast), hls, dektec dvb-asi ve HiDes modülatörleri, oynatıcılar (mplayer, vlc, xine) ve drop olabilir. Giriş ve çıkış arasına çeşitli trafik işlemcileri dahil edilebilir, örneğin, PID yeniden eşleme, karıştırma/karma çözme, CC sayaç analizi, bit hızı hesaplama ve TS akışları için diğer tipik işlemler.

Bu yazıda girdi olarak IP stream (multicast) kullanılacak, bitrate_monitor (adından ne olduğu anlaşılan) işlemciler ve süreklilik (CC sayaçlarının analizi) kullanılacaktır. IP çoklu yayını TSDuck tarafından desteklenen başka bir giriş tipiyle kolayca değiştirebilirsiniz.

Var resmi yapılar/paketler En güncel işletim sistemleri için TSDuck. Debian için mevcut değiller, ancak onları debian 8 ve debian 10 altında sorunsuz bir şekilde oluşturmayı başardık.

Ardından, TSDuck 3.19-1520 sürümü kullanılır, işletim sistemi olarak Linux kullanılır (çözüm hazırlamak için debian 10, gerçek kullanım için CentOS 7 kullanıldı)

TSDuck ve işletim sistemini hazırlama

Gerçek akışları izlemeden önce, TSDuck'ın doğru çalıştığından ve ağ kartı veya işletim sistemi (soket) düzeyinde düşüş olmadığından emin olmanız gerekir. Bu, daha sonra ağda veya "sunucunun içinde" düşüşlerin nerede meydana geldiğini tahmin etmemek için gereklidir. ethtool -S ethX komutuyla ağ kartı düzeyinde düşüşleri kontrol edebilirsiniz, ayarlama aynı ethtool tarafından yapılır (genellikle, RX arabelleğini (-G) artırmanız ve bazen bazı boşaltmaları (-K) devre dışı bırakmanız gerekir). Genel bir öneri olarak, analiz edilen trafiği almak için ayrı bir bağlantı noktası kullanılması önerilebilir, mümkünse bu, diğer trafiğin varlığından dolayı düşüşün tam olarak analizör bağlantı noktasında gerçekleşmesiyle ilişkili yanlış pozitifleri en aza indirir. Bu mümkün değilse (tek bağlantı noktalı bir mini bilgisayar/NUC kullanılır), analizörün bağlı olduğu cihazda analiz edilen trafiğin geri kalanına göre önceliklendirilmesinin ayarlanması oldukça arzu edilir. Sanal ortamlarla ilgili olarak, burada dikkatli olmanız ve fiziksel bir bağlantı noktasından başlayan ve bir sanal makine içindeki bir uygulama ile biten paket düşüşlerini bulabilmeniz gerekir.

Ana bilgisayar içinde bir akışın oluşturulması ve alınması

TSDuck'u hazırlamanın ilk adımı olarak, ağları kullanarak tek bir ana bilgisayarda trafik oluşturacağız ve alacağız.

Ortamın hazırlanması:

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

Ortam hazır. Trafik analizörünü başlatıyoruz:

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

burada "-p 1 -t 1", her saniye bit hızını hesaplamanız ve her saniye bit hızı hakkında bilgi görüntülemeniz gerektiği anlamına gelir
Trafik oluşturucuyu 10 Mbps hızında başlatıyoruz:

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

burada "-p 7 -e", 7 TS paketini 1 IP paketine paketlemeniz ve bunu sıkı (-e) yapmanız gerektiği anlamına gelir, yani. bir IP paketi göndermeden önce daima son işlemciden 7 TS paketi bekleyin.

Analizör beklenen mesajları vermeye başlar:

* 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

Şimdi birkaç damla ekleyin:

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

ve bunun gibi mesajlar görünür:

* 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 

bu bekleniyor. Paket kaybını devre dışı bırakın (ip netns exec P iptables -F) ve jeneratör bit hızını 100Mbps'ye yükseltmeyi deneyin. Analizör bir grup CC hatası ve 75 yerine yaklaşık 100 Mbps bildiriyor. Kimin suçlanacağını bulmaya çalışıyoruz - jeneratörün zamanı yok veya sorun onda değil, bunun için sabit sayıda üretmeye başlıyoruz. paketler (700000 TS paketi = 100000 IP paketi):

# 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

Gördüğünüz gibi tam olarak 100000 IP paketi üretildi (151925460-151825460). Öyleyse analizöre ne olduğunu bulalım, bunun için veth1 üzerindeki RX sayacı ile kontrol ediyoruz, kesinlikle veth0 üzerindeki TX sayacına eşit, sonra soket düzeyinde ne olduğuna bakıyoruz:

# 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 

Burada düşme sayısını = 24355 görebilirsiniz. TS paketlerinde bu 170485 veya 24.36'in %700000'sıdır, dolayısıyla kayıp bit hızının aynı %25'inin udp soketindeki düşüşler olduğunu görüyoruz. Bir UDP soketindeki düşüşler genellikle arabellek eksikliğinden kaynaklanır, varsayılan yuva arabellek boyutuna ve maksimum soket arabellek boyutuna bakın:

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

Bu nedenle, uygulamalar açıkça bir arabellek boyutu talep etmezse, yuvalar 208 KB'lik bir arabellek ile oluşturulur, ancak daha fazlasını talep ederlerse, yine de istenenleri alamazlar. IP girişi (-buffer-size) için arabellek boyutunu tsp olarak ayarlayabildiğiniz için, varsayılan soket boyutuna dokunmayacağız, yalnızca maksimum soket arabellek boyutunu ayarlayacağız ve arabellek boyutunu tsp argümanları aracılığıyla açıkça belirteceğiz:

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

Soket arabelleğinin bu şekilde ayarlanmasıyla, bildirilen bit hızı artık yaklaşık 100 Mbps'dir ve CC hatası yoktur.

tsp uygulamasının kendisinin CPU tüketimine göre. 5 GHz'de tek çekirdekli i4260-1.40U CPU'ya göre, 10 Mbps akış analizi için %3-4 CPU, 100 Mbps - %25, 200 Mbps - %46 gerekir. % Paket Kaybını ayarlarken, CPU üzerindeki yük pratik olarak artmaz (ancak azalabilir).

Daha üretken donanımlarda, 1Gb/sn üzerindeki akışları sorunsuz bir şekilde oluşturmak ve analiz etmek mümkündü.

Gerçek ağ kartlarında test etme

Bir veth çifti üzerinde test ettikten sonra, iki ana bilgisayarı veya bir ana bilgisayarın iki bağlantı noktasını almanız, bağlantı noktalarını birbirine bağlamanız, birinde jeneratörü ve ikincisinde analizörü çalıştırmanız gerekir. Burada sürpriz olmadı, ama aslında her şey demire bağlı, ne kadar zayıfsa, burada o kadar ilginç olacak.

İzleme sistemi (Zabbix) tarafından alınan verilerin kullanılması

tsp, SNMP veya benzeri gibi makine tarafından okunabilen herhangi bir API'ye sahip değildir. CC mesajları en az 1 saniye boyunca toplanmalıdır (yüksek oranda paket kaybıyla, bit hızına bağlı olarak saniyede yüzlerce/binlerce/on binlerce olabilir).

Böylece hem bilgileri kaydetmek hem de CC hataları ve bit hızı için grafik çizmek ve bir takım kazalar yapmak için aşağıdaki seçenekler olabilir:

  1. tsp'nin çıktısını ayrıştırın ve toplayın (CC ile), yani. istediğiniz forma dönüştürün.
  2. tsp'nin kendisini ve/veya işlemci eklentilerini bitrate_monitor ve sürekliliği bitirin, böylece sonuç, izleme sistemi için uygun, makine tarafından okunabilir bir biçimde verilir.
  3. Uygulamanızı tsduck kitaplığının en üstüne yazın.

Açıkçası, seçenek 1, özellikle tsduck'un düşük seviyeli (modern standartlara göre) bir dilde (C ++) yazıldığı düşünüldüğünde, çaba açısından en kolay olanıdır.

Basit bir bash ayrıştırıcı+toplayıcı prototipi, 10 Mbps akışta ve %50 paket kaybında (en kötü durum), bash işleminin tsp işleminin kendisinden 3-4 kat daha fazla CPU tükettiğini gösterdi. Bu senaryo kabul edilemez. Aslında aşağıdaki bu prototipin bir parçası

Üstte erişte

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

Kabul edilemeyecek kadar yavaş olmasının yanı sıra, bash'ta normal threadler yok, bash işleri ayrı süreçler ve yan etkide (her saniyede bir gelen bitrate mesajlarını alırken) missippackets'in değerini saniyede bir yazmak zorunda kaldım. Sonuç olarak, bash yalnız bırakıldı ve golang'da bir sarmalayıcı (ayrıştırıcı + toplayıcı) yazılmasına karar verildi. Benzer golang kodunun CPU tüketimi, tsp işleminin kendisinden 4-5 kat daha azdır. Bash'ın golang ile değiştirilmesi nedeniyle sarmalayıcının hızlanması yaklaşık 16 kat oldu ve genel olarak sonuç kabul edilebilir (en kötü durumda CPU ek yükü %25). Golang kaynak dosyası bulunur burada.

sarmalayıcıyı çalıştır

Paketleyiciyi başlatmak için, systemd için en basit hizmet şablonu yapıldı (burada). Sarmalayıcının kendisinin /opt/tsduck-stat/ konumunda bulunan bir ikili dosyada (go build tsduck-stat.go) derlenmesi gerekiyor. Golang'ı monoton saat desteğiyle (>=1.9) kullandığınız varsayılmıştır.

Hizmetin bir örneğini oluşturmak için systemctl enable komutunu çalıştırmanız gerekir. [e-posta korumalı]:1234 sonra systemctl start ile çalıştırın [e-posta korumalı]: 1234.

Zabbix'ten Keşif

Zabbix'in çalışan servisleri keşfedebilmesi için yapılır. grup listesi üreteci (discovery.sh), Zabbix keşfi için gerekli biçimde, aynı yerde - /opt/tsduck-stat içinde bulunduğu varsayılır. zabbix-agent aracılığıyla keşif çalıştırmak için eklemeniz gerekir .conf dosyası kullanıcı parametresini eklemek için zabbix-agent yapılandırma dizinine.

Zabbix şablonu

Oluşturulan şablon (tsduck_stat_template.xml) otomatik bulma kuralını, öğe prototiplerini, grafikleri ve tetikleyicileri içerir.

Kısa kontrol listesi (peki, ya birisi onu kullanmaya karar verirse)

  1. tsp'nin "ideal" koşullar altında paketleri düşürmediğinden emin olun (jeneratör ve analizör doğrudan bağlanır), düşme varsa, bu konudaki 2. paragrafa veya makalenin metnine bakın.
  2. Ayarlamayı maksimum soket arabelleği yapın (net.core.rmem_max=8388608).
  3. tsduck-stat.go'yu derleyin (gidip tsduck-stat.go'yu oluşturun).
  4. Hizmet şablonunu /lib/systemd/system içine yerleştirin.
  5. Hizmetleri systemctl ile başlatın, sayaçların görünmeye başladığını kontrol edin (grep "" /dev/shm/tsduck-stat/*). Çok noktaya yayın akışlarının sayısına göre hizmet sayısı. Burada çok noktaya yayın grubuna bir rota oluşturmanız, belki de rp_filter'ı devre dışı bırakmanız veya kaynak ip'ye bir rota oluşturmanız gerekebilir.
  6. Discovery.sh'yi çalıştırın, json ürettiğinden emin olun.
  7. Zabbix aracı yapılandırmasını ekleyin, zabbix aracısını yeniden başlatın.
  8. Şablonu zabbix'e yükleyin, izlenen ana bilgisayara uygulayın ve zabbix-agent kurulur, yaklaşık 5 dakika bekleyin, yeni öğeler, grafikler ve tetikleyiciler olup olmadığına bakın.

sonuç

IP(TS) Akışlarını İzlemek için TSDuck Kullanma

Paket kaybını tespit etme görevi için neredeyse yeterlidir, en azından hiç izlememekten iyidir.

Gerçekten de, video parçalarını birleştirirken CC "kayıpları" meydana gelebilir (bildiğim kadarıyla, Rusya Federasyonu'ndaki yerel TV merkezlerinde ekler bu şekilde yapılır, yani CC sayacını yeniden hesaplamadan), bu hatırlanmalıdır. Tescilli çözümler, SCTE-35 etiketlerini algılayarak (akış oluşturucu tarafından eklenmişse) bu sorunu kısmen ortadan kaldırır.

Taşıma kalitesinin izlenmesi açısından, titreme izleme (IAT) eksikliği vardır. TV ekipmanı (modülatörler veya uç cihazlar) bu parametre için gereksinimlere sahiptir ve jitbuffer'ı sonsuza kadar şişirmek her zaman mümkün değildir. Geçiş sırasında büyük arabelleğe sahip ekipman kullanıldığında ve QoS yapılandırılmadığında veya bu tür gerçek zamanlı trafiği iletecek kadar iyi yapılandırılmadığında titreşim yüzebilir.

Kaynak: habr.com

Yorum ekle