يحدث انقسام آثار التتبع عند الجمع بين تطبيقات مجهزة بـ OpenTelemetry وشبكة خدمات تعتمد على Istio لأن Envoy قد ينشئ أثراً جذرياً جديداً بدلاً من متابعة السياق الوارد من التطبيق. ويقترح إسرائيل بلانكاس، مهندس برمجيات في Coralogix، وخوسيه غوميز-سيليس، قائد المنتج في VictoriaMetrics، معالجة عملية تجمع بين ضبط انتشار السياق، واستخدام ممرر OpenTelemetry كنقطة التقاء، وتوجيه آثار Envoy إلى مستقبل Zipkin.
تستند الإرشادات إلى بيئة OpenTelemetry Demo التي تستخدم Jaeger وOpenTelemetry Collector، مع إضافة Istio وKiali لمراقبة الشبكة. وفي هذه البيئة تكون المقاييس والسجلات مفيدة، لكن آثار التتبع لا تظهر كمسار واحد ما لم تُوحَّد طريقة تمرير السياق بين التطبيق والـ sidecar.
ما الذي توفره Istio قبل ظهور المشكلة؟
تمنح Istio فرق المنصات رؤية فورية تقريباً لحركة المرور بين الخدمات من دون تعديل كبير في كود التطبيقات. وبعد حقن الـ sidecars، يمكن الحصول على عناصر مثل:
- حجم الطلبات بين الخدمات.
- زمن الاستجابة ومعدل الأخطاء لكل حمل عمل.
- عرض طبولوجيا الخدمات عبر Kiali.
- سجلات الوصول الصادرة عن الوكلاء الوسيطين.
تساعد هذه البيانات في تحديد ما إذا كانت حركة المرور تعمل، وأين تتركز الأخطاء، وما إذا كانت إحدى القفزات بين الخدمات تضيف زمناً إلى الطلب. لكنها لا تجيب وحدها عن سؤال أكثر تحديداً، مثل سبب فشل طلب مستخدم بعينه بعد أن استدعت خدمة checkout خدمة product-catalog مرتين وأعادت المحاولة إثر مهلة انتظار.
المشكلة هي تجزؤ البيانات لا نقصها
قبل تثبيت Istio، تعرض Jaeger آثاراً كاملة من البداية إلى النهاية عبر خدمات العرض التجريبي، لأن التطبيقات تستخدم حزمة OpenTelemetry وتنشر السياق باستخدام ترويسات W3C Trace Context. وبعد إضافة sidecars وتفعيل تتبع Envoy، تبقى البيانات متاحة، لكنها تظهر في شجرتي تتبع منفصلتين.
قد يظهر في Jaeger اسما خدمتين متشابهتين، مثل checkout القادمة من OpenTelemetry SDK داخل التطبيق، وcheckout.otel-demo القادمة من Envoy sidecar. وتبدو النتيجة للوهلة الأولى وكأنها رؤية إضافية، لكنها في الواقع أثران غير مرتبطين للطلب نفسه: أحدهما يصف منطق العمل واستدعاءات RPC وقواعد البيانات، والآخر يصف قفزات الوكيل وزمن الشبكة وإعادات المحاولة.
يرجع الانقسام أساساً إلى انتشار السياق. فعندما لا يستخرج Envoy السياق الوارد نفسه أو لا يواصل الأثر الموجود، ينشئ span جذرياً جديداً. لذلك لا يكفي أن تكون كل أداة مضبوطة بصورة صحيحة منفردة؛ يجب أن تتحدث مكونات التطبيق والشبكة اللغة نفسها عند تمرير ترويسات التتبع.
دور Collector واختيار صيغة التتبع
يقترح الدليل التعامل مع OpenTelemetry Collector باعتباره نقطة التقاء بين التطبيق والشبكة، لا مجرد وجهة تصدير. فالتطبيقات ترسل بيانات OTLP إلى Collector، بينما يحتاج Collector أيضاً إلى استقبال صيغة التتبع التي يستطيع Envoy استخدامها لاستخراج السياق بطريقة متوافقة.
في الإعداد المعروض، يتطلب الأمر أولاً تعريف خدمة والمنفذ 4317 لممرر OpenTelemetry ضمن إعداد Istio، ثم توجيه Envoy إلى مستقبل Zipkin في Collector عبر المنفذ 9411. ويُنصح كذلك بتفعيل تتبع Istio واستخدام Zipkin tracer في Envoy، لأن هذا المسار يستخرج سياق B3 من الطلبات الواردة وينشئ spans فرعية تحت الأثر القائم بدلاً من بدء أثر جديد.
لا يعني ذلك أن تغيير Envoy وحده يكفي. فالتطبيقات يجب أن تنشر أيضاً ترويسات B3 إلى جانب tracecontext وbaggage. وفي OpenTelemetry Demo يمكن تحقيق ذلك عبر ضبط المتغير OTEL_PROPAGATORS ليشمل tracecontext,baggage,b3multi. وبهذا تحافظ التطبيقات على ترويسات W3C القياسية، وتضيف ترويسات B3 التي يستطيع Envoy استخدامها لمتابعة الأثر نفسه.
النتيجة العملية
بعد تطبيق التعديلات، لا يعود Jaeger يعرض أثراً منفصلاً للتطبيق وآخر للـ sidecar، بل يجمع spans التطبيق والشبكة في أثر واحد. وفي المثال الوارد في المادة، ارتفع عدد الـ spans الظاهرة معاً لخدمة checkout من مجموعات تقارب 14 أو 2 span إلى ما بين 51 و75 span ضمن الأثر نفسه.
يضم الأثر الموحد بيانات منطق العمل والاستدعاءات اللاحقة، إلى جانب قفزات الوكلاء وتأخيرات الشبكة وإعادات المحاولة، مع معرّف أثر واحد يغطي مسار الطلب. ويجعل ذلك البيانات أكثر فائدة عند تصحيح طلب فعلي، بدلاً من الاكتفاء بمعرفة أن الشبكة تبدو غير سليمة.
لماذا يظل Collector محورياً؟
توضح المادة أن اختلاف الإصدارات والافتراضات الافتراضية بين المشاريع قد يكسر التتبع حتى عندما يكون التطبيق وCollector وJaeger مضبوطين بصورة صحيحة كل على حدة. وفي الحالة المدروسة، كان Envoy يستخدم ممرر OpenTelemetry المدمج الذي ينشئ span جذرياً جديداً لكل طلب ولا يقرأ ترويسة traceparent الواردة بالطريقة المطلوبة.
كان استخدام Zipkin/B3 في Envoy نصف الحل فقط؛ أما النصف الآخر فتمثل في وجود نقطة تستقبل الصيغ المختلفة وتحوّلها إلى نموذج OpenTelemetry موحد ثم تصدرها إلى الخلفية نفسها. ووفق الدليل، يمكن لهذا النمط أن يخدم أيضاً تغييرات الاصطلاحات الدلالية، وأخذ العينات، والتحكم في عدد القيم المميزة، وتوليد مقاييس من الـ spans، وحجب المعلومات، والتصدير إلى عدة خلفيات في الوقت نفسه.