خدمة البحث عن المفقودين ، OpenTracing و Jaeger

خدمة البحث عن المفقودين ، OpenTracing و Jaeger

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

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

ما هي المشاكل التي يمكن حلها مع التعقب

  1. ابحث عن معوقات الأداء داخل خدمة واحدة وفي شجرة التنفيذ بأكملها بين جميع الخدمات المشاركة. على سبيل المثال:
    • العديد من المكالمات القصيرة المتتالية بين الخدمات ، على سبيل المثال ، إلى الترميز الجغرافي أو إلى قاعدة البيانات.
    • عمليات انتظار طويلة للإدخال / الإخراج ، مثل عمليات النقل عبر الشبكة أو قراءات القرص.
    • تحليل البيانات الطويلة.
    • عمليات طويلة تتطلب وحدة المعالجة المركزية.
    • أقسام الكود غير الضرورية للحصول على النتيجة النهائية ويمكن إزالتها أو تأخيرها.
  2. افهم بوضوح في تسلسل ما يسمى وما يحدث عند إجراء العملية.
    خدمة البحث عن المفقودين ، OpenTracing و Jaeger
    يمكن ملاحظة أنه ، على سبيل المثال ، جاء الطلب إلى خدمة WS -> استكملت خدمة WS البيانات من خلال خدمة R -> ثم أرسلت طلبًا إلى خدمة V -> قامت خدمة V بتحميل الكثير من البيانات من خدمة R -> انتقلت إلى خدمة P -> ذهبت خدمة P مرة أخرى إلى الخدمة R -> تجاهلت الخدمة V النتيجة وذهبت إلى الخدمة J -> وعندها فقط أعادت الاستجابة للخدمة WS ، مع الاستمرار في حساب شيء آخر في الخلفية.
    بدون مثل هذا التتبع أو التوثيق التفصيلي للعملية بأكملها ، من الصعب جدًا فهم ما يحدث عند النظر إلى الكود لأول مرة ، ويكون الرمز مبعثرًا عبر خدمات مختلفة ومخبأ خلف مجموعة من الصناديق والواجهات.
  3. جمع المعلومات حول شجرة التنفيذ للتحليل المؤجل اللاحق. في كل مرحلة من مراحل التنفيذ ، يمكنك إضافة معلومات إلى التتبع المتاح في هذه المرحلة ثم معرفة بيانات الإدخال التي أدت إلى سيناريو مشابه. على سبيل المثال:
    • معرف المستخدم
    • حقوق
    • نوع الطريقة المختارة
    • خطأ في السجل أو التنفيذ
  4. تحويل الآثار إلى مجموعة فرعية من المقاييس وإجراء مزيد من التحليل بالفعل في شكل مقاييس.

ما يمكن تتبع تسجيل الدخول. فترة

في التتبع يوجد مفهوم الامتداد ، هذا تناظري لسجل واحد ، إلى وحدة التحكم. يحتوي المنتجع الصحي على:

  • الاسم ، وعادة ما يكون اسم الطريقة التي تم تنفيذها
  • اسم الخدمة التي تم إنشاء النطاق فيها
  • معرّف فريد خاص بك
  • نوع من المعلومات الوصفية في شكل مفتاح / قيمة تم تسجيل الدخول إليها. على سبيل المثال ، معلمات الطريقة أو الطريقة انتهت بخطأ أم لا
  • أوقات البدء والانتهاء لهذه الفترة
  • معرف امتداد الوالدين

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

خدمة البحث عن المفقودين ، OpenTracing و Jaeger

أوبنتريس وجاغر وكيف نفذناها لمشاريعنا

هناك معيار مشترك العبرة، الذي يصف كيف وماذا يجب أن يتم جمعه ، دون أن يتم تقييده من خلال تتبع تنفيذ معين بأي لغة. على سبيل المثال ، في Java ، يتم تنفيذ كل الأعمال مع الآثار من خلال Opentrace API المشترك ، وتحتها ، على سبيل المثال ، يمكن إخفاء Jaeger أو تطبيق افتراضي فارغ لا يفعل شيئًا.
نحن نستخدم جيجر كتنفيذ لأوبينتريس. يتكون من عدة مكونات:

خدمة البحث عن المفقودين ، OpenTracing و Jaeger

  • Jaeger-agent هو وكيل محلي يتم تثبيته عادةً على كل جهاز ويتم تسجيل الخدمات فيه على المنفذ الافتراضي المحلي. إذا لم يكن هناك وكيل ، فعادة ما يتم تعطيل آثار جميع الخدمات على هذا الجهاز
  • Jaeger-Collector - يرسل جميع الوكلاء آثارًا مجمعة إليه ، ويضعهم في قاعدة البيانات المحددة
  • قاعدة البيانات هي كاساندرا المفضلة لديهم ، لكننا نستخدم elasticsearch ، وهناك تطبيقات لبضع قواعد بيانات أخرى وتنفيذ في الذاكرة لا يحفظ أي شيء على القرص
  • Jaeger-query هي خدمة تذهب إلى قاعدة البيانات وترجع الآثار التي تم جمعها بالفعل للتحليل
  • Jaeger-ui هي واجهة ويب للبحث عن الآثار وعرضها ، وهي تذهب إلى jaeger-query

خدمة البحث عن المفقودين ، OpenTracing و Jaeger

يمكن تسمية مكون منفصل بتنفيذ opentrace jaeger للغات معينة ، والتي من خلالها يتم إرسال الامتدادات إلى jaeger-agent.
ربط جاغر بجافا يتعلق الأمر بتنفيذ واجهة io.opentracing.Tracer ، وبعد ذلك ستنتقل جميع آثاره إلى الوكيل الحقيقي.

خدمة البحث عن المفقودين ، OpenTracing و Jaeger

أيضا بالنسبة لمكون الربيع ، يمكنك الاتصال opentracing الربيع سحابة كاتب والتنفيذ من جايجر opentracing الربيع جايجر سحابة كاتب والتي ستقوم تلقائيًا بتكوين التتبع لكل ما يمر عبر هذه المكونات ، على سبيل المثال طلبات http إلى وحدات التحكم ، والطلبات إلى قاعدة البيانات من خلال jdbc ، إلخ.

تتبع تسجيل الدخول في جافا

في مكان ما في المستوى الأعلى ، يجب إنشاء أول Span ، ويمكن القيام بذلك تلقائيًا ، على سبيل المثال ، عن طريق وحدة التحكم الزنبركية عند تلقي طلب ، أو يدويًا إذا لم يكن هناك أي طلب. ثم يتم نقله من خلال النطاق أدناه. إذا كانت أي من الطرق أدناه تريد إضافة Span ، فإنه يأخذ activeSpan الحالي من النطاق ، وينشئ Span جديدًا ويقول أن أصله هو activeSpan الناتج ، ويجعل Span الجديد نشطًا. عند الاتصال بالخدمات الخارجية ، يتم تمرير النطاق النشط الحالي إليها ، وتقوم هذه الخدمات بإنشاء نطاقات جديدة بالإشارة إلى هذا النطاق.
يمر كل العمل عبر مثيل Tracer ، يمكنك الحصول عليه من خلال آلية DI ، أو GlobalTracer.get () كمتغير عام إذا لم تعمل آلية DI. بشكل افتراضي ، إذا لم يتم تهيئة التتبع ، فسيعود NoopTracer وهو ما لا يفعل شيئًا.
علاوة على ذلك ، يتم الحصول على النطاق الحالي من المتتبع من خلال ScopeManager ، ويتم إنشاء نطاق جديد من النطاق الحالي مع ربط النطاق الجديد ، ثم يتم إغلاق النطاق الذي تم إنشاؤه ، مما يؤدي إلى إغلاق النطاق الذي تم إنشاؤه وإرجاع النطاق السابق إلى الحالة النشطة. النطاق مرتبط بخيط ، لذلك عند البرمجة متعددة الخيوط ، يجب ألا تنسى نقل الامتداد النشط إلى مؤشر ترابط آخر ، لمزيد من التنشيط لنطاق مؤشر ترابط آخر مع الإشارة إلى هذا النطاق.

io.opentracing.Tracer tracer = ...; // GlobalTracer.get()

void DoSmth () {
   try (Scope scope = tracer.buildSpan("DoSmth").startActive(true)) {
      ...
   }
}
void DoOther () {
    Span span = tracer.buildSpan("someWork").start();
    try (Scope scope = tracer.scopeManager().activate(span, false)) {
        // Do things.
    } catch(Exception ex) {
        Tags.ERROR.set(span, true);
        span.log(Map.of(Fields.EVENT, "error", Fields.ERROR_OBJECT, ex, Fields.MESSAGE, ex.getMessage()));
    } finally {
        span.finish();
    }
}

void DoAsync () {
    try (Scope scope = tracer.buildSpan("ServiceHandlerSpan").startActive(false)) {
        ...
        final Span span = scope.span();
        doAsyncWork(() -> {
            // STEP 2 ABOVE: reactivate the Span in the callback, passing true to
            // startActive() if/when the Span must be finished.
            try (Scope scope = tracer.scopeManager().activate(span, false)) {
                ...
            }
        });
    }
}

بالنسبة للبرمجة متعددة الخيوط ، هناك أيضًا TracedExecutorService وأغلفة مماثلة تقوم تلقائيًا بإعادة توجيه النطاق الحالي إلى مؤشر الترابط عند تشغيل المهام غير المتزامنة:

private ExecutorService executor = new TracedExecutorService(
    Executors.newFixedThreadPool(10), GlobalTracer.get()
);

لطلبات http الخارجية هناك TracingHttpClient

HttpClient httpClient = new TracingHttpClientBuilder().build();

المشاكل التي واجهناها

  • لا تعمل Beans و DI دائمًا إذا لم يتم استخدام التتبع في خدمة أو مكون ، إذن سلكي قد لا يعمل Tracer وسيتعين عليك استخدام GlobalTracer.get ().
  • لا تعمل التعليقات التوضيحية إذا لم تكن مكونًا أو خدمة ، أو إذا تم استدعاء الطريقة من طريقة مجاورة من نفس الفئة. يجب أن تكون حريصًا على التحقق مما يعمل واستخدام إنشاء التتبع اليدوي إذا لم يعملTraced. يمكنك أيضًا إرفاق مترجم إضافي لتعليقات جافا التوضيحية ، ومن ثم يجب أن تعمل في كل مكان.
  • في حذاء الربيع والربيع القديم ، لا يعمل التكوين التلقائي لسحابة الربيع الزنبركية بسبب الأخطاء في DI ، ثم إذا كنت تريد أن تعمل الآثار في مكونات الربيع تلقائيًا ، فيمكنك القيام بذلك عن طريق القياس مع github.com/opentracing-contrib/java-spring-jaeger/blob/master/opentracing-spring-jaeger-starter/src/main/java/io/opentracing/contrib/Java/spring/jaeger/starter/JaegerAutoConfiguration.java
  • حاول باستخدام الموارد لا يعمل بشكل رائع ، يجب عليك استخدام المحاولة أخيرًا.
  • يجب أن يكون لكل خدمة اسم spring.application.name الخاص بها والذي سيتم بموجبه تسجيل الآثار. ماذا يفعل اسم منفصل للبيع والاختبار ، حتى لا يتداخل معهما معًا.
  • إذا كنت تستخدم GlobalTracer و tomcat ، فإن جميع الخدمات التي تعمل في هذا القط لديها GlobalTracer واحد ، لذلك سيكون لديهم جميعًا نفس اسم الخدمة.
  • عند إضافة آثار إلى طريقة ما ، يجب أن تتأكد من عدم استدعائها مرات عديدة في حلقة. من الضروري إضافة تتبع مشترك واحد لجميع المكالمات ، مما يضمن إجمالي وقت العمل. خلاف ذلك ، سيتم إنشاء حمل زائد.
  • مرة واحدة في jaeger-ui ، تم تقديم طلبات كبيرة جدًا لعدد كبير من التتبع ، وبما أنهم لم ينتظروا الرد ، فعلوا ذلك مرة أخرى. نتيجة لذلك ، بدأ جايجر الاستعلام في التهام الكثير من الذاكرة وإبطاء المرونة. بمساعدة من إعادة تشغيل jaeger-query

أخذ العينات والتخزين وعرض الآثار

هناك ثلاثة أنواع آثار أخذ العينات:

  1. Const الذي يرسل ويحفظ جميع الآثار.
  2. الاحتمالية التي تقوم بتصفية الآثار مع بعض الاحتمالات المعطاة.
  3. التصنيف الذي يحد من عدد التتبع في الثانية. يمكنك تكوين هذه الإعدادات على العميل ، إما على وكيل jaeger أو على المجمع. نستخدم الآن const 1 في حزمة المُثمنين ، نظرًا لعدم وجود العديد من الطلبات ، ولكنها تستغرق وقتًا طويلاً. في المستقبل ، إذا كان هذا سيؤدي إلى زيادة الحمل على النظام ، فيمكنك الحد منه.

إذا كنت تستخدم كاساندرا ، فإنها تقوم افتراضيًا بتخزين الآثار لمدة يومين فقط. نحن نستخدم elasticsearch ويتم تخزين الآثار في جميع الأوقات ولا يتم حذفها. يتم إنشاء فهرس منفصل لكل يوم ، على سبيل المثال jaeger-service-2019-03-04. في المستقبل ، تحتاج إلى تكوين التنظيف التلقائي للآثار القديمة.

لعرض الآثار التي تحتاجها:

  • حدد الخدمة التي تريد تصفية الآثار من خلالها ، على سبيل المثال ، tomcat7-default لخدمة تعمل في القط ولا يمكن أن يكون لها اسم خاص بها.
  • ثم حدد العملية والفاصل الزمني والحد الأدنى لوقت التشغيل ، على سبيل المثال من 10 ثوانٍ ، لإجراء عمليات تنفيذ طويلة فقط.
    خدمة البحث عن المفقودين ، OpenTracing و Jaeger
  • اذهب إلى أحد الآثار وشاهد ما كان يتباطأ هناك.
    خدمة البحث عن المفقودين ، OpenTracing و Jaeger

أيضًا ، إذا كان بعض معرف الطلب معروفًا ، فيمكنك العثور على تتبع بواسطة هذا المعرف من خلال البحث في العلامات ، إذا تم تسجيل هذا المعرف في فترة التتبع.

توثيق

مقالات

فيديو

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

إضافة تعليق