استخدام TSDuck لمراقبة تدفقات IP (TS)

اليوم ، هناك حلول جاهزة (خاصة) لمراقبة تدفقات IP (TS) ، على سبيل المثال VB и iQ، لديهم مجموعة غنية من الوظائف وعادة ما يكون لدى المشغلين الكبار الذين يتعاملون مع خدمات التلفزيون مثل هذه الحلول. توضح هذه المقالة حلاً يستند إلى مشروع مفتوح المصدر TSDuck، مصمم للحد الأدنى من التحكم في تدفقات IP (TS) بواسطة عداد CC (عداد الاستمرارية) ومعدل البت. أحد التطبيقات الممكنة هو التحكم في فقد الحزم أو التدفق الكامل من خلال قناة L2 مؤجرة (والتي لا يمكن مراقبتها بشكل طبيعي ، على سبيل المثال ، من خلال قراءة عدادات الخسارة في قوائم الانتظار).

باختصار شديد حول TSDuck

TSDuck هو برنامج مفتوح المصدر (ترخيص BSD مكون من جزئين) (مجموعة من أدوات وحدة التحكم ومكتبة لتطوير أدوات مساعدة مخصصة أو مكونات إضافية) لمعالجة تدفقات TS. كمدخل ، يمكن أن يعمل مع IP (الإرسال المتعدد / الأحادي) ، http ، hls ، موالفات dvb ، مزيل التشكيل dektec dvb-asi ، يوجد مولد تيار TS داخلي والقراءة من الملفات. يمكن كتابة الإخراج إلى ملف ، IP (الإرسال المتعدد / الأحادي) ، hls ، وحدات تعديل dektec dvb-asi و HiDes ، مشغلات (mplayer ، vlc ، xine) وإسقاط. يمكن تضمين معالجات حركة المرور المختلفة بين المدخلات والمخرجات ، على سبيل المثال ، إعادة تعيين PID ، والتخليط / فك الترميز ، وتحليل عداد CC ، وحساب معدل البت ، والعمليات النموذجية الأخرى لتدفقات TS.

في هذه المقالة ، سيتم استخدام تدفقات IP (البث المتعدد) كمدخل ، ويتم استخدام معدل البت للمعالجات (من الاسم يتضح ما هو عليه) والاستمرارية (تحليل عدادات CC). يمكنك بسهولة استبدال IP multicast بنوع إدخال آخر يدعمه TSDuck.

هناك البنيات / الحزم الرسمية TSDuck لمعظم أنظمة التشغيل الحالية. إنها غير متاحة لـ Debian ، لكننا تمكنا من بنائها تحت debian 8 و debian 10 دون أي مشاكل.

بعد ذلك ، تم استخدام الإصدار TSDuck 3.19-1520 ، وتم استخدام Linux كنظام تشغيل (تم استخدام Debian 10 لإعداد الحل ، وتم استخدام CentOS 7 للاستخدام الحقيقي)

تحضير TSDuck و OS

قبل مراقبة التدفقات الحقيقية ، تحتاج إلى التأكد من أن TSDuck يعمل بشكل صحيح ولا توجد قطرات على مستوى بطاقة الشبكة أو نظام التشغيل (المقبس). هذا مطلوب حتى لا تخمن لاحقًا مكان حدوث القطرات - على الشبكة أو "داخل الخادم". يمكنك التحقق من القطرات على مستوى بطاقة الشبكة باستخدام الأمر ethtool -S ethX ، ويتم الضبط بواسطة نفس أداة ethtool (عادةً ما تحتاج إلى زيادة المخزن المؤقت RX (-G) وتعطيل بعض عمليات إلغاء التحميل (-K)). كتوصية عامة ، يمكن أن يُنصح باستخدام منفذ منفصل لتلقي حركة المرور التي تم تحليلها ، إذا كان ذلك ممكنًا ، فهذا يقلل من الإيجابيات الخاطئة المرتبطة بحقيقة أن الانخفاض حدث بالضبط على منفذ المحلل بسبب وجود حركة مرور أخرى. إذا لم يكن ذلك ممكنًا (يتم استخدام كمبيوتر صغير / NUC بمنفذ واحد) ، فمن المستحسن للغاية إعداد ترتيب أولويات حركة المرور التي تم تحليلها فيما يتعلق بالباقي على الجهاز الذي يتصل به المحلل. فيما يتعلق بالبيئات الافتراضية ، يجب أن تكون حذرًا وأن تكون قادرًا على العثور على حزم حزم تبدأ من منفذ مادي وتنتهي بتطبيق داخل جهاز افتراضي.

توليد واستقبال تيار داخل المضيف

كخطوة أولى في إعداد TSDuck ، سنقوم بإنشاء واستقبال حركة المرور داخل مضيف واحد باستخدام الشبكات.

تهيئة البيئة:

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" أنك بحاجة إلى حساب معدل البت كل ثانية وعرض معلومات حول معدل البت كل ثانية
نبدأ مولد المرور بسرعة 10 ميجابت في الثانية:

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 في حزمة IP واحدة والقيام بذلك بقوة (-e) ، أي انتظر دائمًا 1 حزم 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) وحاول زيادة معدل البت للمولد إلى 100 ميجا بت في الثانية. أبلغ المحلل عن مجموعة من أخطاء CC وحوالي 75 ميجابت في الثانية بدلاً من 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

كما ترى ، تم إنشاء 100000 حزمة IP بالضبط (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 كيلوبايت ، ولكن إذا طلبت المزيد ، فلن تتلقى ما هو مطلوب. نظرًا لأنه يمكنك ضبط حجم المخزن المؤقت في ملعقة شاي لإدخال 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

مع هذا الضبط للمخزن المؤقت للمقبس ، يبلغ الآن معدل البت الذي تم الإبلاغ عنه حوالي 100 ميجابت في الثانية ، ولا توجد أخطاء في CC.

وفقًا لاستهلاك وحدة المعالجة المركزية لتطبيق ملعقة شاي نفسها. بالنسبة إلى وحدة المعالجة المركزية i5-4260U ذات النواة الواحدة بسرعة 1.40 جيجاهرتز ، سيتطلب تحليل التدفق بسرعة 10 ميجابت في الثانية 3-4٪ من وحدة المعالجة المركزية ، و 100 ميجابت في الثانية - 25٪ ، و 200 ميجابت في الثانية - 46٪. عند تعيين٪ Packet Loss ، لا يزيد الحمل على وحدة المعالجة المركزية عمليًا (ولكن قد ينخفض).

على الأجهزة الأكثر إنتاجية ، كان من الممكن إنشاء وتحليل تدفقات تزيد سرعتها عن 1 جيجابت / ثانية دون أي مشاكل.

الاختبار على بطاقات الشبكة الحقيقية

بعد الاختبار على زوج veth ، تحتاج إلى أخذ مضيفين أو منفذين لمضيف واحد ، وتوصيل المنافذ ببعضها البعض ، وتشغيل المولد على أحدهما ، والمحلل في الثاني. لم تكن هناك مفاجآت هنا ، لكن في الحقيقة كل هذا يتوقف على الحديد ، وكلما كانت أضعف ، ستكون أكثر إثارة للاهتمام هنا.

استخدام البيانات المستلمة عن طريق نظام المراقبة (Zabbix)

لا يحتوي tsp على أي واجهة برمجة تطبيقات يمكن قراءتها آليًا مثل SNMP أو ما شابه ذلك. يجب تجميع رسائل CC لمدة ثانية واحدة على الأقل (مع وجود نسبة عالية من فقدان الحزمة ، يمكن أن يكون هناك مئات / آلاف / عشرات الآلاف في الثانية ، اعتمادًا على معدل البت).

وبالتالي ، من أجل حفظ كل من المعلومات ورسم الرسوم البيانية لأخطاء CC ومعدل البت وإحداث نوع من الحوادث ، قد تكون هناك الخيارات التالية:

  1. تحليل وتجميع (بواسطة CC) ناتج ملعقة شاي ، أي قم بتحويله إلى النموذج المطلوب.
  2. قم بإنهاء ملعقة صغيرة نفسها و / أو المكونات الإضافية للمعالج bitrate_monitor والاستمرارية بحيث يتم تقديم النتيجة في شكل يمكن قراءته آليًا ومناسب لنظام المراقبة.
  3. اكتب طلبك أعلى مكتبة tsduck.

من الواضح أن الخيار 1 هو الأسهل من حيث الجهد ، لا سيما بالنظر إلى أن tsduck نفسه مكتوب بلغة منخفضة المستوى (وفقًا للمعايير الحديثة) (C ++)

أظهر نموذج أولي بسيط لمحلل bash + مجمّع أنه في تدفق 10 ميجابت في الثانية وفقدان الحزمة بنسبة 50٪ (أسوأ حالة) ، استهلكت عملية bash 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 هي عمليات منفصلة وكان علي أن أكتب قيمة الحزم المفقودة مرة واحدة في الثانية على التأثير الجانبي (عند تلقي رسائل معدل البت التي تأتي كل ثانية). نتيجة لذلك ، تم ترك bash بمفرده وتقرر كتابة غلاف (محلل + مجمّع) في golang. استهلاك وحدة المعالجة المركزية لرمز جولانج مماثل 4-5 مرات أقل من عملية ملعقة شاي نفسها. تبين أن تسريع الغلاف الناتج عن استبدال bash بـ golang كان حوالي 16 مرة وبشكل عام النتيجة مقبولة (CPU overhead بنسبة 25٪ في أسوأ الحالات). يوجد ملف مصدر golang هنا.

تشغيل المجمع

لبدء برنامج التضمين ، تم إنشاء أبسط قالب خدمة لـ systemd (هنا). من المفترض أن يتم تجميع الغلاف نفسه في ملف ثنائي (go build tsduck-stat.go) موجود في / opt / tsduck-stat /. من المفترض أنك تستخدم golang مع دعم للساعة الرتيبة (> = 1.9).

لإنشاء مثيل للخدمة ، تحتاج إلى تشغيل الأمر systemctl enable [البريد الإلكتروني محمي]: 1234 ثم تشغيل مع بدء systemctl [البريد الإلكتروني محمي]: 1234.

اكتشاف من Zabbix

لكي يتمكن zabbix من اكتشاف الخدمات قيد التشغيل ، يتم ذلك مولد قائمة المجموعة (discovery.sh) ، بالتنسيق المطلوب لاكتشاف Zabbix ، يُفترض أنه موجود في نفس المكان - in / opt / tsduck-stat. لتشغيل الاكتشاف عبر وكيل zabbix ، تحتاج إلى إضافة ملف .conf إلى دليل تكوين وكيل zabbix لإضافة معلمة المستخدم.

قالب Zabbix

نموذج تم إنشاؤه (tsduck_stat_template.xml) يحتوي على قاعدة الاكتشاف التلقائي ونماذج العناصر والرسوم البيانية والمشغلات.

قائمة مرجعية موجزة (حسنًا ، ماذا لو قرر شخص ما استخدامها)

  1. تأكد من أن ملعقة شاي لا تسقط الحزم في ظل الظروف "المثالية" (المولد والمحلل متصلان مباشرة) ، إذا كانت هناك قطرات ، انظر الفقرة 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 ، انتظر حوالي 5 دقائق ، واعرف ما إذا كانت هناك عناصر ورسوم بيانية ومشغلات جديدة.

نتيجة

استخدام TSDuck لمراقبة تدفقات IP (TS)

بالنسبة لمهمة الكشف عن فقدان الحزمة ، فهي تكاد تكون كافية ، على الأقل أفضل من عدم المراقبة.

في الواقع ، يمكن أن تحدث "خسائر" CC عند دمج أجزاء الفيديو (على حد علمي ، هذه هي الطريقة التي يتم بها إدخال الإدخالات في مراكز التلفزيون المحلية في الاتحاد الروسي ، أي بدون إعادة حساب عداد CC) ، يجب تذكر ذلك. تتغلب الحلول الخاصة جزئيًا على هذه المشكلة عن طريق الكشف عن ملصقات SCTE-35 (إذا تمت إضافتها بواسطة مولد التيار).

من حيث مراقبة جودة النقل ، هناك نقص في مراقبة الارتعاش (IAT). تتطلب أجهزة التلفزيون (سواء كانت مُعدِّلات أو أجهزة طرفية) متطلبات هذه المعلمة وليس من الممكن دائمًا تضخيم جهاز التليفزيون إلى ما لا نهاية. ويمكن أن يطفو الارتعاش عند استخدام معدات ذات مخازن مؤقتة كبيرة أثناء النقل وعدم تكوين جودة الخدمة أو عدم تكوينها جيدًا بما يكفي لنقل حركة المرور هذه في الوقت الفعلي.

المصدر: www.habr.com

إضافة تعليق