نلفت انتباهكم اليوم إلى مادة صغيرة حول الخدمات المصغرة والبنية الموزعة. على وجه الخصوص ، يتطرق إلى فكرة مارتن فاولر القائلة بأن النظام الجديد يجب أن يبدأ من كتلة متراصة ، وحتى في بنية الخدمات الدقيقة المتقدمة ، يُنصح بترك نواة متجانسة كبيرة.
استمتع بالقراءة!
يفكر الجميع اليوم في الخدمات المصغرة ويكتبونها - ولست استثناءً. استنادًا إلى المبادئ الأساسية للخدمات المصغرة وسياقها الحقيقي ، من الواضح أن الخدمات المصغرة هي نظام موزع.
ما هي الصفقة الموزعة؟
يشار إلى المعاملات التي تمتد عبر أنظمة فعلية متعددة أو أجهزة كمبيوتر على شبكة ما ببساطة على أنها معاملات موزعة. في عالم الخدمات المصغرة ، يتم تقسيم المعاملة عبر خدمات متعددة يتم استدعاؤها في تسلسل لإكمال المعاملة بالكامل.
إليك نظام متجر إلكتروني مترابط يستخدم المعاملات:
الشكل. 1: معاملة في وحدة متجانسة
إذا كان المستخدم في النظام أعلاه ، يرسل طلب أمر (الخروج) إلى النظام الأساسي ، ثم تقوم المنصة بإنشاء معاملة محلية في قاعدة البيانات ، وتمتد هذه المعاملة على العديد من جداول قاعدة البيانات لمعالجة ( معالجة ) الطلب والحجز(احتياطي) البضائع من المستودع. إذا فشلت أي من هذه الخطوات ، فيمكن عندئذٍ التراجع عن المعاملة ، مما يعني رفض كل من الطلب نفسه والسلع المحجوزة. تسمى هذه المجموعة من المبادئ ACID (الذرية ، والاتساق ، والعزل ، والمتانة) وهي مضمونة على مستوى نظام قاعدة البيانات.
فيما يلي تحليل لنظام متجر على الإنترنت تم إنشاؤه من خدمات مصغرة:
الشكل 2: المعاملات في خدمة مصغرة
بعد تفكيك هذا النظام ، أنشأنا خدمات مصغرة
OrderMicroserviceوInventoryMicroserviceمع قواعد بيانات منفصلة. عندما يأتي طلب Checkout من مستخدم ، يتم استدعاء هاتين الخدمتين المصغرتين ويقوم كل منهما بإجراء تغييرات على قاعدة البيانات الخاصة به. نظرًا لأن المعاملة يتم نشرها الآن عبر قواعد بيانات متعددة عبر أنظمة متعددة ، فإنها تعتبر موزعة .
ما هي المشكلة عند القيام بالمعاملات الموزعة في الخدمات المصغرة؟
مع إدخال بنية الخدمات المصغرة ، تفقد قواعد البيانات طبيعتها الحمضية. نظرًا للتكاثر المحتمل للمعاملات بين العديد من الخدمات المصغرة وبالتالي قواعد البيانات ، يجب التعامل مع القضايا الرئيسية التالية:
كيف تحافظ على ذرية الصفقة؟
تعني الذرية أنه في أي معاملة ، يمكن إكمال جميع الخطوات أو عدم إكمالها. إذا فشل المثال أعلاه في إكمال عملية "طلب العناصر" في الطريقة
InventoryMicroservice، فكيف يمكن التراجع عن التغييرات في "معالجة الطلب" التي تم تطبيقها OrderMicroservice؟
كيف أتعامل مع الطلبات التنافسية؟
افترض أن عنصرًا من أي من الخدمات المصغرة يدخل قاعدة البيانات للتخزين طويل المدى ، وفي نفس الوقت يقرأ طلب آخر نفس الكائن. ما هي البيانات التي يجب أن تعيدها الخدمة - قديمة أم جديدة؟ في المثال أعلاه ، عندما يكون
OrderMicroserviceقد أكمل عمله بالفعل InventoryMicroserviceوهو في طور التحديث ، هل تحتاج إلى تضمين الطلب الحالي في عدد طلبات الطلبات المقدمة من قبل المستخدم؟
تم تصميم الأنظمة الحديثة مع وضع الإخفاقات المحتملة في الاعتبار ، وقد تم توضيح إحدى المشكلات الرئيسية في معالجة المعاملات الموزعة بشكل جيد بواسطة Pat Helland.
كقاعدة عامة ، لا يقوم المطورون ببساطة بإنشاء تطبيقات كبيرة قابلة للتطوير والتي قد تتضمن العمل مع المعاملات الموزعة.
الحلول الممكنة
تعتبر المشكلتان المذكورتان أعلاه في غاية الأهمية في سياق تصميم وبناء التطبيقات القائمة على الخدمات المصغرة. لحلها ، يتم استخدام الطريقتين التاليتين:
- التثبيت على مرحلتين
- الاتساق المطلق والتعويضات / SAGA
1. التثبيت على مرحلتين
كما يوحي الاسم ، تتضمن طريقة معالجة المعاملات هذه مرحلتين: مرحلة التحضير ومرحلة الالتزام. يلعب منسق المعاملة دورًا مهمًا في هذه الحالة ، حيث ينظم دورة حياة المعاملة.
كيف تعمل
في المرحلة التحضيرية ، تستعد جميع الخدمات المصغرة المشاركة في العمل للالتزام وإخطار المنسق بأنها جاهزة لإتمام المعاملة. بعد ذلك ، في الخطوة التالية ، يحدث الالتزام ، أو يوجه منسق المعاملة جميع الخدمات المصغرة للتراجع.
ضع في اعتبارك مرة أخرى نظام المتجر عبر الإنترنت كمثال:
الشكل 3: الالتزام الناجح على مرحلتين في نظام الخدمات المصغرة
في المثال أعلاه (الشكل 3) ، عندما يقدم المستخدم طلبًا ،
TransactionCoordinatorيبدأ المنسق أولاً معاملة عالمية بمعلومات كاملة عن السياق. أولاً ، يرسل أمر التحضير إلى الخدمة المصغرة OrderMicroserviceلإنشاء الأمر. ثم يرسل أمر التحضير إلىInventoryMicroserviceلحجز العناصر. عندما تكون كلتا الخدمتين جاهزين لإجراء تغييرات ، فإنهما تحظران الكائنات من إجراء تغييرات أخرى وتبلغان بذلك TransactionCoordinator. بمجرد أن TransactionCoordinatorتؤكد أن جميع الخدمات المصغرة جاهزة لتطبيق تغييراتها ، ستطلب من هذه الخدمات المصغرة حفظها عن طريق طلب الالتزام بالمعاملة. في هذه المرحلة ، سيتم إلغاء قفل جميع الكائنات.
الشكل 4: فشل الالتزام على مرحلتين عند العمل مع الخدمات المصغرة
في سيناريو الفشل (الشكل 4) - إذا لم يكن لدى خدمة مصغرة واحدة في أي لحظة وقت للتحضير ، قم
TransactionCoordinatorبإلغاء المعاملة وابدأ عملية التراجع. في الرسم التخطيطي ، OrderMicroserviceلسبب ما ، لم أتمكن من إنشاء أمر ، لكنني InventoryMicroserviceأجبت أنني مستعد لإنشاء أمر. TransactionCoordinatorسيطلب المنسق الإلغاء فيInventoryMicroservice، وبعد ذلك ستقوم الخدمة بالتراجع عن جميع التغييرات التي تم إجراؤها وإلغاء تأمين كائنات قاعدة البيانات.
فوائد
- يضمن هذا النهج ذرية الصفقة. ستكتمل المعاملة إما عندما تنجح كلتا الخدمتين المصغرتين ، أو عندما لا تُجري الخدمات المصغرة أي تغييرات.
- ثانيًا ، يسمح لك هذا الأسلوب بعزل القراءة عن الكتابة ، نظرًا لأن التغييرات على الكائنات غير مرئية حتى يقوم منسق المعاملة بتنفيذ هذه التغييرات.
- هذا الأسلوب عبارة عن مكالمة متزامنة يتم فيها إخطار العميل بالنجاح أو الفشل.
سلبيات
- لا شيء كامل. تعتبر الالتزامات على مرحلتين بطيئة إلى حد ما مقارنة بعمليات الخدمة المصغرة الفردية. يعتمدون بشكل كبير على المنسق. المعاملات ، والتي يمكن أن تبطئ النظام بشكل كبير خلال فترات الحمل العالي.
- عيب رئيسي آخر هو قفل صف قاعدة البيانات. يمكن أن يصبح القفل عقبة في الأداء ، ويمكن أن تحدث حالات توقف تام ، حيث تغلق معاملتان بعضهما البعض بإحكام.
2. الاتساق المطلق والتعويضات / SAGA
يتم تقديم أحد أفضل تعريفات الاتساق في النهاية على موقع microservices.io: تنشر كل خدمة حدثًا كلما تم تحديث بياناتها. خدمات أخرى الاشتراك في الأحداث. عند تلقي حدث ، تقوم الخدمة بتحديث بياناته .
باستخدام هذا الأسلوب ، يتم تنفيذ معاملة موزعة كمجموعة من المعاملات المحلية غير المتزامنة على الخدمات المصغرة المقابلة. تتبادل الخدمات المصغرة المعلومات عبر ناقل الحدث.
كيف تعمل
مرة أخرى ، لنأخذ مثالاً على نظام يعمل في متجر على الإنترنت:
الشكل 5: Ultimate Consistency / SAGA ، النجاح
في المثال أعلاه (الشكل 5) ، يطلب العميل من النظام معالجة الطلب. هذا الطلب
Choreographerيثير إنشاء ترتيب الحدث، الذي يبدأ المعاملة. OrderMicroserviceتستمع Microservice لهذا الحدث وتقوم بإنشاء طلب - إذا نجحت هذه العملية ، فإنها ترفع حدث Order Created. Choreographerيستمع المنسق إلى هذا الحدث ويتابع طلب العناصر ، مما يرفع من حدث حجز العناصر. خدمة مصغرةInventoryMicroserviceيستمع إلى هذا الحدث ويطلب البضائع ؛ إذا نجح هذا الحدث ، فسيتم رفع حدث العناصر المحجوزة. في هذا المثال ، هذا يعني أن المعاملة قد انتهت.
تحدث جميع الاتصالات القائمة على الحدث بين الخدمات المصغرة من خلال ناقل الحدث ، وهناك نظام آخر مسؤول عن تنظيمه (تصميم الرقصات) - هذه هي الطريقة التي يتم بها حل المشكلة مع تعقيد غير ضروري.
الشكل 6: الاتساق النهائي / SAGA ، النتيجة الفاشلة
إذا ، لسبب ما ،
InventoryMicroserviceلم يتم حجز العناصر (الشكل 6) ، فإنه يثير حدث فشل حجز العناصر. Choreographerيستمع المنسق إلى هذا الحدث ويبدأ معاملة المقاصة ، ويرفع حدث حذف الأمر. خدمة مصغرةOrderMicroservice يستمع إلى هذا الحدث ويزيل الأمر الذي تم إنشاؤه مسبقًا.
فوائد
الميزة الرئيسية لهذا النهج هي أن كل خدمة مصغرة تركز فقط على معاملتها الذرية. لا يتم حظر الخدمات المصغرة إذا استغرق تشغيل خدمة أخرى وقتًا طويلاً نسبيًا. هذا يعني أيضًا أنك لست بحاجة إلى قفل قاعدة البيانات أيضًا. باستخدام هذا النهج ، من الممكن ضمان قابلية تطوير جيدة للنظام عند العمل تحت حمولة عالية ، لأن الحل المقترح غير متزامن ويعتمد على العمل مع الأحداث.
سلبيات
العيب الرئيسي لهذا الأسلوب هو أنه لا يوفر عزل القراءة. وبالتالي ، في المثال أعلاه ، سيرى العميل أن الأمر قد تم إنشاؤه ، ولكن بعد ثانية سيتم حذف الأمر أثناء معاملة المقاصة. بالإضافة إلى ذلك ، مع زيادة عدد الخدمات المصغرة ، يصبح من الصعب تصحيحها وصيانتها.
خاتمة
البديل الأول للنهج المقترح هو التخلي عن المعاملات الموزعة تمامًا. إذا كنت تقوم ببناء تطبيق جديد ، فابدأ بهندسة معمارية متجانسة ، كما هو موضح في MonolithFirst بواسطة Martin Fowler. سوف أقتبس منه.
, , . , , . —إذا كانت البيانات بحاجة إلى تحديث في مكانين في وقت واحد كنتيجة لحدث واحد ، فإن نهج الاتساق / SAGA النهائي يُفضل على نهج مرحلتين لمعالجة المعاملات الموزعة. السبب الرئيسي هو أن نهج مرحلتين في بيئة موزعة لا مقياس. يؤدي استخدام التناسق أيضًا في النهاية إلى إثارة مجموعة المشاكل الخاصة به ، مثل كيفية تحديث قاعدة البيانات ذريًا وإطلاق حدث. بالانتقال إلى فلسفة التطوير هذه ، من الضروري تغيير تصورها من وجهة نظر المطور ومن وجهة نظر المختبر.