أحد أسئلتي المفضلة في المقابلات هو "ماذا تخبرك كلمات مثل و ؟" لأنها تفتح لك الفرصة لإجراء مناقشة شيقة مع الشخص الذي تجري معه المقابلة... أو لا تفتحها لأنها تدور حول هذا الموضوع. في رأيي، من المهم للغاية أن نفهم سبب استخدامنا لهذه التقنية. async await أشعر أن العديد من المطورين يفضلون الاعتماد على عبارة "إنها أفضل ممارسة" واستخدام الأساليب غير المتزامنة بشكل أعمى. توضح هذه المقالة الفرق بين الطرق المتزامنة وغير المتزامنة في الممارسة العملية. أدوات تطبيق واجهة برمجة تطبيقات الويب .NET (هدف الاختبار) 2 قاعدة بيانات Azure SQL 2 Azure App Service على Windows (يستضيف التطبيق) Azure App Insights (لتجميع المقاييس) إطار عمل (لمحاكاة تحميل المستخدم). locust إعدادات سأجري اختبارًا بالطريقة التالية. يتم تشغيل نسختين مستقلتين من Locust على جهازين. تحاكي نسخ Locust مستخدمًا يقوم بما يلي: يصل المستخدم من مضيف الجراد 1 إلى نقطة النهاية ويحصل على الاستجابة، ويبقى خاملاً لمدة 0.5 إلى 1 ثانية (يكون التأخير الزمني الدقيق عشوائيًا). ويتكرر ذلك حتى نهاية التجربة. المتزامنة لخدمة التطبيق 1، يتصرف المستخدم من المضيف الجراد 2 بنفس الطريقة تمامًا، مع اختلاف واحد فقط - فهو يصل إلى نقطة النهاية غير المتزامنة لخدمة التطبيق 2. تحت الغطاء، يتصل كل تطبيق من تطبيقات الخدمة بقاعدة بياناته الخاصة وينفذ استعلام SELECT يستغرق خمس ثوانٍ ويعيد بضعة صفوف من البيانات. راجع كود وحدة التحكم أدناه للحصول على مراجع. سأستخدم Dapper لإجراء مكالمة إلى قاعدة البيانات. أود أن ألفت انتباهك إلى حقيقة أن نقطة النهاية غير المتزامنة تستدعي قاعدة البيانات بشكل غير متزامن أيضًا ( ). QueryAsync<T> من الجدير بالذكر أنني أقوم بنشر نفس الكود لكلا خدمتي التطبيق. أثناء الاختبار، ينمو عدد المستخدمين بالتساوي حتى يصل إلى العدد المستهدف ( ). يتم التحكم في سرعة النمو من خلال معلمة (عدد المستخدمين الفريدين الذين يتم الانضمام إليهم في الثانية) - فكلما زاد العدد، زادت سرعة إضافة المستخدمين. يتم ضبط على 10 مستخدمين/ثانية لجميع التجارب. عدد المستخدمين معدل الظهور معدل الظهور تقتصر جميع التجارب على 15 دقيقة. يمكنك العثور على تفاصيل تكوين الجهاز في قسم التفاصيل الفنية للمقالة. المقاييس — تُظهر عدد الطلبات التي قام التطبيق بمعالجتها فعليًا وإرجاع رمز الحالة. الطلبات في الدقيقة — يوضح عدد الخيوط التي تستهلكها خدمة التطبيق. عدد الخيوط متوسط زمن الاستجابة، مللي ثانية تشير الخطوط الحمراء إلى نقطة النهاية غير المتزامنة، والخطوط الزرقاء إلى نقطة النهاية المتزامنة، على التوالي. هذا كل ما يتعلق بالنظرية، فلنبدأ. التجربة رقم 1 : 75 (لكل خدمة) عدد المستخدمين يمكننا أن نرى أن كلا النقطتين النهائيتين تعملان بشكل مشابه - التعامل مع حوالي 750 طلبًا في الدقيقة مع متوسط وقت استجابة يبلغ 5200 مللي ثانية. الرسم البياني الأكثر إثارة للاهتمام في هذه التجربة هو اتجاه الخيوط. يمكنك رؤية أرقام أعلى بكثير لنقطة النهاية المتزامنة (الرسم البياني الأزرق) - أكثر من 100 خيط! ولكن هذا متوقع، ويتوافق مع النظرية ــ عندما يأتي طلب، ويجري التطبيق مكالمة إلى قاعدة البيانات، يتم حظر الخيط لأنه يتعين عليه الانتظار حتى اكتمال رحلة الذهاب والإياب. وبالتالي، عندما يأتي طلب آخر، يتعين على التطبيق إنتاج خيط جديد للتعامل معه. يُثبت الرسم البياني الأحمر — عدد مؤشرات الترابط في نقطة النهاية غير المتزامنة — سلوكًا مختلفًا. فعندما يأتي طلب ويقوم التطبيق بإجراء مكالمة إلى قاعدة البيانات، يعود المؤشر إلى مجموعة مؤشرات الترابط بدلاً من حظره. وبالتالي، عندما يأتي طلب آخر، يتم إعادة استخدام هذا المؤشر المجاني. وعلى الرغم من تزايد الطلبات الواردة، لا يتطلب التطبيق أي مؤشرات ترابط جديدة، لذا يظل عدد مؤشرات الترابط كما هو. يجدر ذكر المقياس الثالث - . أظهرت كلتا النقطتين النهائيتين نفس النتيجة - 5200 مللي ثانية. لذا، لا يوجد فرق من حيث الأداء. متوسط وقت الاستجابة الآن حان الوقت لرفع الرهانات. التجربة رقم 2 : 150 عدد المستخدمين لقد ضاعفنا الحمل. وتتعامل نقطة النهاية غير المتزامنة مع هذه المهمة بنجاح - حيث يتراوح معدل حول 1500. وفي النهاية وصل الأخ المتزامن إلى رقم مماثل وهو 1410. ولكن إذا نظرت إلى الرسم البياني أدناه، فسترى أن الأمر استغرق 10 دقائق! طلباتها في الدقيقة السبب هو أن نقطة النهاية المتزامنة تتفاعل مع وصول مستخدم جديد من خلال إنشاء سلسلة أخرى، ولكن تتم إضافة المستخدمين إلى النظام (فقط للتذكير بأن هو 10 مستخدمين/ثانية) بشكل أسرع مما يمكن لخادم الويب التكيف معه. ولهذا السبب قام بوضع العديد من الطلبات في قائمة الانتظار في البداية. معدل الظهور ومن غير المستغرب أن يظل مقياس عند مستوى 34 تقريبًا لنقطة النهاية غير المتزامنة، في حين ارتفع من 102 إلى 155 لنقطة النهاية المتزامنة. وانخفض بشكل مماثل لمعدل - كان وقت الاستجابة المتزامنة أعلى بكثير في بداية التجربة. إذا احتفظت بالاختبار لمدة 24 ساعة، فإن الأرقام المتوسطة ستصبح متساوية. عدد الخيوط متوسط وقت الاستجابة الطلب في الدقيقة التجربة رقم 3 : 200 عدد المستخدمين وتهدف التجربة الثالثة إلى إثبات الاتجاهات التي تم الكشف عنها خلال التجربة الثانية - حيث يمكننا أن نرى المزيد من التدهور في نقطة النهاية المتزامنة. خاتمة إن استخدام العمليات غير المتزامنة بدلاً من المتزامنة لا يؤدي إلى تحسين الأداء أو تجربة المستخدم بشكل مباشر. أولاً، يعزز الاستقرار والقدرة على التنبؤ تحت الضغط. بعبارة أخرى، يرفع عتبة التحميل حتى يتمكن النظام من معالجة المزيد قبل تدهوره. الملحق رقم 1. التفاصيل الفنية Azure App Service: B1، 100 ، 1,75 جيجابايت من الذاكرة، مكافئ الحوسبة من سلسلة A. ACU قاعدة بيانات Azure SQL: Standard S4: 200 وحدة بيانات رقمية، ومساحة تخزين 500 ميجابايت. إعدادات اتصال SQL: الحد الأقصى لحجم المجموعة=200. الملحق رقم 2. ملاحظات لتحقيق أفضل نتيجة اختبار، كان يجب عليّ تشغيل الاختبارات من جهازين افتراضيين موجودين في نفس الشبكة حيث توجد خدمات التطبيق المستهدفة. ومع ذلك، افترضت أن تأخر الشبكة سيؤثر على كلا التطبيقين بطريقة مماثلة إلى حد ما. وبالتالي، لا يمكن أن يعرض هذا الهدف الرئيسي للخطر - مقارنة كيفية تصرف الطرق المتزامنة وغير المتزامنة. الملحق رقم 3. تجربة إضافية ما الذي قمت باختراقه لإجبار نقطة النهاية المتزامنة على الأداء بشكل غير متزامن تقريبًا ورسم الرسم البياني أدناه (ظروف التجربة هي نفسها الموجودة في التجربة الثالثة - 200 مستخدم)؟