ใช้ TSDuck เพื่อตรวจสอบสตรีม IP (TS)

ปัจจุบันมีโซลูชันสำเร็จรูป (ที่เป็นกรรมสิทธิ์) สำหรับการตรวจสอบสตรีม IP (TS) เป็นต้น VB и iQพวกเขามีชุดฟังก์ชันที่ค่อนข้างสมบูรณ์และโดยปกติแล้วผู้ให้บริการรายใหญ่ที่เกี่ยวข้องกับบริการทีวีจะมีโซลูชันดังกล่าว บทความนี้อธิบายวิธีแก้ปัญหาตามโครงการโอเพ่นซอร์ส ทีเอสดั๊กออกแบบมาเพื่อควบคุมสตรีม IP(TS) ให้น้อยที่สุดโดยตัวนับ CC (ตัวนับความต่อเนื่อง) และบิตเรต แอปพลิเคชันที่เป็นไปได้คือการควบคุมการสูญหายของแพ็กเก็ตหรือโฟลว์ทั้งหมดผ่านแชนเนล L2 ที่เช่า (ซึ่งไม่สามารถตรวจสอบได้ตามปกติ เช่น โดยการอ่านตัวนับการสูญเสียในคิว)

สั้น ๆ เกี่ยวกับ TSDuck

TSDuck เป็นซอฟต์แวร์โอเพ่นซอร์ส (ใบอนุญาต BSD แบบ 2 ข้อ) (ชุดยูทิลิตี้คอนโซลและไลบรารี่สำหรับพัฒนายูทิลิตี้หรือปลั๊กอินแบบกำหนดเอง) สำหรับจัดการสตรีม TS เป็นอินพุต สามารถทำงานร่วมกับ IP (มัลติคาสต์/ยูนิคาสต์), http, hls, dvb tuners, dektec dvb-asi demodulator มีตัวสร้างสตรีม TS ภายในและอ่านจากไฟล์ เอาต์พุตสามารถเขียนไปยังไฟล์, IP (มัลติคาสต์/ยูนิคาสต์), hls, โมดูเลเตอร์ dektec dvb-asi และ HiDes, เครื่องเล่น (mplayer, vlc, xine) และดรอป ตัวประมวลผลการรับส่งข้อมูลต่างๆ สามารถรวมระหว่างอินพุตและเอาต์พุตได้ เช่น การแมป PID ใหม่ การสแครมบลิง/ดีสแครมบลิง การวิเคราะห์ตัวนับ CC การคำนวณบิตเรต และการดำเนินการทั่วไปอื่นๆ สำหรับสตรีม TS

ในบทความนี้จะใช้สตรีม IP (มัลติคาสต์) เป็นอินพุต โปรเซสเซอร์ bitrate_monitor (จากชื่อเป็นที่ชัดเจนว่าคืออะไร) และความต่อเนื่อง (การวิเคราะห์ตัวนับ CC) คุณสามารถแทนที่ IP multicast ด้วยอินพุตประเภทอื่นที่รองรับโดย TSDuck ได้อย่างง่ายดาย

มีอยู่ สร้าง / แพ็คเกจอย่างเป็นทางการ TSDuck สำหรับระบบปฏิบัติการปัจจุบันส่วนใหญ่ ไม่มีให้บริการสำหรับ Debian แต่เราสามารถสร้างภายใต้เดเบียน 8 และเดเบียน 10 ได้โดยไม่มีปัญหาใด ๆ

ถัดไป ใช้เวอร์ชัน TSDuck 3.19-1520, Linux ใช้เป็น OS (ใช้ debian 10 เพื่อเตรียมโซลูชัน, ใช้ CentOS 7 สำหรับการใช้งานจริง)

กำลังเตรียม TSDuck และ OS

ก่อนตรวจสอบกระแสจริง คุณต้องแน่ใจว่า TSDuck ทำงานได้อย่างถูกต้องและไม่มีการตกที่ระดับการ์ดเครือข่ายหรือระบบปฏิบัติการ (ซ็อกเก็ต) สิ่งนี้จำเป็นเพื่อไม่ให้คาดเดาในภายหลังว่าเกิดการหยดที่ใด - บนเครือข่ายหรือ "ภายในเซิร์ฟเวอร์" คุณสามารถตรวจสอบการลดลงที่ระดับการ์ดเครือข่ายด้วยคำสั่ง ethtool -S ethX การปรับแต่งทำได้โดย ethtool เดียวกัน (โดยปกติแล้ว คุณต้องเพิ่มบัฟเฟอร์ RX (-G) และบางครั้งปิดใช้งานออฟโหลดบางส่วน (-K)) ตามคำแนะนำทั่วไป ขอแนะนำให้ใช้พอร์ตแยกต่างหากเพื่อรับทราฟฟิกที่วิเคราะห์ ถ้าเป็นไปได้ วิธีนี้จะลดผลบวกปลอมที่เกี่ยวข้องกับข้อเท็จจริงที่ว่าการลดลงนั้นเกิดขึ้นบนพอร์ตวิเคราะห์เนื่องจากการมีอยู่ของทราฟฟิกอื่นๆ หากไม่สามารถทำได้ (ใช้มินิคอมพิวเตอร์/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 #настраиваем маршрут по умолчанию внутри 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

สภาพแวดล้อมพร้อม เราเริ่มตัววิเคราะห์ทราฟฟิก:

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" หมายความว่าคุณต้องคำนวณบิตเรตทุกวินาทีและแสดงข้อมูลเกี่ยวกับบิตเรตทุกวินาที
เราเริ่มตัวสร้างทราฟฟิกด้วยความเร็ว 10Mbps:

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) และพยายามเพิ่มบิตเรตของตัวสร้างเป็น 100Mbps ตัววิเคราะห์รายงานข้อผิดพลาด CC จำนวนมากและประมาณ 75 Mbps แทนที่จะเป็น 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

อย่างที่คุณเห็น มีการสร้างแพ็กเก็ต IP ถึง 100000 แพ็กเก็ต (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 KB แต่ถ้าแอปพลิเคชันร้องขอมากกว่านี้ ก็จะยังคงไม่ได้รับสิ่งที่ร้องขอ เนื่องจากคุณสามารถกำหนดขนาดบัฟเฟอร์ใน 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

ด้วยการปรับซ็อกเก็ตบัฟเฟอร์นี้ ตอนนี้บิตเรตที่รายงานคือประมาณ 100Mbps ไม่มีข้อผิดพลาด CC

ตามการใช้งาน CPU ของแอปพลิเคชัน tsp เอง เมื่อเทียบกับหนึ่งคอร์ i5-4260U CPU @ 1.40GHz การวิเคราะห์โฟลว์ 10Mbps จะต้องใช้ CPU 3-4%, 100Mbps - 25%, 200Mbps - 46% เมื่อตั้งค่า % Packet Loss ภาระบน CPU จะไม่เพิ่มขึ้น (แต่อาจลดลง)

บนฮาร์ดแวร์ที่มีประสิทธิภาพมากขึ้น สามารถสร้างและวิเคราะห์สตรีมที่มีความเร็วมากกว่า 1Gb/s ได้โดยไม่มีปัญหาใดๆ

การทดสอบบนการ์ดเครือข่ายจริง

หลังจากทดสอบคู่ veth คุณต้องใช้สองโฮสต์หรือสองพอร์ตของโฮสต์หนึ่ง เชื่อมต่อพอร์ตเข้าด้วยกัน เริ่มตัวสร้างที่หนึ่ง และวิเคราะห์ที่ที่สอง ไม่มีความประหลาดใจที่นี่ แต่ในความเป็นจริงทั้งหมดขึ้นอยู่กับเหล็ก ยิ่งอ่อนแอ ก็ยิ่งน่าสนใจมากขึ้นเท่านั้น

การใช้ข้อมูลที่ได้รับจากระบบตรวจสอบ (Zabbix)

tsp ไม่มี API ที่เครื่องอ่านได้เช่น SNMP หรือที่คล้ายกัน ข้อความ CC ต้องรวมกันเป็นเวลาอย่างน้อย 1 วินาที (ด้วยเปอร์เซ็นต์การสูญเสียแพ็กเก็ตที่สูง อาจมีหลายร้อย/พัน/หมื่นต่อวินาที ขึ้นอยู่กับบิตเรต)

ดังนั้น เพื่อบันทึกทั้งข้อมูลและวาดกราฟสำหรับข้อผิดพลาด CC และบิตเรต และทำให้เกิดอุบัติเหตุบางประเภท อาจมีตัวเลือกต่อไปนี้:

  1. แยกวิเคราะห์และรวม (โดย CC) ผลลัพธ์ของ tsp เช่น แปลงเป็นรูปแบบที่ต้องการ
  2. เสร็จสิ้น tsp เองและ/หรือปลั๊กอินตัวประมวลผล bitrate_monitor และความต่อเนื่อง เพื่อให้ผลลัพธ์ได้รับในรูปแบบที่เครื่องอ่านได้ซึ่งเหมาะสำหรับระบบการตรวจสอบ
  3. เขียนใบสมัครของคุณบนไลบรารี tsduck

เห็นได้ชัดว่าตัวเลือกที่ 1 นั้นง่ายที่สุดในแง่ของค่าแรงโดยเฉพาะอย่างยิ่งเมื่อพิจารณาว่า tsduck นั้นเขียนด้วยภาษาระดับต่ำ (ตามมาตรฐานสมัยใหม่) (C ++)

ตัวอย่าง bash parser+aggregator อย่างง่ายแสดงให้เห็นว่าในสตรีม 10Mbps และการสูญเสียแพ็กเก็ต 50% (กรณีที่แย่ที่สุด) กระบวนการ bash ใช้ CPU มากกว่าตัวกระบวนการ tsp 3-4 เท่า สถานการณ์นี้ยอมรับไม่ได้ จริง ๆ แล้วชิ้นส่วนของต้นแบบนี้ด้านล่าง

ก๋วยเตี๋ยวอยู่ข้างบน

#!/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 งาน bash เป็นกระบวนการที่แยกจากกัน และฉันต้องเขียนค่าของ missPackets หนึ่งครั้งต่อวินาทีในผลข้างเคียง (เมื่อได้รับข้อความบิตเรตที่มาทุกๆ วินาที) เป็นผลให้ bash ถูกทิ้งให้อยู่คนเดียวและตัดสินใจเขียน wrapper (parser + aggregator) ใน golang การใช้ CPU ของรหัส golang ที่คล้ายกันนั้นน้อยกว่ากระบวนการ tsp 4-5 เท่า ความเร็วของ wrapper เนื่องจากการแทนที่ bash ด้วย golang กลายเป็นประมาณ 16 เท่าและโดยทั่วไปผลลัพธ์ก็เป็นที่ยอมรับ (โอเวอร์เฮดของ CPU เพิ่มขึ้น 25% ในกรณีที่เลวร้ายที่สุด) ไฟล์ต้นฉบับ golang อยู่ ที่นี่.

เรียกใช้กระดาษห่อ

ในการเริ่มต้น wrapper ได้สร้างเทมเพลตบริการที่ง่ายที่สุดสำหรับ systemd (ที่นี่). ตัวห่อหุ้มควรจะรวบรวมเป็นไฟล์ไบนารี (ไปสร้าง tsduck-stat.go) ซึ่งอยู่ใน /opt/tsduck-stat/ สันนิษฐานว่าคุณกำลังใช้ golang ที่รองรับนาฬิกาโมโนโทนิก (>=1.9)

ในการสร้างอินสแตนซ์ของบริการ คุณต้องรันคำสั่ง systemctl enable [ป้องกันอีเมล]:1234 จากนั้นรันด้วย systemctl start [ป้องกันอีเมล]: 1234

การค้นพบจาก Zabbix

เพื่อให้ zabbix สามารถค้นพบบริการที่กำลังทำงานอยู่ได้ เครื่องกำเนิดรายชื่อกลุ่ม (discovery.sh) ในรูปแบบที่จำเป็นสำหรับการค้นพบ Zabbix จะถือว่าอยู่ในที่เดียวกัน - ใน /opt/tsduck-stat หากต้องการเรียกใช้การค้นพบผ่าน zabbix-agent คุณต้องเพิ่ม ไฟล์ .conf ไปยังไดเร็กทอรีคอนฟิกูเรชัน zabbix-agent เพื่อเพิ่มพารามิเตอร์ผู้ใช้

เทมเพลต Zabbix

เทมเพลตที่สร้างขึ้น (tsduck_stat_template.xml) มีกฎการค้นหาอัตโนมัติ ต้นแบบรายการ กราฟ และทริกเกอร์

รายการตรวจสอบสั้น ๆ (จะเกิดอะไรขึ้นถ้ามีคนตัดสินใจใช้)

  1. ตรวจสอบให้แน่ใจว่า tsp ไม่ดรอปแพ็กเก็ตภายใต้เงื่อนไข "อุดมคติ" (ตัวสร้างและตัววิเคราะห์เชื่อมต่อโดยตรง) หากมีการดรอป โปรดดูย่อหน้าที่ 2 หรือข้อความของบทความเกี่ยวกับเรื่องนี้
  2. ทำการปรับแต่งบัฟเฟอร์ซ็อกเก็ตสูงสุด (net.core.rmem_max=8388608)
  3. รวบรวม tsduck-stat.go (ไปสร้าง tsduck-stat.go)
  4. ใส่เทมเพลตบริการใน /lib/systemd/system
  5. เริ่มบริการด้วย systemctl ตรวจสอบว่าตัวนับเริ่มปรากฏขึ้น (grep "" /dev/shm/tsduck-stat/*) จำนวนบริการตามจำนวนสตรีมแบบหลายผู้รับ ที่นี่ คุณอาจต้องสร้างเส้นทางไปยังกลุ่มมัลติคาสต์ อาจปิดใช้งาน rp_filter หรือสร้างเส้นทางไปยัง IP ต้นทาง
  6. เรียกใช้ Discovery.sh ตรวจสอบให้แน่ใจว่ามันสร้าง json
  7. เพิ่มการกำหนดค่าตัวแทน zabbix รีสตาร์ทตัวแทน zabbix
  8. อัปโหลดเทมเพลตไปที่ zabbix ใช้กับโฮสต์ที่กำลังตรวจสอบและติดตั้ง zabbix-agent รอประมาณ 5 นาที ดูว่ามีรายการ กราฟ และทริกเกอร์ใหม่หรือไม่

ผล

ใช้ TSDuck เพื่อตรวจสอบสตรีม IP (TS)

สำหรับงานตรวจจับการสูญหายของแพ็กเก็ตนั้นเพียงพอแล้ว อย่างน้อยก็ดีกว่าไม่มีการตรวจสอบ

แท้จริงแล้ว "การสูญเสีย" ของ CC สามารถเกิดขึ้นได้เมื่อรวมส่วนย่อยของวิดีโอ (เท่าที่ฉันรู้ นี่คือวิธีการแทรกที่ศูนย์ทีวีท้องถิ่นในสหพันธรัฐรัสเซีย เช่น โดยไม่ต้องคำนวณตัวนับ CC ใหม่) สิ่งนี้จะต้องถูกจดจำ โซลูชันที่เป็นกรรมสิทธิ์สามารถหลีกเลี่ยงปัญหานี้ได้บางส่วนโดยการตรวจจับฉลาก SCTE-35 (หากเพิ่มโดยเครื่องสร้างสตรีม)

ในแง่ของการตรวจสอบคุณภาพการขนส่ง ขาดการตรวจสอบความกระวนกระวายใจ (IAT) อุปกรณ์ทีวี (ไม่ว่าจะเป็นโมดูเลเตอร์หรืออุปกรณ์ปลายทาง) มีข้อกำหนดสำหรับพารามิเตอร์นี้ และไม่สามารถขยาย jitbuffer ให้ใหญ่ขึ้นได้เสมอไป และความกระวนกระวายใจสามารถลอยได้เมื่อใช้อุปกรณ์ที่มีบัฟเฟอร์ขนาดใหญ่ในระหว่างการขนส่ง และ QoS ไม่ได้รับการกำหนดค่าหรือกำหนดค่าไม่ดีพอที่จะส่งทราฟฟิกแบบเรียลไทม์ดังกล่าว

ที่มา: will.com

เพิ่มความคิดเห็น