بينما ننتقل من تطبيق متجانس إلى بنية الخدمات الصغيرة، فإننا نواجه تحديات جديدة.
في تطبيق متجانس، عادة ما يكون من السهل جدًا تحديد أي جزء من النظام حدث فيه الخطأ. على الأرجح، تكمن المشكلة في كود المونوليث نفسه، أو في قاعدة البيانات. ولكن عندما نبدأ في البحث عن مشكلة في بنية الخدمات الصغيرة، لم يعد كل شيء واضحًا. نحتاج إلى العثور على المسار الكامل الذي سلكه الطلب من البداية إلى النهاية واختياره من بين مئات الخدمات الصغيرة. علاوة على ذلك، لدى العديد منها أيضًا مرافق تخزين خاصة بها، والتي يمكن أن تسبب أيضًا أخطاء منطقية، بالإضافة إلى مشاكل في الأداء والتسامح مع الأخطاء.
لقد كنت أبحث منذ فترة طويلة عن أداة من شأنها أن تساعد في التعامل مع مثل هذه المشاكل (كتبت عن هذا في حبري:
يعد التتبع الموزع حلاً شائعًا لمشكلة العثور على الأخطاء في الأنظمة الموزعة. ولكن ماذا لو لم يتم تنفيذ هذا النهج لجمع المعلومات حول تفاعلات الشبكة بعد في النظام، أو ما هو أسوأ من ذلك، في جزء من النظام يعمل بالفعل بشكل صحيح، ولكن جزئيًا لا يعمل، لأنه لم تتم إضافته إلى الخدمات القديمة ؟ لتحديد السبب الجذري الدقيق للمشكلة، من الضروري أن يكون لديك صورة كاملة عما يحدث في النظام. من المهم بشكل خاص فهم الخدمات الصغيرة التي تشارك في المسارات الرئيسية للأعمال.
هنا يمكن أن يساعدنا نهج شبكة الخدمة، والذي سيتعامل مع جميع آليات جمع معلومات الشبكة بمستوى أقل من الخدمات نفسها التي تعمل بها. يسمح لنا هذا الأسلوب باعتراض كل حركة المرور وتحليلها بسرعة. علاوة على ذلك، لا تحتاج التطبيقات حتى إلى معرفة أي شيء عنها.
نهج شبكة الخدمة
الفكرة الرئيسية لنهج شبكة الخدمة هي إضافة طبقة بنية تحتية أخرى عبر الشبكة، مما سيسمح لنا بفعل أي شيء من خلال التفاعل بين الخدمات. تعمل معظم التطبيقات على النحو التالي: تتم إضافة حاوية جانبية إضافية مع وكيل شفاف إلى كل خدمة صغيرة، والتي يتم من خلالها تمرير كل حركة المرور الواردة والصادرة للخدمة. وهذا هو المكان الذي يمكننا فيه إجراء موازنة العملاء وتطبيق سياسات الأمان وفرض قيود على عدد الطلبات وجمع معلومات مهمة حول تفاعل الخدمات في الإنتاج.
حلول
هناك بالفعل العديد من تطبيقات هذا النهج:
ونتيجة لذلك، نظرنا بالضبط في القدرات التي نحتاجها الآن، وقررنا أن السبب الرئيسي وراء بدءنا في تنفيذ مثل هذه الحلول هو القدرة على جمع معلومات التتبع من النظام بأكمله بشفافية. أردنا أيضًا التحكم في تفاعل الخدمات وإجراء عمليات معالجة مختلفة للترويسات التي يتم نقلها بين الخدمات.
ونتيجة لذلك توصلنا إلى قرارنا:
نتراميش
وكانت الأهداف الرئيسية للحل الجديد هي انخفاض النفقات العامة للموارد والأداء العالي. من بين الميزات الرئيسية، أردنا على الفور أن نكون قادرين على إرسال امتدادات التتبع بشفافية إلى نظام Jaeger الخاص بنا.
اليوم، يتم تنفيذ معظم الحلول السحابية في Golang. وبطبيعة الحال، هناك أسباب لذلك. تعد كتابة تطبيقات الشبكة في Golang التي تعمل بشكل غير متزامن مع الإدخال / الإخراج والتوسع عبر النوى حسب الحاجة أمرًا مريحًا وبسيطًا للغاية. والأهم أيضًا أن الأداء كافٍ لحل هذه المشكلة. ولهذا السبب اخترنا أيضًا جولانج.
أداء
لقد ركزنا جهودنا على تحقيق أقصى قدر من الإنتاجية. للحصول على حل يتم نشره بجوار كل مثيل للخدمة، يلزم استهلاك صغير لذاكرة الوصول العشوائي (RAM) ووقت وحدة المعالجة المركزية (CPU). وبطبيعة الحال، ينبغي أن يكون تأخير الاستجابة صغيرا أيضا.
دعونا نرى ما هي النتائج التي حصلنا عليها.
رامات
يستهلك Netramesh حوالي 10 ميجابايت بدون حركة مرور و50 ميجابايت بحد أقصى مع تحميل يصل إلى 10000 دورة في الثانية لكل مثيل.
يستهلك وكيل Istio Envoy دائمًا ما يقرب من 300 ميجابايت في مجموعاتنا مع آلاف المثيلات. وهذا لا يسمح بتحجيمها إلى المجموعة بأكملها.
مع Netramesh، حصلنا على انخفاض في استهلاك الذاكرة يصل إلى 10x.
وحدة المعالجة المركزية:
استخدام وحدة المعالجة المركزية متساوٍ نسبيًا تحت الحمل. يعتمد ذلك على عدد الطلبات لكل وحدة زمنية للعربة الجانبية. القيم عند 3000 طلب في الثانية في الذروة:
هناك نقطة أخرى مهمة: Netramesh - الحل بدون مستوى تحكم وبدون تحميل لا يستهلك وقت وحدة المعالجة المركزية. مع Istio، تقوم الأجهزة الجانبية دائمًا بتحديث نقاط نهاية الخدمة. ونتيجة لذلك، يمكننا أن نرى هذه الصورة دون تحميل:
نستخدم HTTP/1 للاتصال بين الخدمات. كانت الزيادة في وقت الاستجابة لـ Istio عند التوكيل من خلال المبعوث تصل إلى 5-10 مللي ثانية، وهو عدد كبير جدًا بالنسبة للخدمات الجاهزة للاستجابة خلال ميلي ثانية واحدة. مع Netramesh انخفضت هذه المرة إلى 0.5-2 مللي ثانية.
التدرجية
إن الكمية الصغيرة من الموارد التي يستهلكها كل وكيل تجعل من الممكن وضعها بجانب كل خدمة. تم إنشاء Netramesh عمدًا بدون مكون مستوى التحكم للحفاظ على وزن كل عربة جانبية. في كثير من الأحيان، في حلول شبكات الخدمة، يقوم مستوى التحكم بتوزيع معلومات اكتشاف الخدمة على كل عربة جانبية. جنبا إلى جنب معها تأتي معلومات حول المهلات وإعدادات الموازنة. كل هذا يتيح لك القيام بالكثير من الأشياء المفيدة، ولكن لسوء الحظ، فإنه ينتفخ حجم السيارات الجانبية.
اكتشاف الخدمة
لا يضيف Netramesh أي آليات إضافية لاكتشاف الخدمة. يتم وكيل كل حركة المرور بشفافية من خلال netra Sidecar.
يدعم Netramesh بروتوكول تطبيق HTTP/1. ولتعريفه، يتم استخدام قائمة منافذ قابلة للتكوين. عادة، يحتوي النظام على عدة منافذ يتم من خلالها إجراء اتصال HTTP. على سبيل المثال، نستخدم 80، 8890، 8080 للتفاعل بين الخدمات والطلبات الخارجية، وفي هذه الحالة يمكن ضبطها باستخدام متغير البيئة NETRA_HTTP_PORTS
.
إذا كنت تستخدم Kubernetes كمنسق وآلية كيان الخدمة الخاصة به للاتصال داخل المجموعة بين الخدمات، فستظل الآلية كما هي تمامًا. أولاً، تحصل الخدمة الصغيرة على عنوان IP للخدمة باستخدام kube-dns وتفتح اتصالاً جديدًا به. يتم إنشاء هذا الاتصال أولاً باستخدام netra-sidecar المحلي وتصل جميع حزم TCP مبدئيًا إلى netra. بعد ذلك، تقوم netra-sidecar بإنشاء اتصال بالوجهة الأصلية. يظل NAT الموجود على pod IP على العقدة كما هو تمامًا بدون netra.
التتبع الموزع وإعادة توجيه السياق
يوفر Netramesh الوظائف اللازمة لإرسال امتدادات التتبع حول تفاعلات HTTP. يقوم Netra-sidecar بتحليل بروتوكول HTTP، وقياس تأخيرات الطلب، واستخراج المعلومات الضرورية من رؤوس HTTP. في النهاية، حصلنا على كل الآثار في نظام جايجر واحد. للحصول على تكوين دقيق، يمكنك أيضًا استخدام متغيرات البيئة التي توفرها المكتبة الرسمية
لكن هناك مشكلة. وإلى أن تقوم الخدمات بإنشاء وإرسال رأس خاص لـ uber، لن نرى امتدادات تتبع متصلة في النظام. وهذا ما نحتاجه للعثور بسرعة على سبب المشاكل. وهنا مرة أخرى لدى Netramesh الحل. يقرأ الوكلاء رؤوس HTTP، وإذا لم تحتوي على معرف تتبع uber، فقم بإنشاء واحد. يقوم Netramesh أيضًا بتخزين معلومات حول الطلبات الواردة والصادرة في ملف جانبي ويطابقها عن طريق إثرائها برؤوس الطلبات الصادرة الضرورية. كل ما عليك فعله في الخدمات هو إرسال رأس واحد فقط X-Request-Id
والتي يمكن تهيئتها باستخدام متغير البيئة NETRA_HTTP_REQUEST_ID_HEADER_NAME
. للتحكم في حجم السياق في Netramesh، يمكنك تعيين متغيرات البيئة التالية: NETRA_TRACING_CONTEXT_EXPIRATION_MILLISECONDS
(الوقت الذي سيتم تخزين السياق فيه) و NETRA_TRACING_CONTEXT_CLEANUP_INTERVAL
(تكرار تنظيف السياق).
من الممكن أيضًا دمج مسارات متعددة على نظامك عن طريق وضع علامة عليها برمز جلسة خاص. Netra يسمح لك بالتثبيت HTTP_HEADER_TAG_MAP
لتحويل رؤوس HTTP إلى علامات امتداد التتبع المقابلة. يمكن أن يكون هذا مفيدًا بشكل خاص للاختبار. بعد اجتياز الاختبار الوظيفي، يمكنك معرفة أي جزء من النظام تأثر بالتصفية حسب مفتاح الجلسة المقابل.
تحديد مصدر الطلب
لتحديد مصدر الطلب، يمكنك استخدام وظيفة إضافة رأس مع المصدر تلقائيًا. باستخدام متغير البيئة NETRA_HTTP_X_SOURCE_HEADER_NAME
يمكنك تحديد اسم الرأس الذي سيتم تثبيته تلقائيًا. باستخدام NETRA_HTTP_X_SOURCE_VALUE
يمكنك تعيين القيمة التي سيتم تعيين رأس X-Source عليها لجميع الطلبات الصادرة.
وهذا يسمح بتوزيع هذا الرأس المفيد بشكل موحد عبر الشبكة. ثم يمكنك استخدامه في الخدمات وإضافته إلى السجلات والمقاييس.
توجيه حركة المرور والأجزاء الداخلية من Netramesh
يتكون Netramesh من عنصرين رئيسيين. الأول، netra-init، يقوم بتعيين قواعد الشبكة لاعتراض حركة المرور. انه يستخدم INBOUND_INTERCEPT_PORTS, OUTBOUND_INTERCEPT_PORTS
.
تحتوي الأداة أيضًا على ميزة مثيرة للاهتمام - التوجيه الاحتمالي. إذا كنت تستخدم Netramesh حصريًا لتجميع امتدادات التتبع، فيمكنك في بيئة الإنتاج حفظ الموارد وتمكين التوجيه الاحتمالي باستخدام المتغيرات NETRA_INBOUND_PROBABILITY
и NETRA_OUTBOUND_PROBABILITY
(من 0 إلى 1). القيمة الافتراضية هي 1 (يتم اعتراض كل حركة المرور).
بعد الاعتراض الناجح، يقبل netra Sidecar الاتصال والاستخدامات الجديدة SO_ORIGINAL_DST
خيار المقبس للحصول على الوجهة الأصلية. تقوم Netra بعد ذلك بفتح اتصال جديد بعنوان IP الأصلي وإنشاء اتصال TCP ثنائي الاتجاه بين الأطراف، والاستماع إلى كل حركة المرور المارة. إذا تم تعريف المنفذ على أنه HTTP، فستحاول Netra تحليله وتتبعه. إذا فشل تحليل HTTP، تعود Netra مرة أخرى إلى TCP وتتولى وكيل البايتات بشفافية.
بناء الرسم البياني التبعية
بعد تلقي كمية كبيرة من معلومات التتبع في Jaeger، أرغب في الحصول على رسم بياني كامل للتفاعلات في النظام. ولكن إذا كان نظامك محملاً تمامًا وتتراكم مليارات من فترات التتبع يوميًا، فإن تجميعها لن يصبح مهمة سهلة. هناك طريقة رسمية للقيام بذلك:
إذا كنت تستخدم Elasticsearch لتخزين امتدادات التتبع، فيمكنك استخدام
كيفية استخدام نتراميش
يمكن إضافة Netra بسهولة إلى أي خدمة تقوم بتشغيل أي منسق. يمكنك رؤية مثال
في الوقت الحالي، لا تمتلك Netra القدرة على تنفيذ الجوانب الجانبية للخدمات تلقائيًا، ولكن هناك خطط للتنفيذ.
مستقبل نتراميش
الهدف الرئيسي
في المستقبل، سيدعم Netramesh بروتوكولات طبقة التطبيقات الأخرى إلى جانب HTTP. سيكون التوجيه L7 متاحًا في المستقبل القريب.
استخدم Netramesh إذا واجهت مشكلات مماثلة واكتب إلينا بأسئلة واقتراحات.
المصدر: www.habr.com