مدیریت اجرای کارها با Hangfire

آیا تا به حال برایتان پیش آمده است که نیاز داشته باشید یک سری کارهای پس زمینه را در .Net هندل کنید؟ احتمالا نیاز داشته باشید یک سری جاب را Schedule کنید که در زمان های مشخصی کارهای مشخصی انجام دهند.برای هندل کردن این کارها یک راه کار ساده و مفید وجود دارد به نام Hangfire. Hangfire یک فریم‌ورک open-source است که به توسعه‌دهندگان در اجرای، تنظیم و مدیریت background tasks در هر برنامه‌ای .NET کمک می‌کند. Hangfire همچنین پشتیبانی از هر دو .NET Framework و .NET Core را دارد.// Scheduling a background job using Hangfire BackgroundJob.Enqueue(() => Console.WriteLine(&quotWelcome to the Hangfire World!&quot));در این مثال ساده، از Enqueue method برای اجرای یک متد به صورت asynchronous در background استفاده شده است.علاوه بر سادگی این ویژگی های بسیار جالب نیز در Hangfire قابل توجه است:ثبات کار: Hangfire از ذخیره ساز پایدار استفاده می کند و وظایف را برای پردازش ذخیره می کند. این وظایف را امن نگه داشته و در برابر بازسازی های فرآیند، راه انداز های دستگاه، یا هر شکست غیرمنتظره دیگر، حساس نمی شود.سعي خودکار: Hangfire وظایف ناموفق را خودکار بازسازي مي كند، بنابراین شما نيازي نداريد استثناء ها را به صورت دستي كنترل كنيد.داشبورد UI: داشبورد شفاف آن نمایشگر اجرای بصری وظایف زمان بندی شده، پردازش، موفق و شکست خورده است.پشتيباني از عبارات CRON: برای زمان بندي پيچيده، حتي عبارات CRON را پشتيباني مي كند// An example of scheduling recurring email notifications job using Hangfire RecurringJob.AddOrUpdate(() => EmailService.SendNotifications(), Cron.Daily);در این قطعه کد Hangfire ، AddOrUpdate EmailService.SendNotifications() را برای اجرای به عنوان یک کار روزانه تکرار شونده زمانبندی می کند. از کلاس Cron برای بیان زمانبندی های پیچیده به عنوان عبارات ساده Cron استفاده می کند.معماری Hangfire.NETجاب ها در Hangfire نسخه‌بندی می‌شوند، دوباره امتحان می‌شوند، در صف قرار می‌گیرند و بینworker های موجود توزیع می‌شوند. بیایید اجزای معماریHangfire را ببینیم:نوبت دهی(Enqueuing): هنگامی که یک job ایجاد می شود، به صف ها ارسال می شود.اجرا (Execution):worker ها به طور مداوم Jobها را در این صف ها چک می کنند.تلاش مجدد(Retry): اگر کاری با شکست مواجه شود، به صف تلاش های مجدد منتقل می شود و بعداً تلاش می شود.نسخه‌سازی(Versioning): نسخه‌های قدیمی‌تر Job ها برای یک فرآیند مقیاس‌بندی حفظ می‌شوند.نصب و پیکربندی Hangfire در دات نتپس از نصب بسته Hangfire NuGet، کد زیر را به Startup.cs اضافه کنید:public void Configuration(IAppBuilder app) { // Configuring Hangfire job storage. Let's use SQL Server. GlobalConfiguration.Configuration.UseSqlServerStorage(&quot<connection_string>&quot); // Setting up Hangfire Dashboard and Server in a .NET application app.UseHangfireDashboard(); app.UseHangfireServer(); }به <your_app_url>/hangfire بروید تا داشبورد داخلی Hanfire را ببینید.آشنایی با ویژگی‌هایHangfire.NETاز ویژگی های Hangfire.NET می توان به موارد زیر اشاره کرد:تلاش مجدد خودکار(Automatic Retry) : Hangfire به طور خودکار کارهای ناموفق را بر اساس یک الگوریتم back-off دوباره امتحان می کند.فهرست‌های سرور(Server Lists) : سرورهای Hangfire به‌طور خودکار به کلاستر پیوسته یا به صورت پویا از آن خارج می‌شوند تا دسترسی بالا را حفظ کنند.ادامه کار(Job Continuations): با استفاده از عبارتContinueWith می توانید مطمئن شوید که Job B بعد از Job A اجرا می شود.فیلترهای Job پیشرفته (Advanced Job Filters): فیلترهای سفارشی Job ها به شما این امکان را می دهند که رویداد مورد نظر را برای موارد موفقیت و شکست اضافه کنید.نحوه قرار دادن یک کار پس‌زمینه و به دنبال آن کار ادامه‌دار را بررسی کنید:// Let's queue a background job and a continuation job var jobId = BackgroundJob.Enqueue(() => Console.WriteLine(&quotBackground job&quot)); BackgroundJob.ContinueWith(jobId, () => Console.WriteLine(&quotContinuation job&quot));پیکربندیHangfire در یک پروژه C#// Setting up Hangfire in Startup.cs public void Configuration(IAppBuilder app) { app.UseHangfire(config => config.UseSqlServerStorage(&quot<your connection string>&quot)); app.UseHangfireDashboard(); app.UseHangfireServer(); }در قطعه کد داده شده، ما Hangfire را با نمونه SQL Server خود پیکربندی می کنیم، داشبورد Hangfire را برای نظارت تنظیم می کنیم و سرور Hangfire را راه اندازی می کنیم.ویژگی های کلیدیHangfire Cویژگی های Hangfire در C#به صورت زیر هستند:تلاش‌های مجدد خودکار: گاهی اوقات وظایف با شکست مواجه می‌شوند، اما Hangfire تضمین می‌کند که آنها شانس دیگری برای موفقیت خواهند داشت. مدیریت استثناها: Hangfire می‌تواند استثنائات را به‌خوبی شناسایی و مدیریت کند و برنامه شما را از خرابی احتمالی نجات دهد.اولویت بندی کارها: از آنجایی که همه وظایف برابر نیستند وبرخی باید با اولویت بالاتری اجرا شوند، Hangfire به ما برای رسیدن به این موضوع کمک می‌کند.. استراتژی‌های شکست سفارشی: اگر یک کار شکست بخورد، شما تصمیم می‌گیرید چه اتفاقی بیفتد. کارهای برنامه ریزی شده: روزانه، هفتگی یا یک بار در ماه آبی، کارهای خود را با سهولت برنامه ریزی کنید.مسائل رایج در Hangfire و راه حل های آنهاکار تکرارشونده متوقف شده (Stalled Recurring Job ): معمولاً ناشی از یک خطا در خود Job است . بررسی گزارش استثنا در داشبورد Hangfire معمولاً به مشکل اشاره می کند.//Recurring Job Setup RecurringJob.AddOrUpdate(() => Console.Write(&quotDaily&quot), Cron.Daily); //Let's assume an exception occurs RecurringJob.AddOrUpdate(() => throw new Exception(&quotOops!&quot), Cron.Daily);در این مثال، کار به دلیل یک استثنا با شکست مواجه می شود و Hangfire اجرای آن را تا رفع مشکل به حالت تعلیق در می آورد.صف پردازش نشده (Unprocessed Queue) : در صورت وجود پیکربندی نادرست در سرور Hangfire، صف های سفارشی Hangfire می توانند پردازش نشده باقی بمانند.این مورد به راحتی از طریق یک تنظیم صحیح قابل اجتناب است.//Incorrect Server Setup var options = new BackgroundJobServerOptions { Queues = new[] { &quotcritical&quot, &quotdefault&quot } }; app.UseHangfireServer(options);این سرور کارها را در یک صف سفارشی به نام"emailSend" پردازش نمی کند. برای رفع آن، "ارسال ایمیل" را در لیست صف قرار دهید.کارهای ناموفق گیر کرده در وضعیت تلاش مجدد: Hangfire کارهای ناموفق را به طور خودکار دوباره امتحان می کند. با این حال، ممکن است مواردی وجود داشته باشد که جاب ها در حالت تلاش مجدد باقی بمانند. دلیل آن می تواند یک استثناء کنترل نشده در کد جاب شما باشد.نکاتی برای اشکال زدایی کارآمد در Hangfireلاگ گذاری: Hangfire از مکانیسم‌های ثبت داخلی مانند log4net، NLog و Serilog پشتیبانی می‌کند. از این موارد به نفع خود برای نظارت جامع استفاده کنید رسیدگی به استثناها: استثناهای کنترل نشده پردازش جاب شما را مختل می کند. در نظر بگیرید که کدهای اجرای کار خود را در بلوک‌هایtry-catch بپیچید تا از پردازش یکنواخت کار اطمینان حاصل کنید.try { BackgroundJob.Enqueue(() => Console.Write(&quotNo Errors Here!&quot)); } catch (Exception ex) { Console.WriteLine($&quotOops, something went wrong: {ex.Message}&quot); }از داشبورد استفاده کنید: داشبورد Hangfire شامل ابزارهای کمکی برای اشکال زدایی و ردیابی پیشرفت Job ، Job های ناموفق و تلاش های مجدد است.از شیوه های کدنویسی خوب استفاده کنید: مانند همیشه، پیروی از شیوه های کدنویسی خوب به جلوگیری از ورود اشکالات به Job شما کمک می کند. داده های ورودی خود را به شدت تأیید کنید و خطاها را پیش بینی کنید.نگهداری و نظارت بر جاب ها درHangfireداشبورد Hangfire مانند یک اتاق کنترل است که به تمام نیازهای شما برای نظارت و اعمال قدرت بر روی Job های خود مجهز است. در اینجا چند نکته برای استفاده موثر از آن وجود دارد:همیشه نمودار Job ها را چک کنید: این نمودار میزان موفقیت و شکست ها، در صورت وجود، ارائه می دهد.صف‌ها را بررسی کنید: اگر به نظر می‌رسد کارها گیر کرده‌اند، وضعیت صف ممکن است اشاره‌ای به شما داشته باشد.مشاغل ناموفق: Hangfire ، Job های شکست خورده را به طور متفاوتی طبقه بندی می کند. برای رفع و از سرگیری آن‌ها، استثناهایی را که در مشاغل «ناموفق» با آن مواجه می‌شوند، بررسی کنید.مقیاس‌بندی با Hangfire – پردازش کار پس‌زمینه توزیع‌شده// Setting up distributed Hangfire servers across different machines services.AddHangfire(configuration => configuration .SetDataCompatibilityLevel(CompatibilityLevel.Version_170) .UseSimpleAssemblyNameTypeSerializer() .UseRecommendedSerializerSettings() .UseSqlServerStorage(Configuration.GetConnectionString(&quotHangfireConnection&quot), new SqlServerStorageOptions { CommandBatchMaxTimeout = TimeSpan.FromMinutes(5), JobExpirationCheckInterval = TimeSpan.FromHours(1), CountersAggregateInterval = TimeSpan.FromMinutes(5), PrepareSchemaIfNecessary = true, QueuePollInterval = TimeSpan.Zero, UseRecommendedIsolationLevel = true, UsePageLocksOnDequeue = true, DisableGlobalLocks = true }));این نمونه ای از نحوه راه اندازی یک سیستم سرورHangfire توزیع شده است . تابع UseSqlServerStorage اتصال به SQL Server را پیکربندی می کند وDisableGlobalLocks قفل های توزیع شده را برای سرورها تسهیل می کند.جنبه های امنیتی استفاده از Hangfireاما امنیت دسترسی به دشبورد Hangfire چطور است؟// Set up strict Dashboard access authorization rules app.UseHangfireDashboard(&quot/hangfire&quot, new DashboardOptions { DashboardTitle = &quotMy Hangfire Dashboard&quot, Authorization = new[] { new HangfireCustomAuthorizeFilter() } }); public class HangfireCustomAuthorizeFilter: IDashboardAuthorizationFilter { public bool Authorize(DashboardContext context) { // Check user authorization here, return true if authorized return HttpContext.Current.User.IsInRole(&quotAdmin&quot); } }این قطعه کد داشبورد Hangfire را پیکربندی می‌کند و دارای یک فیلتر مجوز است. این تضمین می کند که فقط کاربرانی که در نقش "Admin" هستند می توانند به داشبورد دسترسی داشته باشند.پیشرفت ها و برنامه های افزودنی در Hangfireهنگ فایر چیزی بیش از یک ابزار است. این یک زمین بازی برای توسعه دهندگان است. با افزونه های متعددی که در اختیار دارید، می توانید Hangfire را مطابق با نیازهای خاص خود تنظیم کنید. می خواهید ببینید چگونه انجام می شود؟// Logging job events using Hangfire.Console extension BackgroundJob.Enqueued += (sender, args) => { Log.Information($&quotJob {args.JobId} has been enqueued&quot); }; // Sample job using Hangfire.Console BackgroundJob.Enqueue(() => ConsoleJob()); public void ConsoleJob(PerformContext context) { context.WriteLine(&quotHello, Hangfire Console!&quot); }در این مثال، از پسوند Hangfire.Console برای ثبت رویدادهای Job ها به کنسول استفاده کردیم. ConsoleJob در حال ثبت یک پیام تبریک هنگام اجرا است.مشاهده نسخه کامل مقاله در اینجا