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

لنبدأ بالتعريف. كيف تبدو في الواقع؟

هذا هو المكان الذي يتم فيه تقديم تطبيق Yandex.Taxi في حالة عدم عمل إحدى الخدمات - الخدمة لاختيار الوجهة التي ينبغي أن يأخذك بها السائق. كما ترى ، لا يوجد على هذه الشاشة زر كبير "اطلب سيارة أجرة" ، مما يعني أن المستخدم لن يكون قادرًا على استخدام الخدمة. ولكن يمكنك محاولة تدهور والسماح للمستخدم بعدم اختيار النقطة ب.
عندها لن يكون قادرًا على معرفة السعر الدقيق للرحلة ، ولن نكون قادرين على بناء طريق ، لكن المستخدم سيحصل على زر "اطلب سيارة أجرة" وسيتمكن من استخدام خدماتنا. الوظيفة الرئيسية لتطبيقنا ستكون متاحة. هذا ما أريد أن أتحدث عنه اليوم. حول كيفية التدهور بشكل صحيح وما يمكن القيام به مع الخدمة التي تعطلت.
خطة الأداء. سوف أخبرك بكيفية تحطيم ما يجب فعله بالخدمة. يمكنك إيقاف تشغيله ، وكذلك استخدام سلوك مختلف. بعد ذلك ، سأخبرك بكيفية فهمك عندما يحين وقت إيقاف تشغيل خدمتنا. وفي النهاية سأتحدث عن بعض الفروق الدقيقة التي كان علينا مواجهتها عندما قمنا بإنشاء نظام تدهور تلقائي لـ Yandex.Taxi.
ما الذي يمكن عمله مع خدمة مكسورة؟ يمكنك إيقاف تشغيل الوظيفة. إذا كانت خدمة التنبؤ بالوجهات الفردية لا تعمل ، فإنك تقوم بإيقاف هذه الخدمة. إذا كانت المحادثة بين السائق والراكب لا تعمل ، فإنك تقوم بإيقاف تشغيل الدردشة. إذا لم تتمكن من طلب سيارة ، فأنت بذلك تقوم بإيقاف تشغيل زر "Order a car" - لا ، هذا لا يعمل. لا يمكن إيقاف تشغيل جميع الوظائف. وإذا تعذر إيقاف تشغيل شيء ما ، فيجب تطبيق نهج مختلف. على سبيل المثال ، يمكنك محاولة إنشاء تخطيط أو وظيفة مبسطة. نحن نسمي هذا السلوك المبسط في ياندكس باليقطين - نقول أن الخدمة قد تحولت إلى قرع.
لننظر في هذه الحلول بمزيد من التفصيل.

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


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

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

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

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

لدينا عميل ، ويتصل بخدمة الوجهة ويحصل على خطأ.

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

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

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

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

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

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

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

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

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

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

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

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