منذ العام الماضي ، بدأ تنظيم hackathons في شركتنا. أول منافسة من هذا القبيل كانت ناجحة للغاية ، وكتبنا عنها في
المقال . تم عقد hackathon الثاني في فبراير 2019 ولم يكن أقل نجاحًا. منظم
كتب مؤخرا عن أهداف هذا الأخير.
تم إعطاء المشاركين مهمة مثيرة للاهتمام مع حرية كاملة في اختيار كومة التكنولوجيا لتنفيذه. كان من الضروري تطبيق نظام أساسي للقرار من أجل النشر المريح لوظائف تسجيل العملاء التي يمكن أن تعمل على التدفق السريع للتطبيقات ، وتحمل الأحمال الثقيلة ، وتم ضبط النظام نفسه بسهولة.
المهمة غير تافهة ويمكن حلها بعدة طرق ، كما رأينا في العرض التقديمي النهائي لمشاريع المشاركين. كان هناك 6 فرق من 5 أشخاص في hackathon ، جميع المشاركين لديهم مشاريع جيدة ، ولكن تبين أن برنامجنا هو الأكثر تنافسية. لقد حصلنا على مشروع ممتع للغاية ، أود التحدث عنه في هذا المقال.
حلنا عبارة عن منصة تستند إلى بنية Serverless داخل Kubernetes ، مما يقلل الوقت اللازم لإنتاج ميزات جديدة للإنتاج. يتيح للمحللين كتابة التعليمات البرمجية في بيئة ملائمة لهم ونشرها في المنتج دون مشاركة المهندسين والمطورين.
ما هو التهديف؟
Tinkoff.ru ، مثل العديد من الشركات الحديثة ، لديه سجل العملاء. التسجيل هو نظام لتقييم العملاء يعتمد على الأساليب الإحصائية لتحليل البيانات.
على سبيل المثال ، يطلب العميل إلينا منح قرض ، أو فتح حساب IP معنا. إذا كنا نخطط لمنحه قرضًا ، فأنت بحاجة إلى تقييم ملاءته ، وإذا كان الحساب ملكية خاصة ، فعليك التأكد من أن العميل لن يقوم بمعاملات احتيالية.
تستند هذه القرارات إلى نماذج رياضية تحلل كلاً من بيانات التطبيق نفسه وبيانات التخزين الخاصة بنا. بالإضافة إلى تسجيل النقاط ، يمكن أيضًا استخدام طرق إحصائية مماثلة في عمل الخدمة لإنشاء توصيات فردية بشأن المنتجات الجديدة لعملائنا.
يمكن لطريقة مثل هذا التقييم تلقي مجموعة متنوعة من بيانات الإدخال. وفي مرحلة ما ، يمكننا إضافة معلمة جديدة إلى المدخلات ، والتي ، وفقًا للتحليل على البيانات التاريخية ، ستزيد من تحويل استخدام الخدمة.
نقوم بتخزين الكثير من البيانات حول علاقات العملاء ، ويتزايد حجم هذه المعلومات باستمرار. لكي تنجح عملية التسجيل ، تتطلب معالجة البيانات أيضًا قواعد (أو نماذج رياضية) تتيح لك أن تقرر بسرعة من الذي يوافق على التطبيق ومن يرفض ، ومن يقدم آخر بعض المنتجات لتقييم اهتمامه المحتمل.
لهذه المهمة ، نحن نستخدم بالفعل
نظام صنع القرار
IBM WebSphere ILOG JRules BRMS ، والذي ، بناءً على القواعد التي وضعها المحللين والتقنيين والمطورين ، يقرر ما إذا كان سيتم اعتماد منتج مصرفي معين لعميل أو رفضه.
هناك العديد من الحلول الجاهزة في السوق ، كل من نماذج التسجيل وأنظمة صنع القرار بأنفسهم. نحن نستخدم أحد هذه الأنظمة في شركتنا. لكن النشاط التجاري ينمو ويزيد من تنوعه ، حيث يتزايد عدد العملاء وعدد المنتجات المعروضة ، وإلى جانب ذلك ، تبرز الأفكار حول كيفية تحسين عملية صنع القرار الحالية. من المؤكد أن الأشخاص الذين يعملون مع النظام الحالي لديهم العديد من الأفكار حول كيفية جعله أكثر بساطة وأفضل وأكثر راحة ، ولكن في بعض الأحيان تكون الأفكار من الخارج مفيدة. من أجل جمع الأفكار السليمة ، تم تنظيم Hackathon جديد.
مهمة
تم عقد الاختراق في 23 فبراير. عُرض على المشاركين مهمة قتالية: لتطوير نظام لصنع القرار ، كان من المفترض أن يستوفي عددًا من الشروط.
قيل لنا كيف يعمل النظام الحالي وما هي الصعوبات التي تنشأ أثناء تشغيله ، وكذلك أهداف العمل التي يجب على المنصة قيد التطوير السعي لتحقيقها. يجب أن يحتوي النظام على وقت سريع للقواعد التي يتم تطويرها في السوق بحيث يتم تشغيل قانون عمل المحللين في أسرع وقت ممكن. وبالنسبة للتدفق الوارد للتطبيقات ، يجب أن يميل وقت اتخاذ القرار إلى الحد الأدنى. أيضًا ، يجب أن يكون النظام المتطور قادرًا على البيع المتبادل من أجل إعطاء العميل الفرصة لشراء منتجات الشركة الأخرى إذا تمت الموافقة عليها من قبلنا وفائدة محتملة من جانب العميل.
من الواضح أنه في ليلة واحدة ، من المستحيل كتابة مشروع جاهز للإطلاق يدخل بالتأكيد مرحلة الإنتاج ، ومن الصعب للغاية تغطية النظام بالكامل ، لذلك طُلب منا تنفيذ جزء منه على الأقل. تم تحديد عدد من المتطلبات التي يجب أن يفي بها النموذج الأولي. يمكن للمرء محاولة تغطية جميع المتطلبات ككل ، والعمل بالتفصيل على أقسام فردية من النظام الأساسي المطور.
بالنسبة للتكنولوجيا ، تم منح جميع المشاركين حرية اختيار كاملة. كان من الممكن استخدام أي مفاهيم وتقنيات: دفق البيانات ، التعلم الآلي ، تحديد مصادر الأحداث ، البيانات الضخمة وغيرها.
قرارنا
بعد جلسة العصف الذهني الصغيرة ، قررنا أن حل FaaS سيكون مثاليًا للمهمة.
بالنسبة لهذا الحل ، كان من الضروري إيجاد إطار عمل مناسب للخوادم لتطبيق قواعد نظام صنع القرار المطور. نظرًا لاستخدام Kubernetes بنشاط في إدارة البنية التحتية في Tinkoff ، فقد درسنا العديد من الحلول الجاهزة القائمة عليها ، وسأتحدث عنها لاحقًا.
لإيجاد الحل الأكثر فعالية ، نظرنا إلى المنتج المطوّر من خلال أعين مستخدميه. المستخدمون الرئيسيون لنظامنا هم محللون مشاركون في تطوير القواعد. يجب نشر القواعد على الخادم ، أو ، كما في حالتنا ، يتم نشرها على السحابة لاتخاذ القرارات اللاحقة. من وجهة نظر المحلل ، سير العمل هو كما يلي:
- يكتب المحلل برنامج نصي أو قاعدة أو نموذج ML استنادًا إلى بيانات من المستودع. كجزء من hackathon ، قررنا استخدام Mongodb ، ولكن اختيار نظام التخزين غير مهم هنا.
- بعد اختبار القواعد المطورة على البيانات التاريخية ، يقوم المحلل بوضع كوده في لوحة المشرف.
- لضمان الإصدار ، ستنتقل جميع الشفرات إلى مستودعات Git.
- من خلال لوحة المسؤول ، سيكون من الممكن نشر الكود في السحابة كوحدة نمطية منفصلة بدون خادم.
يجب أن تمر بيانات المصدر من العملاء عبر خدمة إثراء متخصصة ، مصممة لإثراء الطلب الأولي ببيانات من المستودع. كان من المهم تنفيذ هذه الخدمة بحيث تعمل مع مستودع واحد (يأخذ منه المحلل البيانات عند تطوير القواعد) من أجل الحفاظ على بنية بيانات موحدة.
حتى قبل الاختراق ، قررنا إطار عمل Serverless الذي سنستخدمه. هناك عدد قليل جدا من التقنيات في السوق التي تنفذ هذا النهج. أشهر حلول العمارة في Kubernetes هي Fission و Open FaaS و Kubeless. هناك حتى
مقال جيد مع وصفهم والتحليل المقارن .
بعد وزن جميع إيجابيات وسلبيات ، اخترنا
الانشطار . من السهل جدًا إدارة هذا الإطار Serverless وتلبية متطلبات المهمة.
للعمل مع Fission ، تحتاج إلى فهم مفهومين أساسيين: الوظيفة والبيئة. الوظيفة (دالة) هي جزء من الكود المكتوب بإحدى اللغات التي توجد بها بيئة الانشطار (البيئة).
تشمل قائمة البيئات المنفذة في إطار هذا الإطار Python و JS و Go و JVM والعديد من اللغات والتقنيات الشائعة الأخرى.
الانشطار هو أيضا قادر على أداء وظائف ، مقسمة إلى عدة ملفات ، معبأة مسبقا في الأرشيف. يتم توفير عملية الانشطار في مجموعة Kubernetes من خلال قرون متخصصة ، يتم إدارتها بواسطة الإطار نفسه. للتفاعل مع السنفات العنقودية ، يجب تعيين مسار لكل وظيفة ، والتي يمكنك من خلالها تمرير معلمات GET أو طلب نص في حالة طلب POST.
نتيجة لذلك ، خططنا للحصول على حل يسمح للمحللين بنشر نصوص قاعدة مطورة دون مشاركة المهندسين والمطورين. كما أن النهج الموصوف يلغي الحاجة للمطورين لإعادة كتابة رمز المحللين بلغة أخرى. على سبيل المثال ، بالنسبة لنظام اتخاذ القرارات الحالي الذي نستخدمه ، يتعين علينا كتابة قواعد في تقنيات ولغات ضيقة النطاق ، يكون نطاقها محدود للغاية ، وهناك أيضًا اعتماد قوي على خادم التطبيق ، حيث يتم نشر جميع مسودات قواعد البنك في بيئة واحدة. نتيجة لذلك ، لنشر قواعد جديدة ، من الضروري تحرير النظام بأكمله.
في الحل الذي اقترحناه ، ليست هناك حاجة لإطلاق القواعد ، يتم نشر الرمز بسهولة عند النقر على زر. أيضًا ، تتيح لك إدارة البنية التحتية في Kubernetes عدم التفكير في التحميل والتحجيم ، يتم حل هذه المشكلات خارج نطاق الصندوق. واستخدام مستودع بيانات واحد يلغي الحاجة إلى مقارنة البيانات في الوقت الحقيقي مع البيانات التاريخية ، مما يبسط عمل المحلل.
ماذا حصلنا؟
منذ أن وصلنا إلى hackathon مع حل جاهز (في تخيلاتنا) ، نحتاج فقط إلى تحويل جميع أفكارنا إلى سطور من التعليمات البرمجية.
مفتاح النجاح في أي اختراق هو الإعداد وخطة جيدة الإعداد. لذلك ، قبل كل شيء ، قررنا الوحدات التي ستتألف بنية نظامنا من التقنيات التي سنستخدمها.
كانت بنية مشروعنا كما يلي:
يوضح هذا الرسم البياني نقطتي دخول ، محلل (المستخدم الرئيسي لنظامنا) وعميل.
يتم تنظيم عملية العمل مثل هذا. يقوم المحلل بتطوير وظيفة القاعدة ووظيفة إثراء البيانات لطرازه ، ويحفظ الكود في مستودع Git ، وينشر نموذجه في السحابة من خلال تطبيق المسؤول. ضع في اعتبارك كيف سيتم استدعاء الوظيفة الموسعة واتخاذ القرارات بشأن الطلبات الواردة من العملاء:
- يقوم العميل بملء نموذج على الموقع بإرسال طلبه إلى وحدة التحكم. يصل الطلب إلى مدخلات النظام ، والتي بموجبها يجب اتخاذ قرار ، ويتم تسجيلها في قاعدة البيانات في شكلها الأصلي.
- بعد ذلك ، يتم إرسال طلب خام للتخصيب ، إذا لزم الأمر. يمكنك استكمال الطلب الأولي بالبيانات من كل من الخدمات الخارجية ومن المستودع. يتم تخزين الاستعلام المنسق المستلم أيضًا في قاعدة البيانات.
- يتم تشغيل الوظيفة التحليلية ، والتي تتلقى طلبًا مخصبًا عند الإدخال وتتخذ قرارًا ، والذي يتم تسجيله أيضًا في المستودع.
كتخزين في نظامنا ، قررنا استخدام MongoDB في ضوء التخزين الموثق للبيانات في شكل وثائق JSON ، لأن خدمات التخصيب ، بما في ذلك الطلب الأولي ، جمعت جميع البيانات من خلال وحدات تحكم REST.
لذلك ، كان لدينا يوم لتنفيذ النظام الأساسي. قمنا بتوزيع الأدوار بنجاح ، كل عضو في الفريق كان مسؤولاً عن مسؤوليته في مشروعنا:
- لوحة إدارة الواجهة الأمامية لعمل المحلل والتي يمكن من خلالها تنزيل القواعد من نظام التحكم في الإصدار من البرامج النصية المكتوبة ، واختيار الخيارات لإثراء بيانات الإدخال وتعديل النصوص البرمجية للقواعد عبر الإنترنت.
- لوحة المشرف الخلفية التي تتضمن واجهة برمجة تطبيقات REST للدمج الأمامي وتكامل VCS.
- إعداد البنية التحتية في Google Cloud وتطوير خدمة تخصيب البيانات المصدر.
- الوحدة النمطية لدمج تطبيق المسؤول مع إطار Serverless للنشر اللاحق للقواعد.
- نصوص قواعد لاختبار صحة النظام بأكمله وتجميع التحليلات للتطبيقات الواردة (القرارات المتخذة) للتظاهرة النهائية.
لنبدأ بالترتيب.
تمت كتابة الواجهة الأمامية لدينا في Angular 7 باستخدام مجموعة أدوات واجهة المستخدم المصرفية. النسخة النهائية من لوحة الادارة كانت كما يلي:
نظرًا لعدم وجود الكثير من الوقت ، حاولنا تنفيذ الوظيفة الرئيسية فقط. لنشر وظيفة في نظام Kubernetes ، كان من الضروري اختيار حدث (خدمة تحتاج إلى نشر قاعدة في السحابة) ورمز رمز الوظيفة التي تنفذ منطق القرار. لكل نشر القاعدة للخدمة المختارة ، كتبنا سجل لهذا الحدث. في لوحة الادارة ، يمكنك رؤية سجلات كل الأحداث.
تم تخزين كل رمز الوظيفة في مستودع Git البعيد ، والذي كان لابد أيضًا من ضبطه في لوحة الإدارة. لنسخ الكود ، تم تخزين جميع الوظائف في فروع مختلفة من المستودع. توفر لوحة الإدارة أيضًا القدرة على إجراء تعديلات على البرامج النصية المكتوبة ، بحيث لا يمكنك التحقق من الشفرة المكتوبة فقط قبل نشر وظيفة ما في الإنتاج ، ولكن أيضًا إجراء التغييرات اللازمة.
بالإضافة إلى وظائف القواعد ، أدركنا أيضًا إمكانية التخصيب التدريجي لبيانات المصدر باستخدام وظائف التخصيب ، والتي يتكون رمزها أيضًا من البرامج النصية التي يمكنك من خلالها الذهاب إلى مستودع البيانات ، والاتصال بخدمات الجهات الخارجية وإجراء العمليات الحسابية الأولية. لإظهار حلنا ، قمنا بحساب علامة البروج الخاصة بالعميل الذي ترك التطبيق وحدد مشغل خدمة الجوال الخاص به باستخدام خدمة REST لجهة خارجية.
تمت كتابة الواجهة الخلفية للنظام الأساسي بلغة Java وتنفيذها كتطبيق Spring Boot. لتخزين بيانات المشرف ، خططنا في الأصل لاستخدام Postgres ، ولكن كجزء من الاختراق ، قررنا أن نقتصر على H2 البسيط ، من أجل توفير الوقت. في النهاية ، تم تطبيق التكامل مع Bitbucket لإصدار وظائف تخصيب الاستعلام ونصوص القاعدة. للتكامل مع مستودعات Git البعيدة ،
تم استخدام مكتبة JGit ، وهو نوع من
البرامج المجمعة على أوامر CLI التي تتيح لك تنفيذ أي تعليمات git باستخدام واجهة برنامج ملائمة. لذلك كان لدينا اثنين من المستودعات منفصلة ، لوظائف التخصيب والقواعد ، ويتم ترتيب جميع البرامج النصية في الدلائل. من خلال واجهة المستخدم ، كان من الممكن اختيار نص الالتزام الأخير لفرع مستودع التخزين التعسفي. عند إجراء تغييرات على الكود من خلال لوحة المشرف ، تم إنشاء تعهدات من الكود المعدل في المستودعات البعيدة.
لتنفيذ فكرتنا ، كنا بحاجة إلى بنية تحتية مناسبة. قررنا نشر مجموعة Kubernetes الخاصة بنا في السحابة. خيارنا هو Google Cloud Platform. تم تثبيت إطار عمل fless serverless على مجموعة Kubernetes ، التي نشرناها في Gcloud. في البداية ، تم تنفيذ خدمة إثراء البيانات المصدر من خلال تطبيق جافا منفصل ملفوف في قرنة داخل كتلة k8s. ولكن بعد عرض أولي لمشروعنا في منتصف hackathon ، فقد أوصينا بجعل خدمة التخصيب أكثر مرونة من أجل توفير فرصة لاختيار كيفية إثراء البيانات الخام للتطبيقات الواردة. ولم يكن لدينا خيار سوى جعل خدمة التخصيب أيضًا بدون خادم.
للعمل مع Fission ، استخدمنا Fission CLI ، والذي يجب تثبيته أعلى Kubernetes CLI. إن نشر الوظائف في نظام k8s بسيط للغاية ، فأنت تحتاج فقط إلى تعيين مسار داخلي وإدخال للدالة للسماح بحركة المرور الواردة إذا كان الوصول خارج المجموعة مطلوبًا. عادةً لا يستغرق نشر وظيفة واحدة أكثر من 10 ثوانٍ.
العرض النهائي للمشروع وتلخيص
لإثبات تشغيل نظامنا ، وضعنا على خادم بعيد نموذجًا بسيطًا يمكنك من خلاله التقدم بطلب للحصول على أحد منتجات البنك. بالنسبة للطلب ، كان عليك إدخال الأحرف الأولى من الاسم وتاريخ الميلاد ورقم الهاتف.
تم نقل البيانات من نموذج العميل إلى وحدة التحكم ، التي أرسلت في وقت واحد تطبيقات لجميع القواعد المتاحة ، قبل إثراء البيانات وفقًا للشروط المحددة ، وتخزينها في وحدة تخزين مشتركة. في المجموع ، قمنا بنشر ثلاث وظائف لصنع القرار للتطبيقات الواردة و 4 خدمات لتخصيب البيانات. بعد إرسال التطبيق ، تلقى العميل حلنا:
بالإضافة إلى الرفض أو الموافقة ، تلقى العميل أيضًا قائمة بالمنتجات الأخرى التي أرسلنا لها طلبات بالتوازي. لذلك أظهرنا إمكانية البيع المتبادل في منصتنا.
في المجموع ، كانت 3 منتجات بنكية اخترعت متوفرة:
- الائتمان.
- لعبة
- الرهن العقاري.
خلال كل عرض ، قمنا بنشر وظائف معدة ومخطوطات تخصيب لكل خدمة.
تحتاج كل قاعدة إلى مجموعة بيانات الإدخال الخاصة بها. لذلك ، للموافقة على الرهن العقاري ، قمنا بحساب علامة زودياك العميل وارتبطنا بمنطق التقويم القمري. للموافقة على اللعبة ، تحققنا من أن العميل كان في سن قانونية ، ولإصدار قرض ، أرسلنا طلبًا إلى خدمة مفتوحة خارجية لتحديد مشغل الهاتف المحمول ، واتخذنا قرارًا بشأنه.
لقد حاولنا أن نجعل عرضنا مثيرًا للاهتمام وتفاعليًا ، ويمكن لأي شخص حاضر الدخول في نموذجنا والتحقق من توفر خدماتنا الوهمية له. وفي نهاية العرض التقديمي ، أظهرنا تحليلات التطبيقات التي تم تلقيها ، حيث تم عرض عدد الأشخاص الذين استخدموا خدماتنا ، وعدد الموافقات ، والرفض.
لجمع التحليلات عبر الإنترنت ، قمنا بالإضافة إلى ذلك بنشر أداة
قاعدة البيانات المفتوحة المصدر
Metabase وقمنا بربطها في مستودعنا. تتيح لك قاعدة التعريف إنشاء شاشات مع تحليلات استنادًا إلى البيانات التي نهتم بها ، ما عليك سوى تسجيل اتصال قاعدة بيانات ، وتحديد الجداول (في حالتنا ، مجموعات البيانات ، نظرًا لأننا استخدمنا MongoDB) ، والإشارة إلى المجالات التي تهمنا.
نتيجة لذلك ، حصلنا على نموذج أولي جيد لمنصة صنع القرار ، وفي العرض التوضيحي ، يمكن لكل مستمع اختبار أداءه شخصيًا. حل مثير للاهتمام ، ونموذج أولي جاهز ومظاهرة ناجحة سمحت لنا بالفوز ، على الرغم من المنافسة القوية في مواجهة الفرق الأخرى. أنا متأكد من أنه في مشروع كل فريق ، يمكنك أيضًا كتابة مقال مثير للاهتمام.