MAISON CODE .
/ DevOps · OpenTelemetry · SRE · Monitoring · Backend

إمكانية الملاحظة: رؤية الأشعة السينية للأنظمة الموزعة

لماذا السجلات ليست كافية. دليل تقني عميق لقياس OpenTelemetry والتسجيل المنظم وفلسفة تنبيه SRE (SLI/SLO).

AB
Alex B.
إمكانية الملاحظة: رؤية الأشعة السينية للأنظمة الموزعة

“الموقع بطيء.”

هذه التذكرة المكونة من أربع كلمات هي لعنة كل فريق هندسي. بطيء أين؟ هل قاعدة البيانات مقفلة على وحدة المعالجة المركزية؟ هل شبكة الهاتف المحمول ضعيفة؟ هل انتهت مهلة واجهة برمجة تطبيقات الشحن التابعة لجهة خارجية؟ هل قمنا بنشر تعليمات برمجية سيئة بالأمس؟

إذا كانت استراتيجية تصحيح الأخطاء لديك تعتمد على “console.log” والتحقق من الرسوم البيانية لوحدة المعالجة المركزية للخادم، فأنت تقوم بتصحيح الأخطاء في الظلام. المراقبة تخبرك بأن النظام معطل (لوحة المعلومات الحمراء). قابلية الملاحظة تخبرك لماذا انكسرت.

في Maison Code Paris، نقوم بتشغيل منصات تجارية ذات حركة مرور عالية حيث تعادل دقيقة واحدة من التوقف عشرات الآلاف من اليورو. نحن لا نخمن. نحن نستخدم أدوات التعليمات البرمجية للحصول على رؤية الأشعة السينية في المكدس الموزع.

لماذا تتحدث Maison Code عن هذا

في Maison Code Paris، نعمل كضمير معمari لعملائنا. غالبًا ما نرث حزمًا “حديثة” تم بناؤها دون فهم أساسي للحجم.

نناقش هذا الموضوع لأنه يمثل نقطة تحول حاسمة في النضج الهندسي. التنفيذ الصحيح يميز MVP الهش عن منصة مؤسسية مرنة يمكنها التعامل مع حركة مرور الجمعة السوداء.

الركائز الثلاث لقابلية الملاحظة

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

  1. السجلات: أحداث منفصلة. “حدث شيء ما في الساعة 10:00:01.”
  2. المقاييس: الأرقام المجمعة. “كانت وحدة المعالجة المركزية 80% لمدة 5 دقائق.”
  3. الآثار: دورة حياة الطلب. “نقر المستخدم على الزر -> API -> DB -> API -> UI.”

1. السجلات: منظمة وقابلة للبحث

يحب المطورون console.log("لم يتم العثور على مستخدم خطأ" + id). DevOps يكرهون ذلك. في النظام الذي ينتج 1000 سجل في الثانية، يكون البحث عن “خطأ المستخدم” بطيئًا. تحليل ذلك أمر مستحيل. لا يمكنك رسم بياني “معدل الخطأ لكل معرف مستخدم”.

القاعدة الذهبية: يجب أن تكون السجلات JSON منظمة.

{
  "المستوى": "خطأ"،
  "message": "انتهت مهلة بوابة الدفع",
  "الطابع الزمني": "23-10-2025T14:00:00Z",
  "الخدمة": "واجهة برمجة تطبيقات الخروج"،
  "السياق": {
    "معرف المستخدم": "u_123"،
    "معرف سلة التسوق": "c_456"،
    "البوابة": "شريط"،
    "الكمون": 5002
  },
  "معرف التتبع": "a1b2c3d4e5f6"
}

الآن، في أدوات مثل Datadog أو ELK (Elasticsearch)، يمكنك تشغيل الاستعلامات:

  • الخدمة: checkout-api @context.gateway:stripe @level:error
  • “أرني رسمًا بيانيًا لأخطاء الدفع مجمعة حسب البوابة.”

2. المقاييس: النبض

المقاييس رخيصة للتخزين. إنها مجرد أرقام.

  • العدادات: “إجمالي الطلبات” (يرتفع).
  • المقاييس: “استخدام الذاكرة” (يرتفع لأعلى ولأسفل).
  • الرسوم البيانية: “توزيع زمن الوصول” (95% من الطلبات < 200 مللي ثانية).

فخ الكاردينالية: يحاول المهندسون المبتدئون في كثير من الأحيان وضع علامة على المقاييس ببيانات ذات صلة عالية. http_request_duration_thans{user_id="u_123"}. إذا كان لديك مليون مستخدم، فيمكنك إنشاء مليون سلسلة زمنية. سيؤدي هذا إلى تعطل خادم Prometheus الخاص بك أو إفلاس حساب Datadog الخاص بك. القاعدة: المقاييس مخصصة لـ سلامة النظام. السجلات/الآثار مخصصة لـ مواصفات المستخدم.

3. التتبع: السياق

في الخدمات المصغرة أو البنية بدون رأس، تؤدي نقرة مستخدم واحدة إلى: CDN -> وظيفة الحافة -> Node API -> قاعدة البيانات -> واجهة برمجة تطبيقات الطرف الثالث. إذا استغرق الطلب 3 ثوانٍ، فسيظهر المقياس “زمن الاستجابة مرتفع”. التتبع يظهر لك:

  • واجهة برمجة تطبيقات العقدة: 10 مللي ثانية
  • قاعدة البيانات: 5 مللي ثانية
  • واجهة برمجة تطبيقات الشحن: 2900 مللي ثانية

التتبع يحل “لعبة اللوم”.

القياس عن بعد المفتوح: معيار الصناعة

تاريخيًا، كان عليك تثبيت Datadog SDK، أو New Relic SDK. إذا أردت تبديل الموردين، كان عليك إعادة كتابة التعليمات البرمجية. القياس المفتوح (OTel) هو المعيار المفتوح (CNCF) لجمع القياس عن بعد. يمكنك استخدام الكود الخاص بك مرة واحدة مع OTel. يمكنك بعد ذلك توجيه هذه البيانات إلى Datadog أو Prometheus أو Jaeger أو فقط “stdout”.

أجهزة Node.js التلقائية

تسمح شركة OTel الحديثة “بالأجهزة التلقائية”. لا يمكنك إعادة كتابة معالجات Express الخاصة بك. يقوم بتصحيح المكتبات القياسية (http، pg، redis) في وقت التشغيل.

// الأجهزة.ts
استيراد {NodeSDK} من '@opentelemetry/sdk-node'؛
استيراد {HttpInstrumentation} من '@opentelemetry/instrumentation-http'؛
استيراد {PgInstrumentation} من '@opentelemetry/instrumentation-pg'؛
استيراد { OTLPTraceExporter } من '@opentelemetry/exporter-trace-otlp-proto'؛

const sdk = new NodeSDK({
  TraceExporter: جديد OTLPTraceExporter({
    عنوان url: "https://api.honeycomb.io/v1/traces"، // أو جامعك
  }),
  الأجهزة: [
    new HttpInstrumentation(), // يتتبع كل HTTP الوارد/الصادر
    new PgInstrumentation(), // يتتبع جميع استعلامات Postgres

  اسم الخدمة: "maison-code-api"،
});

sdk.start();

باستخدام هذا الملف المكون من 20 سطرًا، سيكون لديك على الفور مخططات انحدارية لكل استعلام قاعدة بيانات واستدعاء واجهة برمجة التطبيقات (API) في نظام الإنتاج الخاص بك.

تتبع انتشار السياق

كيف تعرف قاعدة البيانات “نقر المستخدم” الذي تسبب في الاستعلام؟ ** نشر السياق **. عندما تستدعي الخدمة “أ” الخدمة “ب”، فإنها تُدخل رأس HTTP عامًا: “Traceparent”. التتبع: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01

تقرأ الخدمة “ب” هذا الرأس. يبدأ نطاقه الخاص، باستخدام المعرف من A باعتباره “معرف الوالدين”. يؤدي هذا إلى ربط العمليات الموزعة في DAG واحد (الرسم البياني الحلقي المباشر).

RUM (مراقبة المستخدم الحقيقي)

تعمل إمكانية المراقبة من جانب الخادم بشكل مثالي، ومع ذلك لا يزال المستخدمون يشكون. “لقد قمت بالنقر على الزر ولم يحدث شيء.” سجلات الخادم: “لم يتم تلقي أي طلب.” الخلاصة: تعطل JavaScript في المتصفح قبل إرسال الطلب.

من أجل إمكانية ملاحظة الواجهة الأمامية، نستخدم ** RUM ** (Sentry، LogRocket). فإنه يلتقط تلقائيا:

  1. عناصر الويب الحيوية الأساسية: أكبر رسم محتوى (LCP)، والتفاعل مع الطلاء التالي (INP).
  2. أخطاء وحدة التحكم: غير محدد ليس دالة.
  3. إعادة تشغيل الجلسة: تسجيل يشبه الفيديو لحركات الماوس الخاصة بالمستخدم.

دراسة حالة: كان لدينا خطأ في عملية الدفع مع عدم وجود سجلات. أثناء مشاهدة إعادة تشغيل الجلسة، رأينا المستخدمين على iPhone SE (شاشة صغيرة) لا يمكنهم التمرير إلى زر “الدفع” لأن “شعار ملف تعريف الارتباط” كان يغطيه بـ .zIndex: 9999. لا يمكن لأي سجل أن يخبرنا بذلك. فعلت إمكانية الملاحظة البصرية.

فلسفة التنبيه: مبادئ SRE

لا تتصل بالمهندس الساعة 3 صباحًا لأن “وحدة المعالجة المركزية هي 90٪”. ربما 90٪ جيد. ربما تتم معالجة قائمة الانتظار بسرعة. تنبيه بشأن الأعراض وليس الأسباب.

SLI (مؤشر مستوى الخدمة): مقياس يهم المستخدم.

  • مثال: “توفر الصفحة الرئيسية”.
  • مثال: “زمن الوصول عند الخروج”.

SLO (هدف مستوى الخدمة): الهدف.

  • “يجب أن تكون الصفحة الرئيسية 200 موافق بنسبة 99.9% من الوقت.”
  • “يجب أن يكون الدفع أقل من ثانيتين بنسبة 95% من الوقت.”

حالة التنبيه:

  • “إذا كان معدل الخطأ > 0.1% لمدة 5 دقائق -> PagerDuty.”
  • “إذا كان معدل الخطأ > 5% -> قم بإيقاظ المدير التنفيذي.”

تكلفة الملاحظة

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

  • أخذ العينات على أساس الرأس: اتخذ القرار عند بداية الطلب. “تتبع 10% من المستخدمين.”
  • أخذ العينات بناءً على الذيل (متقدم): احتفظ بجميع الآثار في الذاكرة. في حالة حدوث خطأ، أرسل التتبع الكامل. إذا نجحت، تجاهلها.
    • يضمن ذلك التقاط 100% من الأخطاء و0% من سجلات النجاح المملة.

10. مراقبة منطق الأعمال (الإشارات الذهبية)

الرسوم البيانية لوحدة المعالجة المركزية لا تدفع الفواتير. الأوامر دفع الفواتير. لا تخبرك سجلات الوصول ما إذا كان زر “إضافة إلى سلة التسوق” معطلاً (إذا كان معطلاً، فلا توجد سجلات). نحن نحدد مقاييس الأعمال:

  • الطلبات_في_الدقيقة
  • add_to_cart_value_total
  • “معدل_رفض_بوابة_الدفع` قمنا بتعيين تنبيهات “الكشف عن الشذوذ”. “إذا انخفض عدد الطلبات/الحد الأدنى بنسبة 50% مقارنةً بيوم الثلاثاء الماضي -> PagerDuty.” يؤدي هذا إلى اكتشاف “حالات الفشل الصامت” (على سبيل المثال، مستمع أحداث Javascript المعطل) الذي لن تراه سجلات الخادم أبدًا.

11. استراتيجيات التحكم في التكاليف

Datadog باهظ الثمن. يعد تخزين كل “console.log” أمرًا مهدرًا. نقوم بتنفيذ مستويات السجل حسب البيئة:

  • التطوير: التصحيح (كل شيء).
  • الإنتاج: معلومات (الأحداث الرئيسية) + خطأ. نستخدم أيضًا مرشحات الاستبعاد على مستوى الوكيل: “أسقط كافة السجلات التي تحتوي على التحقق من الصحة حسنًا”. يؤدي هذا إلى تقليل مستوى الصوت بنسبة 40% دون فقدان الإشارة.

12. الانفجار الكاردينالي (كيفية إفلاس القدرة على الملاحظة)

يبدأ بريئا. metrics.increment('request_duration', { url: req.url }) ثم يقوم الروبوت بالضغط على /login?random=123. ثم /login?random=456. وفجأة، أصبح لديك مليون قيمة علامة فريدة. يقوم Datadog بتحصيل رسوم منك مقابل “المقاييس المخصصة”. الفاتورة: 15000 دولار شهريًا. الإصلاح: تطبيع الأبعاد الخاصة بك. استبدل /login?random=123 بـ /login?random=* في برنامجك الوسيط قبل إرسال المقياس.

13. تسجيل عائد الاستثمار: هل تبلغ قيمة هذا السجل 0.001 دولار؟

نحن نتعامل مع السجلات مثل العقارات. “قام المستخدم بتسجيل الدخول” -> قيمة عالية. احتفظ به لمدة 30 يومًا. “تم اجتياز فحص الصحة” -> قيمة منخفضة. إسقاط على الفور. “تفريغ مصفوفة تصحيح الأخطاء” -> القيمة السالبة. إنه يفسد البحث. نقوم بتنفيذ أخذ العينات الديناميكية: أثناء وقوع حادث، قم بتشغيل DEBUG لـ 1% من المستخدمين. في وقت السلم، احفظه بعيدًا.

14. الاستنتاج

قابلية الملاحظة هي الفرق بين “أعتقد أنه يعمل” و”أعلم أنه يعمل”. إنه ينقل الثقافة من “اللوم” (“فشل فريق الشبكة”) إلى “البيانات” (“يُظهر التتبع مهلة قدرها 500 مللي ثانية على المحول”).

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


هل يمكنك رؤية ما بداخل مجموعتك؟

إذا كنت تقوم بتصحيح الأخطاء باستخدام “console.log”، فإنك تخسر المال.

[قم بتعيين مهندسي DevOps لدينا](/جهة اتصال) لتنفيذ OpenTelemetry. قم بتوظيف مهندسينا.