التحقق من بوابة الخدمات العامة الإقليمية تحت التحميل من خلال دمية

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

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

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

صورة

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

يتمثل دورنا في التحضير في تنظيم الاختبارات والتوصيات بشأن تكوينات التخزين المؤقت في nginx ، حسنًا ، قمنا أيضًا بإعداد تعليمات للمستخدمين الذين لديهم "السلوك" الموصى به.

بالنسبة لأولئك الذين لا يعرفون مشكلة الكتابة في الصف الأول
, . . , , - ( , — ), , - , , . , , , – , . .

1- , . 0:00 , 10:00 26 . , – . 10:00 , — , - .

. . 2017 . . , , . .

خدمة لمورد مطلوب كمهمة فنية


إن المشكلة في خدمات مثل "الكتابة إلى الصف الأول" في المؤشر المتكامل للحمل (أو احتمال الاستعلامات) التي تميل إلى "وظيفة دلتا" (دالة، ، وظيفة Dirac) تظهر بوضوح على الرسوم البيانية في شكل قمم. في هذه اللحظة ، هناك زيادة متعددة في المكالمات في فترة زمنية قصيرة.

إحصائيات دالة and وذروة الاستعلام

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

من المستحيل جسديًا سكب الحجم بالكامل في 10 دقائق من الساعة الرملية في دقيقة واحدة - من الواضح أنها ستنهار. وبالمثل لتقديم الخدمات. لا يفاجئ أحدًا - عندما يحين دور MFC والفضائح لتلقي الخدمات ، لكنه يفاجئ الجميع - لماذا سقطت البوابة.

هناك أنماط مختلفة من سلوك التعامل مع الحمل من نظرية الانتظار :

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

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

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

تراجع العدالة
, «», . ? «» , . . — , . « ». . .

تنظيم تقديم الخدمات


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

نموذج حساب تقريبي للتطبيقات الشرطية 1000 ساعة في الساعة على النحو التالي:

  • الذروة من 5 إلى 10 دقائق من البداية وسيتم إيداع 80 ٪ من الطلبات بموجب قاعدة باريتو
  • تقليديا ، نحن نخطط 160 تطبيق في الدقيقة أو 3 تطبيقات في الثانية.

في الواقع ، حدث التقديم الأول بعد دقيقة واحدة و 45 ثانية ، وبلغت ذروة الطلبات من 4 دقائق.

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

معتكف حول التعليمات والترتيبات التنظيمية
.

, « » . .. . , - ..

, , , . - . , , .

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

إعدادات nginx نفسها قياسية إلى حد ما. هنا من المهم اختيار القيود التي يمكن أن يتحملها النظام. التقاطها - أي بدء وضع الطلبات في قائمة الانتظار عندما يتوقع أن يصل الخادم إلى حدود إمكاناته.

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

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

صورة

أدى هذا إلى تقليل عدد الطلبات المحتملة من 89 طلبًا إلى 14 والحجم من 2.1 ميغابايت (بالنسبة إلى 1000 مستخدم قاموا بتحديث الصفحة ، هذه ذروة محتملة تبلغ 4-8 جيجابت / ثانية) إلى 38 كيلوبايت (نتذكر جميعًا حزمة الويب ، ولكن بالنسبة لمنصات الإدخال ، هذا ليس من السهل دائما القيام بذلك). وفقًا لنتائج المقطع ، كان لا يزال من الضروري تخزين ذاكرة التخزين المؤقت ليس فقط في النظام ، ولكن أيضًا في nginx بعض الدلائل من النموذج والمصنفات الديناميكية غير المستخدمة في وقت الذروة وفرض العمر الافتراضي لها. ومع زيادة التحميل ، من المنطقي عمومًا وضع الصفحة الثابتة الرئيسية بالكامل مع توجيه المستخدمين إلى الخدمة المطلوبة أو إنشاء مورد منفصل للخدمة.

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

لن أصف التحسين الأمثل للنظام نفسه - أثناء اختبار الحمل ، تم تحديد الاختناقات - بشكل أساسي في استعلامات DBMS وتم تحسين الفهارس والاستعلامات نفسها.

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

  • — , , . — 5-10 ( iPhone ) 5- 375 / (1 10 , application/x-www-form-urlencoded – 20 ), 100 625 /. 100/ — . , « ». — ? , . , ?
  • أدلة متطورة. عادة ما يتم زيادة الحمل باستخدام دليل عنوان FIAS أو CLADR. المشاكل هنا بسبب الحجم - FIAS يأخذ ما يصل إلى 40 جيجابايت في قاعدة البيانات ويستغرق بعض الوقت للبحث عنها. أعشار الثانية ، ولكن مضروبًا في 1000 طلب متزامن ، قم بتحميل أي نظام. بدون تحضير خاص ، ربما في شكل خدمة ويب منفصلة وعلى مورد منفصل ، من الصعب تحمل الحمل - وبالتالي ، غالبًا ما يستخدمون حقل نص عادي للعنوان.

حسنًا ، دعنا ننتقل إلى الاختبارات.

اختبار الحمل قيد التحضير


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

بادئ ذي بدء ، قمنا بتجميع ملف تعريف سلوك المستخدم وقسمنا الإجراء إلى مراحل رئيسية:

  1. إذن جماعي في ESIA
  2. تحديث نموذج الخدمة لمرة واحدة ،
  3. تغذية جماعية

لكل مرحلة من المراحل قمنا باختبار منفصل.

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

الاختبار نفسه بسيط. يوجد أدناه جزء من النقر على زر "تسجيل الدخول" في بوابة الخدمات لإدخال البيانات في ESIA.

await page.waitForSelector(AUTH_AVAIL,{timeout:OPT_ELEM_WAIT_TIME});
const needAuth = await page.$(ELEM_AUTH_IN);
if (!needAuth) throw (new Error(`  `));
        
await page.waitForSelector(AUTH_BUT, OPT_ELEMENT_VISIBLE);
await page.click(AUTH_BUT);
await waitNewUrl(page, 'https://esia.gosuslugi.ru/idp/rlogin?cc=bp', OPT_PAGE_WAIT_TIME);
await page.waitForSelector('#mobileOrEmail', OPT_ELEMENT_VISIBLE);
let text = await elemGetText(page, '#authnFrm > div.login-slils-box > div > div.detected > div.left > div.this-user');
if (text) 
   text = text.replace(/ -\(\)/g, '');        
if (text && text.indexOf(user) === -1) {
  await page.click('div.click-to-another > a');
  await page.waitForSelector('#authnFrm > div.login-slils-box > div >' +
                ' div.detected > div.left > div.this-user', OPT_ELEMENT_INVISIBLE);
}
await page.waitForSelector('#password', OPT_ELEMENT_VISIBLE);
await page.type('#mobileOrEmail', user);
await page.type('#password', pwd);
await page.click('#loginByPwdButton');

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

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

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

صورة

جزء من الاختبار لفتح الصفحة الرئيسية وتحديث الصفحة.

try {
  await page.setViewport(PUP_OPT);
  await page.goto(BASE_URL);
  await page.setCookie(...cookies[worker.id]);
  await page.goto(`${BASE_URL}/nd/lk/form/dnv.htm`);
  rdyRefresh++;
} catch (err) {
  console.error(`#       ${data}: ${err.message}`);
  getErr++;
  await page.screenshot({path: filename});
}
for (let i = 0; i < AMOUNT_REFRESH - 1; i++) {
  const filenameIter = path.join(BASE_DIR, PIC_DIR, `${data}-${i}.png`);
   try {
       await page.reload({waitUntil: ["networkidle0", "domcontentloaded"]});
        rdyRefresh++;
    } catch (err) {
        if (!err.message.includes('Navigation failed because browser')) {
           console.error(`#     ${data}-${i}: ${err.message}`);
           getErr++;
           await page.screenshot({path: filenameIter});
        }
   }
}

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

شظية.

for (let i = 0; i < AMOUNT_RESEND; i++) {
   const filename = path.join(BASE_DIR, PIC_DIR, `${data}-${i}.png`);
  try {
     await page.goto('https://uslugi27.ru/nd/lk/form/dnv.htm');
  } catch (err) {
      console.error(`#      1  ${data}-${i}: ${err.message}`);
      await page.screenshot({path: filename});
      getErr++;
      continue;
 }
 try {
     const FORM_PREF = '#createForm > div:nth-child(4) > ';
     await clickDelayed(page,`${FORM_PREF}fieldset.petgroup.ungroupped-attrs > div > div:nth-child(4) > div.col-md-9.attr-data`);
// <…>
     await page.type(`${FORM_PREF}fieldset:nth-child(2) > div > div:nth-child(1) > div.col-md-9.attr-data > input`, '');
// <…>
  } catch (err) {
      console.error(`#      ${data}-${i}: ${err.message}`);
      await page.screenshot({path: filename});
     continue;
  }
  try {
      await page.click('#createForm > div.col_100.controls > button.btn.btn-primary.pull-right.next');
      await clickDelayed(page,`#createForm > div:nth-child(5) > fieldset > div > div:nth-child(1) > div > div`);
       await page.click('#createForm > div:nth-child(5) > fieldset > div > div:nth-child(2) > div > div');
       await page.click('#createForm > div.col_100.controls > button.btn.btn-success.pull-right.submit');
  } catch (err) {
    console.error(`#     ${data}-${i}: ${err.message}`);
    await page.screenshot({path: filename});
    sendErr++;
    continue;
  }

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

document.querySelector('#createForm > div:nth-child(4) > fieldset.petgroup.ungroupped-attrs > div > div:nth-child(4) > div.col-md-9.attr-data').click();
 document.querySelector('#createForm > div:nth-child(4) > fieldset:nth-child(2) > div > div:nth-child(1) > div.col-md-9.attr-data > input').value = '';

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

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

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

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

All Articles