خبرة في تطوير خدمة أداة الاسترداد باستخدام واجهة برمجة التطبيقات غير المتزامنة على كافكا

ما الذي يمكن أن يجعل شركة كبيرة مثل Lamoda ، من خلال عملية مبسطة وعشرات من الخدمات المترابطة ، يحدث تغييرًا كبيرًا في النهج؟ يمكن أن يكون الدافع مختلفًا تمامًا: من التشريعي إلى الرغبة في التجربة المتأصلة في جميع المبرمجين.

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

خبرة في تطوير خدمة أداة الاسترداد باستخدام واجهة برمجة التطبيقات غير المتزامنة على كافكا

إخلاء المسؤولية: تستند هذه المقالة إلى مواد من اللقاء الذي عقده سيرجي في نوفمبر 2018 في HighLoad ++. اجتذبت تجربة لامودا الحية للعمل مع كافكا المستمعين بما لا يقل عن التقارير الأخرى الواردة في الجدول. يبدو لنا أن هذا مثال رائع على حقيقة أنه من الممكن والضروري دائمًا العثور على أشخاص متشابهين في التفكير ، وسيواصل منظمو HighLoad ++ محاولة خلق جو يفضي إلى ذلك.

حول العملية

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

أداة رد الأموال مع واجهة برمجة تطبيقات تعتمد على الأحداث

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

خبرة في تطوير خدمة أداة الاسترداد باستخدام واجهة برمجة التطبيقات غير المتزامنة على كافكا

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

لكن العائد أصبح أكثر تعقيدًا بسبب التغييرات في التشريعات ، وكان علينا تنفيذ خدمة مصغرة منفصلة لذلك.

خبرة في تطوير خدمة أداة الاسترداد باستخدام واجهة برمجة التطبيقات غير المتزامنة على كافكا

دافعنا:

  1. القانون FZ-54 - باختصار ، يتطلب القانون إبلاغ مكتب الضرائب عن كل معاملة نقدية ، سواء كانت عودة أو إيصالًا ، في اتفاقية مستوى خدمة قصيرة إلى حد ما مدتها بضع دقائق. نحن ، بصفتنا تجارة إلكترونية ، نقوم بالعديد من العمليات. من الناحية الفنية ، هذا يعني مسؤولية جديدة (وبالتالي خدمة جديدة) وتحسينات في جميع الأنظمة المعنية.
  2. انقسام بوب - مشروع داخلي للشركة لتخليص BOB من عدد كبير من المسؤوليات غير الأساسية وتقليل تعقيدها العام.

خبرة في تطوير خدمة أداة الاسترداد باستخدام واجهة برمجة التطبيقات غير المتزامنة على كافكا

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

هناك أيضًا الكثير من التبادلات في BOB: أنظمة الدفع والتسليم والإشعارات وما إلى ذلك.

من الناحية الفنية ، BOB هو:

  • ~ 150 ألف سطر من التعليمات البرمجية + ~ 100 ألف سطر من الاختبارات ؛
  • php7.2 + Zend 1 & Symfony Components 3؛
  • > 100 واجهة برمجة تطبيقات و 50 تكامل خارجي ؛
  • 4 دول مع منطق الأعمال الخاصة بهم.

يعد نشر BOB أمرًا مكلفًا ومؤلماً ، ومقدار الكود والمهام التي يحلها لا يمكن لأحد أن يضعها في ذهنه بالكامل. بشكل عام ، هناك العديد من الأسباب لتبسيطها.

عملية العودة

في البداية ، يتم تضمين نظامين في العملية: BOB والدفع. الآن هناك نوعان آخران:

  • خدمة المالية ، والتي ستهتم بمشاكل المالية العامة والتواصل مع الخدمات الخارجية.
  • أداة الاسترداد ، والتي يتم فيها إخراج البورصات الجديدة ببساطة حتى لا تضخم BOB.

الآن تبدو العملية كما يلي:

خبرة في تطوير خدمة أداة الاسترداد باستخدام واجهة برمجة التطبيقات غير المتزامنة على كافكا

  1. يتلقى BOB طلب استرداد.
  2. يتحدث BOB عن أداة رد الأموال هذه.
  3. تقول أداة رد الأموال للدفع: "رد الأموال".
  4. الدفع يعيد المال.
  5. تقوم أداة رد الأموال و BOB بمزامنة الحالات بينهما ، لأن كلاهما في الوقت الحالي يحتاجان إليها. لسنا مستعدين بعد للتبديل الكامل إلى أداة استرداد الأموال ، نظرًا لأن BOB لديه واجهة مستخدم ، وتقارير للمحاسبة ، وبشكل عام الكثير من البيانات التي لا يمكن نقلها بهذه السهولة. عليك أن تجلس على كرسيين.
  6. طلب الإجازات المالية.

نتيجة لذلك ، صنعنا حافلة مناسبة معينة في كافكا - حافلة الأحداث ، حيث بدأ كل شيء. الصيحة ، الآن لدينا نقطة واحدة من الفشل (السخرية).

خبرة في تطوير خدمة أداة الاسترداد باستخدام واجهة برمجة التطبيقات غير المتزامنة على كافكا

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

ما هي واجهة برمجة التطبيقات التي تحركها الأحداث

توجد إجابة جيدة على هذا السؤال في تقرير مارتن فاولر (غوتو 2017) "المعاني العديدة للعمارة المدفوعة بالحدث".

باختصار ما فعلناه:

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

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

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

التبادل غير المتزامن كما هو

للتبادلات غير المتزامنة ، يستخدم قسم PHP عادةً RabbitMQ. قمنا بجمع البيانات الخاصة بالطلب ، ووضعناها في قائمة الانتظار ، وقام مستهلك نفس الخدمة بحسابها وإرسالها (أو لم يرسلها). بالنسبة لواجهة برمجة التطبيقات نفسها ، يستخدم لامودا Swagger بنشاط. نقوم بتصميم واجهة برمجة التطبيقات ، ووصفها في Swagger ، وإنشاء رمز العميل والخادم. نستخدم أيضًا JSON RPC 2.0 الممتد قليلاً.

في بعض الأماكن ، يتم استخدام حافلات esb ، يعيش شخص ما في activeMQ ، ولكن بشكل عام ، RabbitMQ - قياسي.

التبادل غير المتزامن ليكون

عند تصميم التبادل من خلال ناقل الأحداث ، يمكن تتبع القياس. نحن نصف بالمثل تبادل البيانات في المستقبل من خلال أوصاف بنية الحدث. تنسيق yaml ، كان علينا القيام بتوليد الكود بأنفسنا ، يقوم المولد بإنشاء DTOs وفقًا للمواصفات ويعلم العملاء والخوادم العمل معهم. ينتقل الجيل إلى لغتين - golang و php. هذا يحافظ على اتساق المكتبات. المولد مكتوب بلغة غولانغ ، ومن أجله حصل على اسم gogi.

إن تحديد مصادر الأحداث في كافكا أمر نموذجي. هناك حل من إصدار المؤسسة الرئيسي لـ Kafka Confluent ناكاديحل من "اخواننا" في مجال زالاندو. ملكنا الدافع للبدء بالفانيليا كافكا هو ترك الحل مجانيًا حتى نقرر أخيرًا ما إذا كنا سنستخدمه في كل مكان ، ونترك لأنفسنا أيضًا مجالًا للمناورة والتحسينات: نريد دعمًا JSON RPC 2.0 تحديث، مولدات لغتين ولنرى ماذا أيضًا.

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

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

الأحداث حافلة

أو حافلة الحدث. إنها مجرد بوابة http عديمة الحالة وتتولى عدة أدوار مهمة:

  • إنتاج المصادقة - تحقق من أن الأحداث تتوافق مع مواصفاتنا.
  • نظام إتقان الأحداث، أي أن هذا هو النظام الرئيسي والوحيد في الشركة الذي يجيب على السؤال المتعلق بالأحداث التي تعتبر الهياكل صالحة. التحقق من الصحة هو مجرد أنواع بيانات وتعدادات لمواصفات المحتوى الصارمة.
  • دالة تجزئة للتجزئة - بنية رسالة كافكا هي قيمة مفتاح ويتم حسابها من التجزئة من مكان وضعها.

لماذا

نحن نعمل في شركة كبيرة مع عملية مبسطة. لماذا تغير شيئا؟ هذه تجربةونتوقع الحصول على العديد من الفوائد.

تبادلات 1: n + 1 (واحد إلى كثير)

مع كافكا ، من السهل جدًا توصيل مستهلكين جدد بواجهة برمجة التطبيقات.

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

في حالة أداة الاسترداد ، وهي قطعة من BOB ، من الملائم لنا أن نجعلها متزامنة من خلال كافكا. يقول الدفع أنه تم إرجاع الأموال: اكتشف BOB و RT ذلك ، وقاموا بتغيير أوضاعهم ، واكتشفت خدمة Fiscalization هذا الأمر وأصدرت شيكًا.

خبرة في تطوير خدمة أداة الاسترداد باستخدام واجهة برمجة التطبيقات غير المتزامنة على كافكا

لدينا خطط لإنشاء خدمة إخطارات واحدة من شأنها أن تخطر العميل بالأخبار المتعلقة بطلبه / مرتجعاته. الآن هذه المسؤولية منتشرة عبر الأنظمة. سيكون كافيًا أن نعلم خدمة الإشعارات أن تلتقط المعلومات ذات الصلة من كافكا والرد عليها (وتعطيل هذه الإشعارات في الأنظمة الأخرى). لن تكون هناك حاجة للتبادلات المباشرة الجديدة.

تعتمد على البيانات

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

سجل النسخ المتماثل

لا تختفي الرسائل بعد قراءتها ، كما هو الحال في RabbitMQ. عندما يحتوي الحدث على معلومات كافية للمعالجة ، يكون لدينا سجل بآخر التغييرات التي تم إجراؤها على الكائن ، وإذا رغبت في ذلك ، القدرة على تطبيق هذه التغييرات.

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

خبرة في تطوير خدمة أداة الاسترداد باستخدام واجهة برمجة التطبيقات غير المتزامنة على كافكا

علاوة على ذلك ، إعادة سرد بسيط للوثائق ، لأولئك الذين ليسوا على دراية بكافكا (الصورة أيضًا من التوثيق)

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

لدى كافكا فكرة مجردة مماثلة موضوعالتي تكتب فيها الرسائل لكنها لا تختفي بعد قراءتها. بشكل افتراضي ، عندما تتصل بـ Kafka ، فإنك تتلقى جميع الرسائل ، ولديك خيار الحفظ من حيث توقفت. أي أنك تقرأ بالتسلسل ، لا يمكنك وضع علامة على الرسالة كمقروءة ، ولكن يمكنك حفظ المعرف ، والذي يمكنك من خلاله متابعة القراءة لاحقًا. المعرف الذي توقفت عنده يسمى offset (offset) ، والآلية تسمى الإزاحة الالتزام.

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

متطلبات الحدث:

  • اكتمال البيانات. أرغب في حصول الحدث على بيانات كافية حتى يمكن معالجته.

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

كافكا في لامودا

لدينا ثلاث منشآت كافكا:

  1. السجلات؛
  2. بحث وتطوير؛
  3. أحداث الحافلة.

اليوم نحن نتحدث فقط عن النقطة الأخيرة. في حافلات الأحداث ، ليس لدينا منشآت كبيرة جدًا - 3 وسطاء (خوادم) و 27 موضوعًا فقط. كقاعدة عامة ، موضوع واحد هو عملية واحدة. لكن هذه نقطة دقيقة ، والآن سنتطرق إليها.

خبرة في تطوير خدمة أداة الاسترداد باستخدام واجهة برمجة التطبيقات غير المتزامنة على كافكا

أعلاه هو مخطط rps. يتم تمييز عملية استرداد الأموال بخط فيروزي (نعم ، الخط الموجود على المحور السيني) ، والوردي هو عملية تحديث المحتوى.

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

قمم الوردي هي تحديثات المنتج ، أي تغييرات المنتج. يمكن ملاحظة أن الرجال التقطوا الصور والتقطوا الصور ثم مرة أخرى! - تحميل حزمة من الأحداث.

حالات استخدام Lamoda Events

نستخدم الهيكل المُنشأ للعمليات التالية:

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

الآن الجزء الأكثر إثارة حول النتوءات المحشوة والاكتشافات المثيرة التي حدثت في ستة أشهر.

مواضيع تصميمية

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

يبدو أن هذه مناطق متشابهة ، ولكن تختلف الحالات بالنسبة لمعالجة الطلبات في BOB ونظام التسليم. على سبيل المثال ، لا ترسل بعض خدمات البريد السريع حالات وسيطة ، ولكنها ترسل فقط الحالات النهائية: "تم التسليم" أو "المفقودة". آخرون ، على العكس من ذلك ، يتحدثون بتفصيل كبير عن حركة البضائع. كل شخص لديه قواعد التحقق الخاصة به: بالنسبة لشخص ما ، البريد الإلكتروني صالح ، مما يعني أنه سيتم معالجته ؛ بالنسبة للآخرين ، هذا غير صحيح ، لكن الأمر سيستمر في المعالجة ، لأنه يوجد هاتف للاتصال ، وسيقول أحدهم أن مثل هذا الطلب لن تتم معالجته على الإطلاق.

تدفق المعلومات

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

في موضوع واحد أو في موضوع مختلف؟

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

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

مجال جديد أم حدث جديد؟

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

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

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

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

إصدار الأحداث

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

قراءة الأقسام لضمان الطلب

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

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

كيف يشاركهم كافكا؟ كل رسالة لها جسم (نخزن فيه JSON) ومفتاح. يمكنك إرفاق وظيفة تجزئة بهذا المفتاح ، والتي ستحدد القسم الذي ستقع فيه الرسالة.

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

الأحداث مقابل الأوامر

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

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

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

خبرة في تطوير خدمة أداة الاسترداد باستخدام واجهة برمجة التطبيقات غير المتزامنة على كافكا

في تبادل غير متزامن في RabbitMQ ، عندما تقرأ رسالة ، انتقل إلى http ، لديك رد - على الأقل أنه تم قبول الرسالة. عندما تكتب إلى كافكا ، هناك رسالة كتبتها إلى كافكا ، لكنك لا تعرف شيئًا عن كيفية معالجتها.

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

الفروق الدقيقة

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

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

لفترة ، توقفت الخدمة - لحسن الحظ ، مع كافكا لم يكن هذا مخيفًا ، لأن الرسائل باقية. عندما يتم استعادة العمل ، يمكن قراءتها. انها مريحة.

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

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

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

رصد

أعتقد أن الطريقة التي نراقبها ستجعل من الواضح أكثر ما هي المشاكل الموجودة في النهج الحالي.

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

خبرة في تطوير خدمة أداة الاسترداد باستخدام واجهة برمجة التطبيقات غير المتزامنة على كافكا

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

خبرة في تطوير خدمة أداة الاسترداد باستخدام واجهة برمجة التطبيقات غير المتزامنة على كافكا

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

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

خبرة في تطوير خدمة أداة الاسترداد باستخدام واجهة برمجة التطبيقات غير المتزامنة على كافكا

هذا ما تبدو عليه استجابة API. هنا مجموعة bob-live-fifa ، استرداد القسم.update.v1 ، حالة OK ، lag 0 هو آخر تعويض نهائي كذا وكذا.

خبرة في تطوير خدمة أداة الاسترداد باستخدام واجهة برمجة التطبيقات غير المتزامنة على كافكا

رصد updated_at SLA (عالقة) لقد ذكرت بالفعل. على سبيل المثال ، تم نقل العنصر إلى حالة أنه جاهز للإرجاع. قمنا بتعيين Cron ، والذي يقول أنه إذا لم يتم استرداد هذا الكائن في 5 دقائق (نعيد الأموال من خلال أنظمة الدفع بسرعة كبيرة) ، فحينئذٍ حدث خطأ ما بالتأكيد ، وهذه بالتأكيد حالة للدعم. لذلك ، نأخذ ببساطة Cron ، الذي يقرأ مثل هذه الأشياء ، وإذا كانت أكبر من 0 ، فإنه يرسل تنبيهًا.

للتلخيص ، استخدام الأحداث مفيد عندما:

  • المعلومات مطلوبة من قبل عدة أنظمة ؛
  • نتيجة المعالجة ليست مهمة ؛
  • أحداث قليلة أو معدومة.

يبدو أن المقال يحتوي على موضوع محدد للغاية - واجهة برمجة تطبيقات غير متزامنة على كافكا ، لكن فيما يتعلق به ، أود أن أوصي على الفور بالكثير من الأشياء.
أولا ، بعد ذلك HighLoad ++ لكن عليك الانتظار حتى نوفمبر ، وفي أبريل سيكون هناك إصدار سانت بطرسبرغ ، وفي يونيو سنتحدث عن الأحمال الكبيرة في نوفوسيبيرسك.
ثانيًا ، مؤلف التقرير سيرجي زيكا هو عضو في لجنة البرنامج في مؤتمرنا الجديد حول إدارة المعرفة مؤتمر المعرفة. المؤتمر ليوم واحد ، وسيعقد في 26 أبريل ، لكن برنامجه ثري للغاية.
وسوف يكون في مايو PHP روسيا и RIT ++ (مع DevOpsConf كجزء) - هناك يمكنك أيضًا اقتراح موضوعك والتحدث عن تجربتك والشكوى من الرموز المحشوة.

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

إضافة تعليق