所使用的是 Hangfire 強大排程器有 UI 介面可以使用.
首先安裝 PM> Install-Package Hangfire
安裝這個包含安裝 Hangfire 所有的相關環境了 類似 Hangfire Sql Server Hangfire.Core....
在來是設定 IIS 因為是使用 IIS 站台.
請在你的 IIS 應用程式集區找到您所使用的站台接下來點選 =>
進階設定找到啟動模式 (Start Mode) 改成 AlwaysRunning 模式.
也要把站台的進階設定, 預先載入已啟動, 改為 True 否則 AlwaysRunning 會沒有效果的.
接下來要在程式設定 IIS 站台永遠執行模式 在程式 Create ApplicationPreload.cs
- # 讓 IIS 處在啟動狀態 要從 IIS 設定 PreLoad(預先載用) = true 進階設定 接下來在應用程式集區 進階設定 啟動模式選擇 AlwaysRunning
- # 接下來要到 C:WindowsSystem32inetsrvconfigapplicationHost.config 設定
- # 查看 applicationPools 的 startMode 是否為 AlwaysRunning
- <site name = "testsite" id="2" serverAutoStart="true">
- <application path = "/" applicationPool="testsite" preloadEnabled="true" serviceAutoStartProvider="ApplicationPreload">
- <virtualDirectory path = "/" physicalPath="D:testsite" />
- </application>
- <binding protocol = "http" bindingInformation="*:5:" /></bindings>
- </site>
- # 接下來複製貼上以下文字 在 system.applicationHost 內 sites 範圍外面
- <!-- Just AFTER closing the `sites` element AND AFTER `webLimits` tag -->
- <serviceAutoStartProviders>
- <add name = "ApplicationPreload" type="ExampleService.AgentService.ApplicationPreload, ExampleService.AgentService" />
- <serviceAutoStartProviders>
In ApplicationPreload.cs
- public class ApplicationPreload : System.Web.Hosting.IProcessHostPreloadClient
- {
- public void Preload(string[] parameters)
- {
- Startup.Instance.Start();
- }
- }
在 global.asax.cs 裡啟動 Hangfire
- public class Global : HttpApplication
- {
- protected void Application_Start(object sender, EventArgs e)
- {
- Startup.Instance.Start();
- }
- protected void Application_End(object sender, EventArgs e)
- {
- Startup.Instance.Stop();
- }
- }
需建立完全同名 Startup.cs 因 Hangfire 會先到這取得 Configuration 資訊 使用 Owin 環境設定
- [assembly: OwinStartup(typeof(AgentService.Startup))]
- namespace AgentService
- {
- public class Startup : IRegisteredObject
- {
- public static readonly Startup Instance = new Startup();
- private readonly object _lockObject = new object();
- private bool _started;
- private BackgroundJobServer _backgroundJobServer;
- /// <summary>
- /// 一開始所要執行的 初始化 Hangfire
- /// 會先尋找資料庫是否有被初始化再來則是這邊 如果一開始不先初始化資料庫直接 啟動 UseHangfireServer 會產生
- /// 錯誤
- /// </summary>
- /// <param name="app"></param>
- public void Configuration(IAppBuilder App)
- {
- // 啟用 Hangfire 的 Dashboard
- // 預設 Dashboard 路徑為 http://localhost:xxxx/hangfire
- // 使用 Dashboard, 可以設定顯示 dashboard 的 path http://localhost:xxxx/HangfireDashboard
- // 在這設定能進入 Dashboard 得權限
- App.UseHangfireDashboard("/HangfireDashboard", new DashboardOptions
- {
- Authorization = new[] { new HangfireDashBoardAuthorizationFilter() },
- });
- // 執行所需的 排程
- StartMyTask();
- }
- }
Cron 的時間設定說明
Cron 時間計算
Cron 詳細解說 https://en.wikipedia.org/wiki/Cron
- /// <summary>
- /// 執行的 Method 參數最好是字串, 如果是物件的話, 不要是 nested 物件, 這樣會 Parse 不出來, 然後報錯哦!
- /// 使用 Hangfire 去執行的話, nested obj 會 parse 不出來, 所以用字串傳遞
- /// </summary>
- private void StartMyTask()
- {
- // 設定每天的幾十幾分運作
- //Cron.Daily(07,30)
- // 同上
- // 分鐘 小時 日期 月份 週
- //30 07 * * *
- // 代表這個域上包含所有合法的值
- // 以下方做為表示是說每天 07:30 AM 執行此排程
- string cronExp = "30 07 * * *";
- // 設定注意 這就是所謂的固定時間去做排程定時
- // 第一參數為 RecurringJobId
- // 第二為 你要所使用的 call method
- // 第三 就是你要這排程何時運作
- // 第四 很重要!! 他會依你的排程時間下去實作但你需要將此時間設定為 Local 否則預設是 UTC 你會不知道何時運作
- RecurringJob.AddOrUpdate("test", () => AgentService.SetDEMOamount(), cronExp,Ti meZoneInfo. Local);
- // 這是需要在長時間 背景執行的工作就可以設定這個
BackgroundJob. 大专栏 使用 Hangfire MVC 做排程 > Enqueue(() => AgentService.SetDEMOamount());
- //BackgroundJob.Schedule() 將目前的任務延後執行, 在送入背景等待時就已經執行完畢, 而不是 3 秒後才被執行.
- BackgroundJob.Schedule(() => AgentService.SetDEMOamount()),TimeSpan.FromSeconds(3));
- // 使用下列方法 他會馬上執行此排程但不會紀錄這次的使用
- RecurringJob.Trigger("test");
- }
- /// <summary>
- /// 一開始從 Global.aspx 會啟動這邊 直接開啟 Hangfire 與 JobStorage 資料庫連接
- /// </summary>
- public void Start()
- {
- lock (_lockObject)
- {
- if (_started) return;
- _started = true;
- HostingEnvironment.RegisterObject(this);
- JobStorage.Current = new SqlServerStorage(ConnectionString);
- GlobalConfiguration.Configuration.UseSqlServerStorage(ConnectionString);
- // 建立 Background JobSserver 來處理 Job
- // 啟用 HanfireServer
- // reduce the heartbeat of the Hangfire dashboard. It is taking too much of our CPU usag e.It is in our production also
- _backgroundJobServer = new BackgroundJobServer(new BackgroundJobServerOptions
- {
- // 要處理的陣列列表
- Queues = new[] { "test" },
- // 巡迴訪問時間越長 將會很耗 CPU 的效能
- // 預設 30 秒 6 分鐘為 使用 TransactionScope 限制時間
- HeartbeatInterval = new TimeSpan(0, 6, 0),
- ServerCheckInterval = new TimeSpan(0, 6, 0),
- // 預設詢問 Job 是 15 秒, 也可以依狀況來調整, 如下我使用 6 分鐘
- SchedulePollingInterval = new TimeSpan(0, 6, 0),
- // 服務名稱
- ServerName = "FundaySaleshangfireahent",
- // 設定 Hangfire 同一時間, 可以處理多少的 Job 現在是 20
- // 預設是 處理器數目 * 5
- WorkerCount = Environment.ProcessorCount * 5,
- });
- }
- }
- /// <summary>
- /// 程序停止
- /// </summary>
- public void Stop()
- {
- lock (_lockObject)
- {
- if (_backgroundJobServer != null)
- {
- _backgroundJobServer.Dispose();
- }
- HostingEnvironment.UnregisterObject(this);
- }
- }
- void IRegisteredObject.Stop(bool immediate)
- {
- Stop();
- }
- }
排程權限設定
- /// <summary>
- /// 取得能進入 Hangfire Dashboard 的人員 只有管理者權限才能進入
- /// </summary>
- public class HangfireDashBoardAuthorizationFilter : IDashboardAuthorizationFilter
- {
- public bool Authorize([NotNull]DashboardContext context)
- {
- if (context == null) throw new ArgumentNullException(nameof(context));
- var owinContext = new Microsoft.Owin.OwinContext(context.GetOwinEnvironment());
- if (owinContext.Authentication.User.Identity.IsAuthenticated)
- {
- return true;
- }
- return false;
- }
- }
參考資源
- hangfire install
- IIS Application Initialization
- Settings IIS AlwaysRunning
Cron 時間計算
Cron 詳細解說 https://en.wikipedia.org/wiki/Cron
- HangfireIO Owin https://github.com/HangfireIO/Hangfire/issues/613
- HangfireIO using-dashboard
- Hangfire-aspnet-mvc-webapi
- Hangfire Configuring
- Hangfire Performing
来源: http://www.bubuko.com/infodetail-3327484.html