Skip to content

Latest commit

 

History

History
106 lines (52 loc) · 20.6 KB

Throttling pattern.md

File metadata and controls

106 lines (52 loc) · 20.6 KB

‏Throttling pattern

مصرف منابع مورداستفاده توسط یک نمونه از یک اپلیکیشن، یک مستأجر (tenant) شخصی یا یک سرویس را کنترل کنید. این مورد می‌تواند به سیستم اجازه دهد تا به وظایف خود به‌درستی ادامه دهد و نیازمندی‌های سطح سرویس را برآورده کند، حتی زمانی که افزایش بار، فشار شدیدی را بر مصرف منابع وارد می‌کند.

زمینه و مشکل

بار روی یک برنامه ابری معمولاً در طول زمان بر اساس تعداد کاربران فعال یا نوع فعالیت‌هایی که انجام می‌دهند متفاوت است. به‌عنوان‌مثال، احتمالاً کاربران بیشتری در طول ساعات کاری فعال هستند یا ممکن است سیستم در پایان هر ماه نیاز به انجام تجزیه‌وتحلیل‌های محاسباتی پرهزینه‌ای داشته باشد. همچنین ممکن است انفجارهای ناگهانی و غیرمنتظره در فعالیت‌ها وجود داشته باشد. اگر نیازهای پردازشی سیستم از ظرفیت منابع موجود بیشتر شود، از کارایی سیستم کاسته می‌شود و حتی ممکن است سیستم از کار بیفتد. اگر سیستم باید نیازمندی‌های سطح سرویس موردنظر را برآورده کند، چنین شکستی می‌تواند غیرقابل‌قبول باشد.

بسته به اهداف تجاری برنامه، رویکردهای زیادی برای مدیریت بارهای مختلف در فضای ابری وجود دارد. یک راهبُرد استفاده از مقیاس خودکار (autoscaling) برای تطبیق منابع ارائه شده با نیازهای کاربر در هر زمان معین است. این مورد پتانسیل زیادی را دارد که به طور مداوم تقاضای کاربر را برآورده کند، درحالی‌که هزینه‌های جاری را بهینه می‌کند. بااین‌حال، درحالی‌که autoscaling می‌تواند باعث تأمین منابع اضافی شود، این تأمین منابع فوری نیست. اگر تقاضا به‌سرعت رشد کند، ممکن است یک پنجره زمانی وجود داشته باشد که در آن کسری منابع وجود داشته باشد.

راه‌حل

این سیستم می‌تواند چندین راهبُرد throttling را اجرا کند، از جمله:

*‏ رد درخواست‌‌های یک کاربر که قبلاً بیش از n بار در ثانیه در یک بازه زمانی معین به APIهای سیستم دسترسی داشته است. این امر مستلزم آن است که سیستم میزان استفاده از منابع را برای هر tenant یا کاربری که یک برنامه را اجرا می‌کند اندازه‌گیری کند. برای اطلاعات بیشتر، راهنمای سنجش سرویس (Service Metering Guidance) را ببینید.

*‏ غیرفعال‌کردن یا کاهش کارایی سرویس‌‌های غیرضروری و کمتر لازم به‌طوری‌که سرویس ضروری بتوانند بدون مانع با منابع کافی اجرا شوند. به‌عنوان‌مثال، اگر برنامه در حال پخش خروجی ویدئو باشد، می‌تواند به‌وضوح پایین‌تری تغییر کند.

*‏ استفاده از سطح‌بندی بار (load leveling) برای هموارسازی حجم فعالیت (این رویکرد با جزئیات بیشتری توسط الگوی Queue-based Load Leveling pattern پوشش داده شده است). در یک محیط دارای چندین tenant، این رویکرد کارایی هر tenant را کاهش می‌دهد. اگر سیستم باید ترکیبی از tenant ‌هایی با SLA ‌های مختلف را پشتیبانی کند، کار برای tenant ‌های باارزش ممکن است بلافاصله انجام شود. درخواست‌‌های tenantها دیگر را می‌توان متوقف کرد و زمانی بررسی شود که عقب‌ماندگی تسک مورد کاهش‌یافته باشد. الگوی صف اولویت می‌تواند برای کمک به پیاده‌سازی این رویکرد استفاده شود، همان‌طور که می‌تواند endpoint ‌های مختلف را برای سطوح/اولویت‌‌های سرویس مختلف نشان دهد.

*‏ به تعویق‌انداختن عملیاتی که از طرف applicationها یا tenant با اولویت پایین‌تر انجام می‌شود. این عملیات را می‌توان به حالت تعلیق درآورد یا محدود کرد، به‌استثنای یک استثنا برای اطلاع tenant که سیستم مشغول است و این عملیات باید بعداً دوباره امتحان شود.

*‏ هنگام ادغام با برخی از سرویس‌‌های شخص ثالث که ممکن است در دسترس نباشند یا با خطا مواجه شوند، باید مراقب باشید. تعداد درخواست‌‌های هم‌زمان در حال پردازش را کاهش دهید تا لاگ‌ها بی‌جهت با موارد خطا پر نشوند. همچنین از هزینه‌‌های مرتبط با پردازش مجدد درخواست‌‌هایی که به دلیل آن سرویس‌های شخص ثالث (3rd-party) مواجه می‌شوند، اجتناب کنید. سپس، هنگامی که درخواست‌ها با موفقیت پردازش شدند به پردازش درخواست‌‌های معمولی بازگردید. یکی از کتابخانه‌‌هایی که این قابلیت را پیاده‌سازی می‌کند  NServiceBus است.

شکل زیر نمودار ناحیه‌ای برای استفاده از منابع (ترکیبی از حافظه، CPU، پهنای باند و عوامل دیگر) را در برابر زمان برای برنامه‌‌هایی که از هر سه ویژگی استفاده می‌کنند نشان می‌دهد. یک ویژگی ناحیه‌ای از کارایی است، مانند مؤلفه‌ای که مجموعه خاصی از وظایف را انجام می‌دهد، قطعه کدی که محاسبات پیچیده‌ای را انجام می‌دهد، یا عنصری که سرویسی مانند کش در حافظه را ارائه می‌دهد. این ویژگی‌ها دارای برچسب‌های A، B و C هستند.

این ناحیه زیر خط یک ویژگی مربوط به منابعی را نشان می‌دهد که برنامه‌ها هنگام فراخوانی این ویژگی‌ها از آنها استفاده می‌کنند. به‌عنوان‌مثال، ناحیه زیر خط برای ویژگی A، منابع استفاده شده توسط برنامه‌‌هایی را نشان می‌دهد که از ویژگی A استفاده می‌کنند و ناحیه بین خطوط برای ویژگی A و ویژگی B، منابع استفاده شده توسط برنامه را با استفاده از ویژگی B را نشان می‌دهد. تجمیع مناطق برای هر ویژگی، استفاده کلی از منابع سیستم را نشان می‌دهد.

شکل قبلی اثرات عملیات به تعویق‌انداختن (deferring operations) را نشان می‌دهد. درست قبل از زمان T1، کل منابع تخصیص‌داده‌شده به همه برنامه‌ها با استفاده از این ویژگی‌ها به یک آستانه (محدودیت استفاده از منابع) می‌رسد. در این مرحله، applicationها در خطر محدودیت منابع موجود هستند. در این سیستم، ویژگی B نسبت به ویژگی A یا ویژگی C از اهمیت کمتری برخوردار است، بنابراین به طور موقت غیرفعال می‌شود و منابعی که استفاده می‌کرد آزاد می‌شوند. بین زمان‌‌های T1 و T2، برنامه‌‌هایی که از ویژگی A و ویژگی C استفاده می‌کنند به طور عادی به کار خود ادامه می‌دهند. در نهایت، استفاده از منابع این دو ویژگی به حدی کاهش می‌یابد که در زمان T2، ظرفیت کافی برای فعال‌کردن مجدد ویژگی B وجود دارد.

رویکردهای مقیاس خودکار (autoscaling) و throttling همین‌طور می‌توانند برای کمک به واکنش‌گرا (responsive) بودن برنامه‌ها با SLAها ترکیب شوند. اگر چه انتظار می‌رود تقاضای مصرف منابع همچنان بالا بماند اما throttling یک راه‌حل موقت ارائه می‌کند تا در نتیجه سیستم scales out شود، در این مرحله، کارایی کامل سیستم قابل بازیابی است.

شکل بعدی یک نمودار ناحیه‌ای از استفاده کلی از منابع توسط همه applicationها در حال اجرا در یک سیستم در برابر زمان را نشان می‌دهد و نشان می‌دهد که چگونه throttling را می‌توان با autoscaling ترکیب کرد.

در زمان T1، آستانه تعیین‌شدهٔ رسیدن به حد استفاده از منابع رسیده است. در این مرحله، سیستم می‌تواند شروع به کوچک‌شدن مقیاس (scale out) کند. بااین‌حال، اگر منابع جدید به‌سرعت در دسترس قرار نگیرند، ممکن است منابع موجود تمام شده و سیستم از کار بیفتد. برای جلوگیری از این اتفاق، سیستم به طور موقت، همان‌طور که قبلاً توضیح داده شد، خفه (throttled) می‌شود. هنگامی که autoscaling کامل شد و منابع اضافی در دسترس قرار گرفت، می‌توان خفه کن (throttling) را رها کرد.

مسائل و ملاحظات:

هنگام تصمیم‌گیری در مورد نحوه اجرای این الگو باید نکات زیر را در نظر بگیرید:

*‏ Throttling یک برنامه و راهبُرد موردنظر وابسته به یک تصمیم‌گیری در زمینه معماری سیستم است که کل طراحی یک سیستم را تحت‌تأثیر قرار می‌دهد. Throttling باید در مراحل اولیه طراحی برنامه در نظر گرفته شود؛ زیرا اضافه‌کردن آن پس از پیاده‌سازی یک سیستم آسان نیست.

*‏ Throttling باید به‌سرعت انجام شود. سیستم باید توانایی تشخیص افزایش فعالیت را داشته باشد و متناسب با آن واکنش نشان دهد. همچنین سیستم باید بتواند پس از کاهش بار به‌سرعت به حالت اولیه خود بازگردد. این مستلزم آن است که داده‌های کارایی مناسب به طور مداوم جمع‌آوری و نظارت شود.

*‏ اگر سرویسی باید درخواست کاربر را به طور موقت رد کند، باید یک کد خطای خاص مانند 429 ("Too many requests") و 503 ("Server Too Busy") را برگرداند تا برنامه client بتواند دلیل ردکردن از سرویس را بفهمد. به‌خصوص اینکه یک request به دلیل throttling رد شده است.

*‏ HTTP 429 نشان می‌دهد که کلاینت درخواست‌های زیادی را در یک پنجره زمانی ارسال کرده و از حد از پیش تعیین شده فراتر رفته است.

*‏ ‌ HTTP 503 نشان می‌دهد که سرویس برای پردازش درخواست‌ها و requestها آماده نیست. دلیل رایج این است که سرویس تحت‌تأثیر بارهای سنگین (load spikes) موقتی را بیش از حد انتظار تجربه می‌کند.

برنامه کلاینت می‌تواند قبل از retry درخواست، مدتی صبر کند. یک هدر HTTP از نوع Retry-After باید در پیام گنجانده شود تا از کلاینت در انتخاب راهبُرد retry پشتیبانی کند.

*‏ درحالی‌که یک سیستم autoscale می‌شود، می‌توان از Throttling به‌عنوان یک واحد موقت استفاده کرد. در برخی موارد بهتر است به‌جای استفاده از مقیاس‌کردن(scale) از یک throttle ساده استفاده کنیم؛ مثلاً زمانی که یک فعالیت شدید و غیرمنتظره که مدت طولانی ‌ای ماندگار نیست رو برنامه رخ‌داده است، در این حالت استفاده از روش scaling می‌تواند هزینه زیادتری را نسبت به روش Throttling در پیش داشته باشد.

*‏ اگر در زمانی که سیستم به‌صورت خودکار مقیاس می‌شود، از throttling به‌عنوان یک واحد موقت استفاده شود و اگر تقاضای منابع خیلی سریع افزایش یابد، سیستم ممکن است نتواند به کار خود ادامه دهد - حتی زمانی که در حالت throttling کار می‌کند. اگر این مورد قابل‌قبول و اجرا نیست، ظرفیت و منابع بیشتری را در نظر گرفته و autoscaling تهاجمی‌تر را پیکربندی کنید.

*‏ متعادل‌سازی منابع مصرفی برای عملیات مختلف، همان‌طور که آن منابع معمولاً هزینه‌های اجرایی برابری ندارند. برای مثال، محدودیت‌‌های throttling ممکن است برای عملیات خواندن کمتر و برای عملیات نوشتن بیشتر باشد. درنظرنگرفتن هزینه یک عملیات می‌تواند منجر به هدررفت ظرفیت منابع موجود و در معرض قراردادن یک بردار حمله (attack vector) بالقوه شود.

*‏ تغییر در لحظه پیکربندی و تنظیمات مربوط به رفتار و عملکرد راهبُرد throttling به‌خصوص در حالت اجرا یا runtime بسیار مطلوب است. اگر سیستمی با بار غیرعادی روبرو شود که پیکربندی اعمال شده قادر به تحمل آن نیست بهتر است برای تثبیت سیستم و همگام‌شدن با ترافیک فعلی، محدودیت‌‌های throttling باید افزایش یا کاهش یابد. deployment ‌های پرخطر و کند در این مرحله مناسب نیستند پس با استفاده از الگوی External Configuration Store pattern پیکربندی throttling به‌صورت خارجی است و می‌توان آن را تغییر داد و بدون deployment خاصی آن اعمال کرد.

چه زمانی از این الگو استفاده کنیم؟

از این الگو در حالت‌های زیر استفاده کنید:

*‏ برای اطمینان از اینکه یک سیستم به ملاحظات سطح سرویس ادامه می‌دهد.

*‏ برای جلوگیری از انحصار مصرف منابع توسط یک tenant یا یک برنامه خاص.

*‏ برای مدیریت حجم زیاد درخواست‌ها و فعالیت‌ها در زمان‌‌های کوتاه و لحظه‌ای.

*‏ برای کمک به بهینه‌سازی هزینه یک سیستم با محدودکردن حداکثر سطوح منابع موردنیاز برای حفظ کارایی آن.

مثال

شکل زیر نشان می‌دهد که چگونه throttling را می‌توان در یک سیستم داری چندین tenant پیاده‌سازی کرد. کاربران هر یک از tenantها به یک برنامه میزبانی ابری(cloud-hosted) دسترسی پیدا می‌کنند که در آنجا فرم نظرسنجی‌ها را تکمیل و ارسال می‌کنند. این برنامه حاوی ابزاردقیقی است که بر میزان ارسال درخواست‌‌های این کاربران به برنامه را مانیتور می‌کند.

به‌منظور جلوگیری از تأثیرگذاری کاربران در یک tenant بر پاسخگویی و دردسترس‌بودن برنامه برای همه کاربران دیگر، محدودیتی برای تعداد درخواست‌‌هایی در هر ثانیه اعمال می‌شود که کاربران از هر یک tenant می‌توانند ارسال کنند. برنامه درخواست‌‌هایی را که از این حد فراتر می‌روند را مسدود می‌کند.

قدم بعدی

راهنمایی زیر ممکن است هنگام اجرای این الگو نیز مرتبط باشد:

مورد Instrumentation and Telemetry Guidance. باتوجه‌به اینکه throttling وابستگی به جمع‌آوری اطلاعات در مورد میزان استفاده از یک سرویس دارد پس این مورد نحوه تولید و ضبط اطلاعات مانیتورینگ سفارشی شده را شرح می‌دهد. راهنمای سنجش سرویس(Service Metering Guidance). نحوه اندازه‌گیری میزان استفاده از سرویس را به‌منظور درک نحوه استفاده از آنها شرح می‌دهد. این اطلاعات می‌تواند در تعیین نحوه throttle شدن یک سرویس مفید باشد. راهنمای Autoscaling Guidance. همان‌طور که قبلاً گفته شده است Throttling می‌تواند به‌عنوان یک معیار موقت در حین مقیاس‌پذیری خودکار(autoscale) سیستم یا رفع نیاز به یک سیستم برای autoscale استفاده شود. پس این مورد حاوی اطلاعاتی در مورد راهبُردهای autoscale است.

منابع مرتبط

الگوهای زیر نیز ممکن است هنگام اجرای این الگو مرتبط باشند:

الگوی بارگذاری بر اساس صف (Queue-based Load Leveling pattern). ترازکردن بار مبتنی بر صف مکانیزمی است که معمولاً برای اجرای الگوی Throttling استفاده می‌شود. یک صف می‌تواند به‌عنوان یک بافر عمل کند که به یکنواخت کردن نرخ ارسال درخواست‌های ارسال شده توسط یک برنامه به یک سرویس کمک می‌کند. الگوی صف اولویت(Priority Queue pattern). یک سیستم می‌تواند از صف اولویت‌بندی به‌عنوان بخشی از راهبُرد throttling خود برای حفظ کارایی برای برنامه‌‌های مهم یا باارزش بالاتر استفاده کند، درحالی‌که کارایی برنامه‌‌های کم‌اهمیت را کاهش می‌دهد. الگوی ذخیره پیکربندی خارجی(External Configuration Store pattern.). متمرکزکردن و خارج‌کردن سیاست‌‌های throttling قابلیت تغییر پیکربندی را در runtime را بدون نیاز به deploy مجدد فراهم می‌کند. سرویس‌ها می‌توانند به‌راحتی پیکربندی شوند و پیکربندی جدید را بلافاصله برای پایداری سیستم اعمال کنند.