項目介紹:
Hangfire:是一個開源的job調度系統,支持分布式JOB!!
Hangfire.HttpJob 是我針對Hangfire開發的一個組件,該組件和Hangfire本身是獨立的。可以獨立更新Hangfire版本不影響!
該組件已被Hangfire官方采納,在Hangfire官網可以查到:
開源地址:
https://github.com/yuzd/Hangfire.HttpJob
該項目目的是:
剝離Job調度和業務
Hangfire.HttpJob究竟是干嘛的
- 傳統使用Hangfire都是把JOb的處理邏輯代碼寫在和Hangfire的同一個工程!
缺點: 這樣就耦合在了一起,如果業務線增大,會導致每個業務線的Job處理邏輯都得和Hangfire耦合在一起!發布的時候所有業務線Job都得暫停調度
- 而使用了Hangfire.HttpJob的話 就是把Hangfire的服務拓展成可以把Job的處理邏輯代碼寫在別的工程里面(以webapi的形式暴露給Hangfire去調度)
優點:這樣就解耦了Hangfire和業務處理邏輯,業務job開發者可以忽略Hangfire的存在!不同的業務線分開不同的JobAgent可以分別部署,發布互不影響
Hangfire.HttpJob
是對Hangfire的一個擴展插件,利用Hangfire.HttpJob可以快速搭建分部署Job調度Server。
特點是:
- 業務與調度完全分離。
- 支持定點執行 延遲執行 周期性循環執行,支持秒級別
- 配合JobAgent組件可以實現Job管理 監控 日志等
共有三篇文章
開源分布式Job系統,調度與業務分離-如何創建一個計划httpjob任務
開源分布式Job系統,調度與業務分離-如何創建周期性的HttpJob任務
開源分布式Job系統,調度與業務分離-HttpJob.Agent組件介紹以及如何使用
本篇教程:HttpJob.Agent組件介紹以及如何使用
HttpJob.Agent是什么?
是一個基於netcore web的一個中間件,專門用於配合Hangfire.HttpJob 開發HttpJob的組件
NUGET地址:Install-Package Hangfire.HttpJob.Agent
幫助快速創建HttpJob並有以下特色
- job的調度和業務完全分離
- 可以在hangfire的后台進行添加變成一個HttpJob
- 支持在hangfire后台手動發送該job 執行命令 和 停止命令
- 支持 長時間運行
如何使用
JobAgent 是作為一個中間件來使用的 DEMO 可以查看 https://github.com/yuzd/Hangfire.HttpJob/tree/master/Test/TestHangfireAgent
JobAgent:一個JobAgent表示一個App 通過netcore web形式部署,一個JobAgent可以宿主多個Job
Job:表示單個Job,用於處理特定的業務邏輯
1.創建一個netcore的web空的工程
安裝nuget包
這里我也用NLOG組件來記錄日志: 所以也安裝下Nlog的包: NLog.Extensions.Logging
新增一個Nlog.config文件,可以參考 https://github.com/yuzd/Hangfire.HttpJob/blob/master/Test/TestHangfireAgent/NLog.Config
配置startup
在appsettings.json里面配置JobAgent的啟動參數
參數說明
字段名稱 | 備注 |
---|---|
Enabled | 代表是否啟用JobAgent |
SitemapUrl | 代表JobAgent的請求地址 默認"/jobagent" |
EnabledBasicAuth | 代表是否開啟basicAuth認證 如果true 需要設置下面2個參數 |
BasicUserName | basicAuth認證的用戶名 |
BasicUserPwd | basicAuth認證的密碼 |
AgentJob 分下面兩種
- 單例的Job ===> 指的是在Agent運行期間只會存在一個實例 如果該實例沒有執行完畢 是不允許再次執行的
- 多例的Job ===> 每次執行都會新生成一個實例
PS:Job類都是注冊在Netcore 的 DI容器里面的,所以可以在job類的構造方法 注入你想要的類,比如Logger組件
開始寫job了
1. 寫一個最簡單的job
新建一個cs 叫 TestJob.cs
讓它繼承 JobAgent 並且重寫 下面3個方法
- OnStart
- OnStop
- OnException
特別說明: OnStart方法在被執行的時候是在一個獨立的線程執行的,所以能夠執行長時間的任務
默認注冊的單例JOB,下面會有多例的舉例
2. 注冊到Hangfire里面去
# 特別要注意的以下幾個參數
1. Url 要填 Agent的注冊地址 “/jobagent”
2. BasicUserName 和 BasicPassword 要填 Agent的配置的basicAuth
3. AgentClass 要填你添加的job類的完整名稱
4. DelayFromMinutes這里我們填-1 代表必須手動執行 如果填0代表是立即執行 如果填>1 代表延遲分鍾數
# 那么對應如下填寫:
{
"JobName": "TestJob", //Job名稱
"Method": "POST", //http請求的方法
"ContentType": "application/json", //http參數類型
"Url": "http://localhost:5002/jobagent", //Agent的注冊地址
"DelayFromMinutes": -1, //-1代表必須手動啟動
"Data": "",
"Timeout": 5000, //http調用超時設置
"BasicUserName": "test", //Agent設置的basicAuth
"BasicPassword": "123456", //Agent設置的basicAuth
"EnableRetry": false,
"SendSucMail": false,
"SendFaiMail": true, //http失敗時發郵件通知
"Mail": "1877682825@qq.com", //http調用失敗通知我
"AgentClass": "TestHangfireAgent.Jobs.TestJob,TestHangfireAgent"
}
添加成功后可以在job列表查到
- 由於我剛剛添加設置的是DelayFromMinutes:-1 所以【隊列】這里顯示【multiple】代表可以多次運行 並且 只能自己點擊按鈕執行
- 由於我們填了AgentClass 這個屬性,所以Hangfire會認為這個是一個AgentJob 在[作業]顯示的名稱里面會有 JobAgent的字樣
如下圖所示:
- 手動觸發試一試
可以填參數 也可以不填參數 這里我們測試就隨便寫
可以看到AgentJob的控制台看到 調用執行成功 參數也傳的沒問題
再回到Hangfire的后台看下調用的日志
注意:由於這個是一個單例的JOB,在Onstart方法里面我們 采用 await Task.Delay(1000 * 10); 延遲了10秒 所以如果你在這10秒內重復執行這個Job 會提示 這個Job正在running 不能重新啟動!等OnStart方法執行完畢后這個job才能被再次調用
2. 創建一個多例的JOB
其實很簡單 就是在類上面加一個[TransientJob]標簽就變成多例了
如下圖所示 我們創建一個測試多例的job:TestTransientJob.cs 然后在它的類上面打上一個[TransientJob]標簽 如下圖所示:
采用和上面一樣的方式注冊到Hangfire里面去! 和上面單例的唯一區別就是 多例的Job 每次都是一個新的實例,不會判斷你上一個實例有沒有執行完.
3. 創建一個可以Hang住OnStart方法的Job
意思就是 Job在執行OnStart方法完成的時候 不去結束這個Job 而是Hang住。 和Console.ReadKey() 類似的感覺!!
等到收到OnStop命令才去終止這個Job。
常見使用場景:消息隊列Client端處理
使用也很簡單 在類上打一個標簽[HangJobUntilStop(true)]即可
20190605追加一個用於JobAgent的記錄log到hangfire 后台 Console 中間件
NUGET 地址: https://www.nuget.org/packages/Hangfire.HttpJob.Agent.MysqlConsole/
也是開源的 開源代碼在:https://github.com/yuzd/Hangfire.HttpJob
這個中間件的目的是能讓JobAgent 寫log到hangfire的Console
如圖:
如何在JobAgent記錄日志而且Hangfire后台能查到呢?
-
首先引用上面的MysqlConsole中間件的NUGET包
-
在application.json里面配置
-
在startUp.cs文件里面注冊
-
在Job類里面使用
注意說明:
如果你不注冊使用MysqlConsole這個中間件的話,
那么默認的: jobContext.Console.WriteLine 方法 等於 _logger.LogInformation(message);