• خانه
  • وبلاگ
  • راهنمای مبتدیان برای امتحان مجدد مدل انحراف نمایی

راهنمای مبتدیان برای امتحان مجدد مدل انحراف نمایی

 تاریخ انتشار :
/
  وبلاگ
راهنمای مبتدیان برای امتحان مجدد مدل انحراف نمایی


گنجاندن Retry Pattern در فضای توسعه به دلیل خرابی های گذرا است که بیشتر در محیط توسعه ابری. خرابی های گذرا در طول توسعه زمانی رخ می دهد که یک مورد با یک جزء خارجی ارتباط برقرار می کند، اما آن جزء یا سرویس خارجی در دسترس نیست.

اما مشکل موقتی است و وقتی دوباره با سرویس یا کامپوننت تماس گرفتیم وصل می شود. به این محدودیت های موقت، خرابی های گذرا می گویند و در محیط ابری احتمال این خرابی ها افزایش یافته است.

از آنجایی که سیستم رایانش ابری در طیف کاملی از اجزا و برنامه های مختلف توزیع شده است، مشکلات میزبانی وجود دارد. برخی از از دست دادن لحظه ای شبکه یا کمبود سرویس بیشتر به مشکلات کمک می کند. استقرار RetryPattern راه حلی برای دور زدن این مسائل است.

اما پس چرا از امتیاز نمایی استفاده می کنیم؟

ایده پشت استفاده از لغو نمایی با تلاش مجدد این است که به جای تلاش مجدد پس از انتظار برای یک دوره زمانی ثابت، تأخیر بین تلاش های مجدد را پس از هر تلاش ناموفق افزایش دهیم.

به عنوان مثال، زمانی که از SFTP برای انتقال و کپی فایل ها استفاده می کنیم، انجام کار به زمان نیاز دارد. می توانیم از این زمان برای اجرای تابع ExponentialBackoff استفاده کنیم.

برای استفاده از تاخیر نمایی، می توانیم از کتابخانه منبع باز (Polly) استفاده کنیم. کتابخانه Polly از Framework 4.0 به بعد پشتیبانی می کند و همچنین با .NET Core سازگار است.

برای استفاده از Polly باید بسته Polly را از بسته NuGet در ویژوال استودیو نصب کنیم.

چند

در اینجا ما فقط این مفهوم را به اشتراک می گذاریم که چگونه می توانیم از کتابخانه Polly برای بررسی اینکه آیا یک فایل در جاده موجود است یا نه استفاده کنیم.

برای انجام این کار، ما تابعی ایجاد می کنیم تا بررسی کنیم که آیا فایل به روش خاصی در دسترس است یا خیر.

public static bool IsAvailableFile(string filePath) 

        { 

            Policy retryPolicy = Policy.Handle<IOException>().WaitAndRetry(6, i => TimeSpan.FromSeconds(Math.Pow(2, i))); 

            retryPolicy.Execute(() => 

            { 

                using (FileStream stream = File.OpenRead(filePath)) 

                { 

                    stream.Close(); 

                } 

            }); 

            return true;   }

در کد بالا می بینیم که مسیر فایل را به تابع منتقل کرده ایم و بررسی می کند که آیا فایل به طور کامل ذخیره شده است یا خیر. اگر نه، زمان معینی منتظر می ماند، دوباره امتحان کنید و دوباره وضعیت فایل را بررسی کنید.

بر این اساس، مقدار واقعی فایلی که با موفقیت ذخیره شده است را برمی گرداند. اکنون می توانیم از این فایل برای پردازش بیشتر استفاده کنیم. کد بالا را می توان در هر جایی با توجه به نیاز ما استفاده کرد.

علاوه بر بررسی اینکه آیا فایل ذخیره شده است یا نه، می توانیم از کتابخانه Polly برای موارد دیگر استفاده کنیم. این شامل؛

  • دوباره امتحان کن
  • تعویض
  • زمان انتظار
  • عایق مانع
  • تخفیف به روشی روان و بدون نخ

اسکریپت کد زیر نشان می دهد که چگونه می توانیم از HTTP Retires ادغام شده با Polly در lHTTPClientFactory استفاده کنیم.

lHttpClientFactory پس از Dot Net Core 2.1 در دسترس است. به همین دلیل توصیه می شود از آخرین بسته های Net 5 NuGet استفاده کنید.

یک مشتری تکراری Polly را پیکربندی کنید startup.cs

//ConfigureServices()  - Startup.cs

services.AddHttpClient<IBasketService, BasketService>()

.SetHandlerLifetime(TimeSpan.FromMinutes(5))  //Set lifetime to five minutes

.AddPolicyHandler(GetRetryPolicy());

برای داشتن یک رویکرد ماژولارتر به خط مشی HTTP Retry مجدد، می توانید از روش استقرار دیگری پیروی کنید که در زیر آورده شده است.

static IAsyncPolicy<HttpResponseMessage>GetRetryPolicy()
{
    return HttpPolicyExtensions
.HandleTransientHttpError()
.OrResult(msg =>msg.StatusCode == System.Net.HttpStatusCode.NotFound)
.WaitAndRetryAsync(6, retryAttempt =>TimeSpan.FromSeconds(Math.Pow(2,
retryAttempt)));
}

با استفاده از Polly، می‌توانیم یک خط‌مشی تلاش مجدد را با n تلاش مجدد تعریف کنیم، و در صورت وجود یک استثنا HTTP، مانند ثبت خطا، اقداماتی را می‌توان انجام داد.

در مورد بالا، این خط‌مشی به گونه‌ای پیکربندی شده است که شش بار با تلاش مجدد نمایی شروع شود، که با دو ثانیه شروع می‌شود.

خط مشی امتحان مجدد می تواند سیستم ما را در صورت موازی بودن و مقیاس پذیری بالا تحت تأثیر قرار دهد. برای غلبه بر اوج چنین تلاش های مجددی که از سوی بسیاری از مشتریان با یک وقفه جزئی انجام می شود، می توانیم اضافه کنیم استراتژی نوسان به الگوریتم / خط مشی سعی مجدد.

این کار باعث بهبود عملکرد سیستم از انتها به انتها می شود. برای بررسی کد به نمونه زیر مراجعه کنید استراتژی نوسان.

var delay = Backoff.DecorrelatedJitterBackoffV2(medianFirstRetryDelay: TimeSpan.FromSeconds(1), retryCount: 5);
 var retryPolicy = Policy
.Handle<FooException>()
.WaitAndRetryAsync(delay);

تعویض

برای کنترل عیوب گذرا درازمدت، یک قطع کننده مدار اضافه شده است. می‌توانیم یک بریکر به کد اضافه کنیم تا سرویس را بپیچانیم و مدار را باز علامت‌گذاری کنیم تا نشان دهیم که سرویس یا قطعه در دسترس نیست یا حتی پس از چندین بار تلاش پاسخ نمی‌دهد.

اگر مشکلی پیش بیاید، دائماً دکمه را فشار می دهیم که از تلاش بیشتر برای تکرار عملیات جلوگیری می کند.

این معمولاً زمانی استفاده می شود که اعتیاد بسیار غیرقابل اعتمادی داشته باشیم. در این مورد، ما می خواهیم به طور کامل فراخوانی آن را متوقف کنیم، زیرا تلاش های اضافی برای فراخوانی ممکن است وضعیت را بدتر کند. یک مثال از این می تواند یک پایگاه داده متراکم باشد.

امضا:

Policy
.Handle<Exception>()
.CircuitBreakerAsync(
	int exceptionsAllowedBeforeBreaking,
TimeSpandurationOfBreak,
	Action<Exception, TimeSpan>onBreak,
	Action onReset);

دستکاری کننده<Изключение>: مانند قوانین امتحان مجدد. این نوع استثناهایی را که این خط‌مشی می‌تواند مدیریت کند، تعیین می‌کند.

CircuitBreakerAsync (():

استثناهای int قبل از خراب شدن مجاز هستند نشان می دهد که چند استثنا در یک ردیف باعث راه اندازی یک قطع کننده مدار می شود.

TimeSpandurationOfBreak تعیین می کند که چه مدت مدار شکسته باقی می ماند.

عملدر استراحت نماینده ای است که به شما امکان می دهد یک عمل (معمولاً برای ثبت نام استفاده می شود) را هنگام شکستن زنجیره انجام دهید.

عمل بازنشانی نماینده ای است که به شما امکان می دهد هنگام تنظیم مجدد مدار، عملی را انجام دهید (دوباره معمولاً برای ثبت نام).

در مثال خود، یک خط مشی قطع کننده مدار ایجاد کردیم که پس از 1 شکست روشن می شود.

اگرچه مثال بالا برای نمایش است، می‌توانید این مقدار را در یک سناریوی واقعی با توجه به الزامات و سرویسی که می‌خواهید تماس بگیرید، تغییر دهید.

public async Task&lt;string&gt;GetGoodbyeMessage()
{
  try
  {
Console.WriteLine($"Circuit State: {_circuitBreakerPolicy.CircuitState}");
	return await _circuitBreakerPolicy.ExecuteAsync&lt;string&gt;(async () =&gt;
	{
    	return await _messageRepository.GetGoodbyeMessage();
	});
  }
  catch (Exception ex)
  {
	return ex.Message;
  }
}

این به این دلیل است که وقتی خط مشی شکن خاموش است، هر تلاش دیگری برای انجام این عمل به طور خودکار انجام می شود استثنا برای BrokenCircuitException.

به جای مدیریت صحیح خطا، ما به سادگی پیام خطا را به عنوان مقدار بازگشتی ارسال می کنیم – باز هم، این فقط برای اهداف نمایشی است، بنابراین می توانیم ببینیم که خطا چگونه به نظر می رسد. در ابتدا متوجه خواهید شد که اشتباه به این صورت است.

راهنمای مبتدیان برای امتحان مجدد مدل انحراف نمایی

اما زمانی که برای اولین بار یک استثنا رخ می دهد که باعث ایجاد خط مشی قطع کننده مدار می شود، مقدار را به صورت باز می گرداند.

راهنمای مبتدیان برای امتحان مجدد مدل انحراف نمایی

تمام تلاش‌های بعدی برای تماس با سرویس با شکست مواجه می‌شوند استثنا برای BrokenCircuitException توسط سیاست برای قطع کننده مدار پرتاب می شود.

نتیجه

RetryPattern، Backoff Exponential و Circuit Breaker ابزارهای عالی در این دنیای مدرن توسعه هستند. استفاده از آنها در یک محیط توسعه که توسط محاسبات ابری، میکروسرویس ها و معماری بدون سرور هدایت می شود، افزایش خواهد یافت.

اگرچه این مولفه های توسعه مهم هستند، اما باید از آنها عاقلانه استفاده کرد. استفاده از آنها به محیط توسعه، الزامات برنامه و رفتار خدمات بستگی دارد. بنابراین، قبل از استفاده از هر یک از این اجزا، حتما این جنبه ها را در نظر بگیرید.

در حالی که در مورد تمرین های توسعه آینده محور صحبت می کنیم، ما در DEV IT درک تأثیر و اهمیت توسعه بر تجارت. وقتی می خواهید راه حل آماده ای برای آینده بسازید، دیگر به دنبال آن نباشید. نیازهای خود را به ما اطلاع دهید و ما به شما در ایجاد راه حل مناسب کمک خواهیم کرد.

نشریه A Beginner’s Guide to Re-Trying to Implementation An Exponential Deviation Model برای اولین بار در مجله DEV IT ظاهر شد.