
العالم الحديث ببساطة لا يمكن تصوره دون استخدام الأنظمة الموزعة. حتى أبسط تطبيقات الهاتف المتحرك بها واجهة برمجة تطبيقات يتم من خلالها توصيل وحدة التخزين السحابية. ومع ذلك ، فإن تصميم النظم الموزعة لا يزال فنًا وليس علمًا دقيقًا. الحاجة إلى وضع أساس جاد في ظلها طال انتظارها ، وإذا كنت ترغب في اكتساب الثقة في إنشاء ودعم وتشغيل النظم الموزعة - ابدأ بهذا الكتاب!
يحدد بريندان بيرنز ، المتخصص في مجال التقنيات السحابية و Kubernetes ، في هذا العمل الصغير الحد الأدنى الضروري اللازم للتصميم الصحيح للأنظمة الموزعة. يصف هذا الكتاب أنماط دائم الشباب لتصميم النظم الموزعة. سوف يساعدك ليس فقط إنشاء مثل هذه الأنظمة من نقطة الصفر ، ولكن أيضًا تحويل الأنظمة الحالية بشكل فعال.
مقتطفات. نمط الديكور. تحويل طلب أو استجابة
تعد FaaS مثالية عندما تحتاج إلى وظائف بسيطة تعالج بيانات الإدخال ثم تنقلها إلى خدمات أخرى. يمكن استخدام هذا النوع من الأنماط لتوسيع أو تزيين طلبات HTTP المرسلة أو المستلمة بواسطة خدمة أخرى. يظهر هذا النمط بشكل تخطيطي في الشكل. 8.1.
بالمناسبة ، في لغات البرمجة هناك العديد من أوجه التشابه لهذا النمط. على وجه الخصوص ، لدى Python أدوات تزيين وظيفية تشبه وظيفيًا مُصممي الطلب أو الاستجابة. نظرًا لأن تزيين التحويلات لا يخزن الحالة وغالبًا ما تتم إضافته بحكم الواقع مع تطور الخدمة ، فهي مناسبة بشكل مثالي للتنفيذ كـ FaaS. بالإضافة إلى ذلك ، تعني خفة FaaS أنه يمكنك تجربة العديد من الديكورات حتى تجد واحدة تتكامل بشكل وثيق مع الخدمة.

توضح إضافة القيم الافتراضية إلى معلمات الإدخال لطلبات HTTP RESTful API فوائد نموذج الديكور. تحتوي العديد من طلبات واجهة برمجة التطبيقات على حقول تحتاج إلى تعبئتها بقيم معقولة إذا لم يتم تحديدها بواسطة المتصل. على سبيل المثال ، تريد أن يكون الحقل افتراضيًا إلى true. من الصعب تحقيق ذلك باستخدام JSON الكلاسيكي ، لأن الحقل الفارغ الافتراضي باطل ، والذي عادة ما يتم تفسيره على أنه خاطئ. لحل هذه المشكلة ، يمكنك إضافة منطق استبدال القيم الافتراضية إما أمام خادم API أو في رمز التطبيق (على سبيل المثال ، إذا كان الحقل (= = null) = true). ومع ذلك ، كلا الأسلوبين غير مثاليين ، لأن آلية الاستبدال الافتراضية مستقلة من الناحية النظرية عن معالجة الطلب. بدلاً من ذلك ، يمكننا استخدام نمط FaaS Decorator ، الذي يحول الطلب على الطريق بين المستخدم وتنفيذ الخدمة.
بالنظر إلى ما قيل سابقًا في القسم الخاص بأنماط العقدة المفردة ، فقد تتساءل عن سبب عدم تصميم خدمة الاستبدال الافتراضية في شكل حاوية محول. هذا النهج منطقي ، لكنه يعني أيضًا أن توسيع نطاق خدمة البحث الافتراضية وتوسيع نطاق خدمة واجهة برمجة التطبيقات (API) نفسها أصبحا يعتمدان على بعضهما البعض. يعد استبدال القيم الافتراضية عملية سهلة من الناحية الحسابية ، وعلى الأرجح لن تحتاج إلى العديد من مثيلات الخدمة.
في الأمثلة الواردة في هذا الفصل ، سوف نستخدم إطار FaaS kubeless (https://github.com/kubeless/kubeless). يتم نشر Kubeless على رأس خدمة أوركسترا حاوية Kubernetes. إذا كنت قد قمت بالفعل بإعداد نظام Kubernetes ، فتابع تثبيت Kubeless ، والذي يمكن تنزيله من الموقع المقابل (https://github.com/kubeless/kubeless/releases). بمجرد حصولك على الملف القابل للتنفيذ kubeless ، يمكنك تثبيته في نظام المجموعة باستخدام أمر التثبيت kubeless.
يتم تثبيت Kubeless كبرنامج إضافي لبروتوكول Kubernetes لجهة خارجية. هذا يعني أنه بعد التثبيت ، يمكن استخدامه كجزء من أداة سطر الأوامر kubectl. على سبيل المثال ، يمكن رؤية الوظائف المنشورة في نظام المجموعة عن طريق تشغيل الأمر kubectl get jobs. لا توجد حاليًا وظائف منتشرة في نظامك.
ورشة عمل. استبدال القيم الافتراضية قبل معالجة الطلب
يمكنك إثبات جدوى نمط Decorator في FaaS باستخدام مثال استبدال القيم الافتراضية في استدعاء RESTful للمعلمات التي لم يقم المستخدم بتعيين قيمها. مع FaaS ، هذا بسيط للغاية. وظيفة البحث الافتراضية مكتوبة في بيثون:
# -, # def handler(context): # obj = context.json # "name" , # if obj.get("name", None) is None: obj["name"] = random_name() # 'color', # 'blue' if obj.get("color", None) is None: obj["color"] = "blue" # API- # # return call_my_api(obj)
احفظ هذه الوظيفة إلى ملف يسمى defaults.py. تذكر استبدال المكالمة call_my_api بـ API الذي تريده. يمكن تسجيل وظيفة الاستبدال الافتراضية هذه كدالة kubeless باستخدام الأمر التالي:
kubeless function deploy add-defaults \ --runtime python27 \ --handler defaults.handler \ --from-file defaults.py \ --trigger-http
لاختباره ، يمكنك استخدام أداة kubeless:
kubeless function call add-defaults --data '{"name": "foo"}'
يُظهر نموذج Decorator مدى سهولة تكييف واجهات برمجة التطبيقات الحالية وتوسيع نطاقها مع ميزات إضافية مثل التحقق من القيم الافتراضية أو استبدالها.
التعامل مع الحدث
معظم الأنظمة موجهة نحو الاستعلام - وهي تقوم بمعالجة التدفقات المستمرة لطلبات المستخدم وواجهة برمجة التطبيقات. على الرغم من هذا ، هناك عدد لا بأس به من أنظمة موجهة نحو الحدث. الفرق بين الطلب والحدث ، كما يبدو لي ، يكمن في مفهوم الجلسة. الطلبات هي أجزاء من عملية تفاعل أكبر (الجلسة). في الحالة العامة ، يعد كل طلب مستخدم جزءًا من عملية التفاعل مع تطبيق ويب أو واجهة برمجة التطبيقات ككل. أرى الأحداث أكثر "لمرة واحدة" ، غير متزامن في الطبيعة. تعتبر الأحداث مهمة ويجب التعامل معها وفقًا لذلك ، لكنها ممزقة من السياق الرئيسي للتفاعل ولا تأتي الإجابة عليها إلا بعد مرور بعض الوقت. مثال على هذا الحدث هو اشتراك المستخدم في خدمة معينة ، مما يؤدي إلى إرسال خطاب ترحيب ؛ تحميل ملف إلى مجلد مشترك ، مما سيؤدي إلى إرسال إشعارات إلى جميع مستخدمي هذا المجلد ؛ أو حتى إعداد الكمبيوتر لإعادة التشغيل ، والذي سيُخطر المشغل أو النظام الآلي بضرورة اتخاذ الإجراء المناسب.
نظرًا لأن هذه الأحداث مستقلة إلى حد كبير وليست لها حالة داخلية ، كما أن تواترها متغير جدًا ، فهي مناسبة تمامًا للعمل في بنيات FaaS الموجهة نحو الأحداث. غالبًا ما يتم نشرها بجوار خادم التطبيقات "battle" لتوفير إمكانيات إضافية أو للمعالجة الخلفية للبيانات استجابةً للأحداث الناشئة. بالإضافة إلى ذلك ، نظرًا لأن الأنواع الجديدة من الأحداث التي تتم معالجتها تتم إضافتها باستمرار إلى الخدمة ، فإن بساطة نشر الوظيفة تجعلها مناسبة لتنفيذ معالجات الأحداث. ونظرًا لأن كل حدث مستقل من الناحية النظرية عن الآخر ، فإن الضعف القسري للعلاقات داخل نظام مبني على أساس الوظائف يسمح لنا بتقليل تعقيده المفاهيمي ، مما يسمح للمطور بالتركيز على الخطوات اللازمة لمعالجة نوع واحد محدد من الأحداث فقط.
من الأمثلة المحددة لدمج مكون موجه نحو الحدث في خدمة موجودة تطبيق المصادقة ثنائية العامل. في هذه الحالة ، سيكون الحدث هو تسجيل دخول المستخدم إلى النظام. يمكن للخدمة إنشاء حدث لهذا الإجراء وتمريره إلى وظيفة معالج. يقوم المعالج ، على أساس الرمز المنقول وتفاصيل الاتصال للمستخدم ، بإرسال رمز مصادقة له في شكل رسالة نصية.
ورشة عمل. تطبيق المصادقة الثنائية
تشير المصادقة ثنائية العامل إلى أنه لكي يدخل المستخدم النظام ، فإنه يحتاج إلى شيء يعرفه (على سبيل المثال ، كلمة مرور) وشيء لديه (على سبيل المثال ، رقم هاتف). المصادقة ثنائية أفضل بكثير من مجرد كلمة مرور ، لأن المهاجم سوف يضطر إلى سرقة كل من كلمة المرور ورقم هاتفك للوصول.
عند التخطيط لتنفيذ مصادقة ثنائية ، تحتاج إلى معالجة طلب لإنشاء رمز عشوائي ، وتسجيله مع خدمة تسجيل الدخول وإرسال رسالة إلى المستخدم. يمكنك إضافة رمز يقوم بتنفيذ هذه الوظيفة مباشرة في خدمة تسجيل الدخول نفسها. هذا يعقد النظام ، ويجعله أكثر متجانسة. يجب أن يتم إرسال رسالة في وقت واحد مع الرمز الذي ينشئ صفحة الويب لتسجيل الدخول ، والتي قد تؤدي إلى تأخير معين. هذا التأخير يحط من جودة تفاعل المستخدم مع النظام.
سيكون من الأفضل إنشاء خدمة FaaS من شأنها إنشاء رقم عشوائي بشكل غير متزامن ، وتسجيله باستخدام خدمة تسجيل الدخول وإرساله إلى هاتف المستخدم. وبالتالي ، يمكن لخادم تسجيل الدخول ببساطة تنفيذ طلب غير متزامن لخدمة FaaS ، والذي سيؤدي في نفس الوقت المهمة البطيئة نسبيًا لتسجيل الكود وإرساله.
لمعرفة كيفية عمل ذلك ، ضع في الاعتبار الكود التالي:
def two_factor(context): # code = random.randint(1 00000, 9 99999) # user = context.json["user"] register_code_with_login_service(user, code) # Twillio account = "my-account-sid" token = "my-token" client = twilio.rest.Client(account, token) user_number = context.json["phoneNumber"] msg = ", {}, : {}.".format(user, code) message = client.api.account.messages.create(to=user_number, from_="+1 20652 51212", body=msg) return {"status": "ok"}
ثم سجل FaaS في kubeless:
kubeless function deploy add-two-factor \ --runtime python27 \ --handler two_factor.two_factor \ --from-file two_factor.py \ --trigger-http
يمكن إنشاء مثيل لهذه الوظيفة بشكل غير متزامن من كود JavaScript من جانب العميل بعد قيام المستخدم بإدخال كلمة المرور الصحيحة. يمكن لواجهة الويب عرض الصفحة فورًا لإدخال الرمز ، ويمكن للمستخدم ، حالما يتلقى الرمز ، إبلاغه بخدمة تسجيل الدخول التي تم تسجيل هذا الرمز فيها بالفعل.
لذلك ، فإن نهج FaaS قد سهل إلى حد كبير من تطوير خدمة بسيطة وغير متزامنة وموجهة نحو الحدث يتم إطلاقها عند قيام المستخدم بتسجيل الدخول إلى النظام.
الحدث الناقلون
هناك عدد من التطبيقات ، في الواقع ، من الأسهل اعتبارها بمثابة خط أنابيب للأحداث المزدوجة. تشبه خطوط أنابيب الأحداث في الغالب المخططات القديمة الجيدة. يمكن تمثيلها كرسم بياني موجه لتزامن الأحداث ذات الصلة. في إطار نمط خط أنابيب الأحداث ، تتوافق العقد مع الوظائف ، والأقواس التي تربطها تتوافق مع طلبات HTTP أو أي نوع آخر من مكالمات الشبكة.
بين عناصر الحاوية ، كقاعدة عامة ، لا توجد حالة عامة ، ولكن قد يكون هناك سياق مشترك أو نقطة مرجعية أخرى ، على أساسها سيتم إجراء البحث في المستودع.
ما هو الفرق بين خط الأنابيب وهندسة الخدمات الصغيرة؟ هناك نوعان من الاختلافات الهامة. الفرق الأول والأكثر أهمية بين وظائف الخدمة والخدمات التي تعمل باستمرار هو أن خطوط أنابيب الأحداث هي أساسها الأحداث. بنية Microservice ، على العكس من ذلك ، تنطوي على مجموعة من خدمات العمل باستمرار. بالإضافة إلى ذلك ، يمكن أن تكون خطوط أنابيب الأحداث غير متزامنة وتربط مجموعة متنوعة من الأحداث. من الصعب تخيل كيف يمكن دمج الموافقة على تطبيق جيرا في تطبيق خدمة microservice. في الوقت نفسه ، من السهل تخيل كيفية اندماجه في خط أنابيب الحدث.
كمثال ، ضع في اعتبارك خط أنابيب يكون فيه الحدث المصدر هو تحميل الكود في نظام التحكم في الإصدار. هذا الحدث يؤدي إلى إعادة إنشاء التعليمات البرمجية. قد يستغرق التجميع عدة دقائق ، وبعدها يتم إنشاء حدث يؤدي إلى تشغيل وظيفة الاختبار للتطبيق المجمع. اعتمادًا على نجاح التجميع ، تتخذ وظيفة الاختبار إجراءات مختلفة. في حالة نجاح التجميع ، يتم إنشاء تطبيق ، والذي يجب أن يوافق عليه الشخص حتى يبدأ تشغيل الإصدار الجديد من التطبيق. إغلاق التطبيق بمثابة إشارة إلى تشغيل الإصدار الجديد. في حالة فشل التجميع ، يقدم Jira طلبًا للخطأ الذي تم اكتشافه ويخرج خط الأنابيب.
ورشة عمل. تنفيذ خط أنابيب لتسجيل مستخدم جديد
النظر في مهمة تنفيذ سلسلة من الإجراءات لتسجيل مستخدم جديد. عند إنشاء حساب جديد ، يتم دائمًا تنفيذ سلسلة كاملة من الإجراءات ، على سبيل المثال ، إرسال بريد إلكتروني ترحيب. هناك أيضًا عدد من الإجراءات التي قد لا يتم تنفيذها في كل مرة ، على سبيل المثال ، الاشتراك في رسالة إخبارية بالبريد الإلكتروني حول الإصدارات الجديدة من المنتج (المعروف أيضًا باسم البريد العشوائي).
يتضمن أحد الأساليب إنشاء خدمة متجانسة لإنشاء حسابات جديدة. مع هذا النهج ، يكون فريق التطوير مسؤولاً عن الخدمة بأكملها ، والتي يتم نشرها أيضًا ككل. هذا يجعل من الصعب إجراء تجارب وإجراء تغييرات على عملية تفاعل المستخدم مع التطبيق.
النظر في تنفيذ تسجيل دخول المستخدم كخط أنابيب حدث للعديد من خدمات FaaS. مع هذا الفصل ، فإن وظيفة إنشاء المستخدم ليس لديها فكرة عما يحدث أثناء تسجيل دخول المستخدم. لديها قائمتين:
- قائمة بالإجراءات اللازمة (على سبيل المثال ، إرسال بريد إلكتروني ترحيبي) ؛
- قائمة بالإجراءات الاختيارية (على سبيل المثال ، الاشتراك في رسالة إخبارية).
يتم تطبيق كل من هذه الإجراءات أيضًا على أنها FaaS ، وقائمة الإجراءات ليست أكثر من قائمة بوظائف رد اتصال HTTP. لذلك ، وظيفة إنشاء المستخدم لديه النموذج التالي:
def create_user(context): # for key, value in required.items(): call_function(value.webhook, context.json) # # for key, value in optional.items(): if context.json.get(key, None) is not None: call_function(value.webhook, context.json)
يمكن الآن تنفيذ كل من المتعهدين وفقًا لمبدأ FaaS:
def email_user(context): # user = context.json['username'] msg = ', {}, , !".format(user) send_email(msg, contex.json['email]) def subscribe_user(context): # email = context.json['email'] subscribe_user(email)
متحللة بهذه الطريقة ، تصبح خدمة FaaS أكثر بساطة ، وتحتوي على عدد أقل من سطور الكود وتركز على تنفيذ وظيفة واحدة محددة. يبسط نهج الخدمة المجهرية كتابة التعليمات البرمجية ، ولكن يمكن أن يؤدي إلى صعوبات في نشر وإدارة ثلاثة خدمات مجهرية مختلفة. هنا يثبت نهج FaaS نفسه بكل مجده ، لأنه نتيجة استخدامه يصبح من السهل جدًا إدارة أجزاء صغيرة من التعليمات البرمجية. كما يتيح لنا تصور عملية إنشاء مستخدم في شكل خط أنابيب للحدث أن نفهم بشكل عام ما يحدث بالضبط عند تسجيل دخول المستخدم ، وذلك ببساطة عن طريق تتبع التغيير في السياق من وظيفة إلى وظيفة داخل خط الأنابيب.
»يمكن الاطلاع على مزيد من المعلومات حول الكتاب على
موقع الناشر»
المحتويات»
مقتطفاتخصم 20 ٪ على القسائم للمصممين -
أنماط التصميمعند دفع النسخة الورقية من الكتاب ، يتم إرسال نسخة إلكترونية من الكتاب عن طريق البريد الإلكتروني.