Hangfire 在asp.net core環境的使用

hf被定義爲分佈式後臺服務,更加相似job做業的服務
作做業的插件有quartz.net,JobScheduler 等
固然,都有一些分別和適用的場景。
1.安裝
須要安裝
Hangfire.Core
Hangfire.AspNetCore
Hangfire.SqlServer
關於數據庫存儲工具,能夠根據場景去選擇安裝
例如mysql 的,須要安裝 Hangfire.MySql (mysql不少第三方寫,因此使用時主要使用環境)
Redis放入 Hangfire.Redis
redis是官方做者去更新,因此這些使用能夠直接看官網
2.配置
asp.net core主要是startup配置DI組件。
官網也有說,列舉一下mysql

  // Add Hangfire services.
            services.AddHangfire(configuration => configuration
           .SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
           .UseSimpleAssemblyNameTypeSerializer()
           .UseRecommendedSerializerSettings()
           .UseSqlServerStorage(Configuration.GetConnectionString("default"), new SqlServerStorageOptions
           {
               CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
               SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
               QueuePollInterval = TimeSpan.Zero,
               UseRecommendedIsolationLevel = true,
               UsePageLocksOnDequeue = true,
               DisableGlobalLocks = true
           }));

      services.AddHangfireServer();

關鍵是這個鏈如何配,UseSqlServerStorage專門讀取hangfire會寫入哪一個數據庫,若是用如今的業務數據庫,hangfire的表會寫進去的,也能夠設計分開來存放,例如hangfire的DB,集中去管理。固然通常小的項目,直接跟業務數據庫,集中而獨立的架構。redis

Configure裏面的配置sql

var jobOptions = new BackgroundJobServerOptions
            {
                Queues = new[] { "back", "front", "default" },//隊列名稱,只能爲小寫
                WorkerCount = Environment.ProcessorCount * 5, //併發任務數
                ServerName = "conference hangfire1",//服務器名稱
            };

            app.UseHangfireServer(jobOptions);//啓動Hangfire服務

            app.UseHangfireDashboard();//啓動hangfire面板
            backgroundJobs.Enqueue(() => Console.WriteLine("Hangfire 服務器已啓動"));

            app.UserHangfireAdminService(service); //這個是本身寫的服務擴展

jobOptions若是不配置,會有本身默認的名稱,例如服務器會讀取你當前系統的名稱,隊列那些會讀取對應服務器的程序集名稱。數據庫

3.寫服務api

完成了第一二步,這裏看這個做業如何寫服務器

public static class HangfireAdminService
    {
        private static BackgroundJobServer _server;

        /// <summary>
        /// 使用後臺做業
        /// </summary>
        /// <param name="app"></param>
        /// <param name="service"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public static IApplicationBuilder UserHangfireAdminService(this IApplicationBuilder app,
            IConferenceService service)
        {
            var mcfg = service.MailConfigDefault();
            BackgroundJob.Enqueue(() => Console.WriteLine($"測試單個做業: {DateTime.Now}"));
            RecurringJob.AddOrUpdate(
                () =>
               Console.WriteLine($"測試循環做業: {DateTime.Now}"), Cron.Minutely
            );

            BackgroundJob.Schedule(() => Console.WriteLine($"測試延遲做業: {DateTime.Now}"), TimeSpan.FromMinutes(1));

            return app;
        }
    }

這個是剛纔configure裏面的方法。 能夠寫成一個IApplicationBuilder的擴展方法,加進管道
這樣服務器啓動時,就會啓動裏面的服務。
若是Job做業須要調用一個後臺服務,就不能直接在裏面_service.Log這樣去調用方法了,由於處於不一樣的線程方式。因此job調後臺,能夠這樣操做
舉例,這是個api發郵件的方法架構

/// <summary>
        /// 發送郵件
        /// </summary>
        /// <param name="mail"></param>
        [HttpPost]
        [Route("SendPwd")]
        public MsgResult<bool> SendPwd(MailConfigDto mail)
        {
            MsgResult<bool> result = new MsgResult<bool>(ResultCode.Success);
            UserAccountDto user = null;
            try
            {
                MailConfigDto defaultMail = _service.MailConfigDefault();

                user = _service.UserDtoById(mail.ExtensionId);
                defaultMail.Body = $"用戶註冊成功!登陸名是:{user.UserName},登陸密碼是:{user.Password},註冊類型是:{user.CustomerProfileName}";
                defaultMail.Subject = $"用戶:{user.Name}註冊成功!";
                List<KeyValuePair<string, string>> To = new List<KeyValuePair<string, string>>() {
                    new KeyValuePair<string, string>(user.Name,user.Email)
                };
                defaultMail.To = To;
                SendEmail(defaultMail);
                BackgroundJob.Enqueue<IConferenceService>((s) =>
                 s.LogAdd("註冊成功", $"用戶{user.Name}註冊成功,已發送郵件", OPLog.AdminLogin)
                  );
            }
            catch (Exception ex)
            {
                result = new MsgResult<bool>(ResultCode.Exception, ex.Message);
            }

            return result;

        }

關鍵點, BackgroundJob.Enqueue<IConferenceService>((s) =>s.LogAdd());
Enqueue有個泛型的重載,這裏等因而依賴注入的方式,由於在全局autofac配置過
IConferenceService是指向ConferenceService服務的,因此這裏注入了Enqueue<IConferenceService>接口,只能是接口,纔可讓DI生效。
so, s.LogAdd表明了接口裏面的方法。這樣Enqueue裏面就能夠調用後臺自定義的服務了併發

4.總結,固然還有不少細節沒談,不過這樣基本的配置和使用,已經知足軟件的平常用途了。
補充一點,經常使用的三種方式的特色,
當即執行,完過後會自動銷燬,固然,失敗了按默認的1分鐘後會從新嘗試,直到成功了
延遲執行,這個等於制定了計劃的執行時間,這裏最少時間是按分鐘算,因此這裏不能按用秒甚至毫秒作計算時間的任務。
循環執行,循環執行獨立一個方法 RecurringJob。若是大類分,前2個是一個後臺做業類,這個獨立的類。循環執行某次進程若是失敗了,也不會影響總體的循環效果,只是失敗的進程也會按整體的規則,1分鐘後從新嘗試失敗的進程。app

固然還有其餘的,例如批量處理,延續,批量延續等asp.net

相關文章
相關標籤/搜索