ABP VNext + Quartz.NET vs Hangfire:靈活調度與任務管理

ABP VNext + Quartz.NET vs Hangfire:靈活調度與任務管理 🚀


📚 目錄

  • ABP VNext + Quartz.NET vs Hangfire:靈活調度與任務管理 🚀
    • ? TL;DR
    • 🛠 環境與依賴
    • 🔧 Quartz.NET 在 ABP 中接入
      • 1. 安裝與模塊依賴
      • 2. 集中配置持久化、序列化與集群
      • 3. 服務注冊、作業定義與重試策略
      • 4. 業務層動態調度 🔄
    • 🔧 Hangfire 在 ABP 中接入
      • 1. 安裝與模塊依賴
      • 2. 作業定義與觸發 🎯
    • 🔒 高可用與集群部署對比
    • ? 性能與可視化對比
    • 💡 最佳實踐


? TL;DR

  • 通過 ABP VNext 的配置管道,使用 PreConfigure<AbpQuartzOptions>Configure<AbpHangfireOptions>,實現對 Quartz.NET 與 Hangfire 的零侵入集成
  • 對比兩者在持久化存儲集群模式作業定義可視化監控等方面的核心差異
  • 多實例高可用場景下的選型建議落地最佳實踐

背景與動機
在微服務架構中,定時與異步任務無處不在。ABP 自帶的 Background Job 模塊適合中小規模場景;但當你需要精細調度策略多節點容錯可視化監控時,Quartz.NET 與 Hangfire 是首選方案。本文結合 ABP VNext 最佳實踐,系統對比二者接入方式、集群部署與運維復雜度,助你快速選型并落地。


🛠 環境與依賴

  • 平臺版本:.NET 7/8 + ABP VNext 7.x/8.x

  • 核心 NuGet 包

    abp add-package Volo.Abp.BackgroundJobs.Quartz
    abp add-package Volo.Abp.BackgroundJobs.HangFire
    
  • 持久化存儲:SQL Server / Redis(可選)


🔧 Quartz.NET 在 ABP 中接入

1. 安裝與模塊依賴

abp add-package Volo.Abp.BackgroundJobs.Quartz
[DependsOn(typeof(AbpBackgroundJobsQuartzModule))]
public class MyAppQuartzModule : AbpModule
{// ...
}

2. 集中配置持久化、序列化與集群

public override void PreConfigureServices(ServiceConfigurationContext context)
{var configuration = context.Services.GetConfiguration();var appName       = configuration["App:Name"] ?? "MyApp";PreConfigure<AbpQuartzOptions>(options =>{options.Properties = new NameValueCollection{// 調度器實例名與自動生成實例ID,保證同庫多應用/多節點隔離["quartz.scheduler.instanceName"] = appName,["quartz.scheduler.instanceId"]   = "AUTO",      // ADO.NET JobStore 與表前綴["quartz.jobStore.type"]          = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz",["quartz.jobStore.tablePrefix"]   = "QRTZ_",["quartz.jobStore.dataSource"]    = "default",// 數據源配置["quartz.dataSource.default.provider"]       = "SqlServer",["quartz.dataSource.default.connectionString"] = configuration.GetConnectionString("Default")!,// JSON 序列化["quartz.serializer.type"]                  = "json",// SQL Server 驅動委派["quartz.jobStore.driverDelegateType"]      = "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz",// 集群模式開關["quartz.jobStore.clustered"]               = "true",   // 配置集群模式// 心跳檢查間隔與錯過觸發容忍閾值(單位:毫秒)["quartz.jobStore.clusterCheckinInterval"]  = "20000",["quartz.jobStore.misfireThreshold"]        = "60000"};});
}

說明:在集群模式下,quartz.jobStore.clustered=true 用于開啟數據庫鎖與心跳機制;quartz.scheduler.instanceId=AUTO 確保每個節點擁有唯一 ID。

3. 服務注冊、作業定義與重試策略

public override void ConfigureServices(ServiceConfigurationContext context)
{// 注入作業實現context.Services.AddTransient<SampleJob>();// 注冊 Quartz 并調度作業context.Services.AddQuartz(q =>{q.UseMicrosoftDependencyInjectionJobFactory();q.ScheduleJob<SampleJob>(trigger => trigger.WithIdentity("SampleJobTrigger").StartNow().WithCronSchedule("0/5 * * * * ?")); // 每 5 秒執行一次});// 托管服務:在停止時等待作業完成context.Services.AddQuartzHostedService(opt => opt.WaitForJobsToComplete = true);// 全局重試策略(單位:毫秒)Configure<AbpBackgroundJobQuartzOptions>(opts =>{opts.RetryCount               = 3;opts.RetryIntervalMillisecond = (int)TimeSpan.FromSeconds(10).TotalMilliseconds;});
}
public class SampleJob : IJob, ITransientDependency
{public Task Execute(IJobExecutionContext context){Console.WriteLine($"[Quartz] Executed at {DateTime.Now:O}");return Task.CompletedTask;}
}

4. 業務層動態調度 🔄

public class ScheduleService : ITransientDependency
{private readonly IQuartzScheduleJobManager _jobManager;public ScheduleService(IQuartzScheduleJobManager jobManager) =>_jobManager = jobManager;public async Task ScheduleSampleJobAsync(){await _jobManager.ScheduleAsync<SampleJob>(job => job.WithIdentity("DynamicSampleJob").WithDescription("由業務層動態調度"),trigger => trigger.StartNow().WithSimpleSchedule(x => x.WithIntervalInSeconds(15).RepeatForever()));}
}

優化提示:也可使用 AbpQuartzOptions.Configurator API 進行鏈式配置,避免手動拼寫屬性名,語義更清晰。


🔧 Hangfire 在 ABP 中接入

1. 安裝與模塊依賴

abp add-package Volo.Abp.BackgroundJobs.HangFire
[DependsOn(typeof(AbpBackgroundJobsHangfireModule))]
public class MyAppHangfireModule : AbpModule
{public override void ConfigureServices(ServiceConfigurationContext context){var configuration = context.Services.GetConfiguration();// 持久化存儲context.Services.AddHangfire(cfg =>cfg.UseSqlServerStorage(configuration.GetConnectionString("Default")));// 服務器選項:并發工作數與隊列Configure<AbpHangfireOptions>(options =>{options.ServerOptions = new BackgroundJobServerOptions{WorkerCount = 20,Queues      = new[] { "default" }};});}public override void OnApplicationInitialization(ApplicationInitializationContext context){var app = context.GetApplicationBuilder();// 掛載 Dashboard 并使用 ABP 授權過濾app.UseAbpHangfireDashboard("/hangfire", opts =>{opts.AsyncAuthorization = new[]{new AbpHangfireAuthorizationFilter("Hangfire.View")};});  // 建議使用 ABP 授權過濾app.UseConfiguredEndpoints();// 周期任務示例var recurringManager = context.ServiceProvider.GetRequiredService<IRecurringJobManager>();recurringManager.AddOrUpdate("HelloJobRecurring",Job.FromExpression<HelloJob>(job => job.ExecuteAsync(new HelloJobArgs { Name = "ABP" })),Cron.Minutely);}
}

2. 作業定義與觸發 🎯

public class HelloJobArgs { public string Name { get; set; } }public class HelloJob : AsyncBackgroundJob<HelloJobArgs>, ITransientDependency
{public override Task ExecuteAsync(HelloJobArgs args){Console.WriteLine($"[Hangfire] Hello, {args.Name}, at {DateTime.Now:O}");return Task.CompletedTask;}
}public class SomeService : ITransientDependency
{private readonly IBackgroundJobManager _jobManager;public SomeService(IBackgroundJobManager jobManager) => _jobManager = jobManager;public Task RunAsync() =>_jobManager.EnqueueAsync<HelloJob, HelloJobArgs>(new HelloJobArgs { Name = "World" });
}

🔒 高可用與集群部署對比

Hangfire Cluster
Dequeue/Execute
Dequeue/Execute
Hangfire Storage DB
Client Enqueue
Server 1
Server 2
Quartz.NET Cluster
Poll & Lock
Poll & Lock
Grant & Trigger
Scheduler Node 1
Quartz JobStore DB
Scheduler Node 2

說明:Quartz 通過輪詢 + 鎖競爭實現集群;Hangfire 則由客戶端入隊,任意 Server 拉取執行。

特性Quartz.NETHangfire
集群模式quartz.jobStore.clustered=true + clusterCheckinInterval + misfireThreshold,DB 鎖與心跳協調執行多服務器共享存儲,GUID 生成唯一 ServerId,無需額外配置
故障切換鎖超時后其他節點接管;錯過觸發由 misfireThreshold 控制重調度延遲心跳停止后,未完成任務按 InvisibilityTimeout 重新入隊并重試
持久化存儲支持ADO.NET(SQL/Oracle/PostgreSQL)、MongoDB、Redis 等SQL Server、Redis、MongoDB 等;多種官方 & 社區擴展
可視化管理第三方 Dashboard:SilkierQuartz、QuartzDesk 等內置 Dashboard + ABP 授權過濾,支持失敗重試與隊列監控

? 性能與可視化對比

  • 啟動延遲:Quartz 需初始化 Scheduler 與 JobStore,冷啟動略慢;Hangfire 支持延遲加載 Server,啟動體驗更快。

  • 吞吐能力:視硬件、網絡與存儲配置而定,建議使用 Benchmark.NET 進行真實測量

  • Dashboard 功能

    • Quartz + SilkierQuartz:需額外部署,支持作業歷史與觸發器管理;
    • Hangfire:開箱即用,支持自定義隊列、重試策略與并發監控。

💡 最佳實踐

  1. 零侵入抽象:業務層僅依賴 AsyncBackgroundJob<TArgs>IBackgroundJobManager/IQuartzScheduleJobManager,可測試性與可切換性俱佳。

  2. 集中配置管道:通過 PreConfigure<AbpQuartzOptions>Configure<AbpHangfireOptions> 統一管理持久化、集群、隊列與重試策略。

  3. 依賴注入:作業類型實現 ITransientDependency 即可自動注冊;Quartz 場景下如需顯式注冊,可 AddTransient<SampleJob>()

  4. 安全與監控

    • Quartz:結合 Prometheus Exporter 與 SilkierQuartz 構建可觀測平臺;
    • Hangfire:使用 ABP 授權過濾(AbpHangfireAuthorizationFilter)保護 Dashboard。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/94166.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/94166.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/94166.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[硬件電路-148]:數字電路 - 什么是CMOS電平、TTL電平?還有哪些其他電平標準?發展歷史?

1. CMOS電平定義&#xff1a; CMOS&#xff08;Complementary Metal-Oxide-Semiconductor&#xff09;電平基于互補金屬氧化物半導體工藝&#xff0c;由PMOS和NMOS晶體管組成。其核心特點是低功耗、高抗干擾性和寬電源電壓范圍&#xff08;通常為3V~18V&#xff09;。關鍵參數&…

0基礎網站開發技術教學(二) --(前端篇 2)--

書接上回說到的前端3種主語言以及其用法&#xff0c;這期我們再來探討一下javascript的一些編碼技術。 一) 自定義函數 假如你要使用一個功能&#xff0c;正常來說直接敲出來便可。可如果這個功能你要用不止一次呢?難道你每次都敲出來嗎?這個時侯&#xff0c;就要用到我們的自…

前端 拼多多4399筆試題目

拼多多 3 選擇題 opacity|visibity|display區別 在CSS中&#xff0c;opacity: 0 和 visibility: hidden 都可以讓元素不可見&#xff0c;但它們的行為不同&#xff1a; ? opacity: 0&#xff08;透明度為0&#xff09; 元素仍然占據空間&#xff08;不移除文檔流&#xff0…

數琨創享:全球汽車高端制造企業 QMS質量管理平臺案例

01.行業領軍者的質量升級使命在全球汽車產業鏈加速升級的浪潮中&#xff0c;質量管控能力已成為企業核心競爭力的關鍵。作為工信部認證的制造業單項冠軍示范企業&#xff0c;萬向集團始終以“全球制造、全球市場、做行業領跑者”為戰略愿景。面對奔馳、寶馬、大眾等“9N”高端客…

GaussDB 約束的使用舉例

1 not null 約束not null 約束強制列不接受 null 值。not null 約束強制字段始終包含值。這意味著&#xff0c;如果不向字段添加值&#xff0c;就無法插入新記錄或者更新記錄。GaussDB使用pg_get_tabledef()函數獲取customers表結構&#xff0c;如&#xff1a;csdn> set sea…

自動駕駛中的傳感器技術13——Camera(4)

1、自駕Camera開發的方案是否歸一化對于OEM&#xff0c;或者自駕方案商如Mobileye如果進行Camera的開發&#xff0c;一般建議采用Tesla的系統化最優方案&#xff0c;所有Camera統一某個或者某兩個MP設計&#xff08;增加CIS議價權&#xff0c;減少Camera PCBA的設計維護數量&am…

開源利器:glTF Compressor——高效優化3D模型的終極工具

在3D圖形開發領域,glTF(GL Transmission Format)已成為Web和移動端3D內容的通用標準。然而,3D模型的文件體積和紋理質量往往面臨權衡難題。Shopify最新開源的glTF Compressor工具,為開發者提供了一套精細化、自動化的解決方案,讓3D模型優化既高效又精準。本文將深入解析這…

LeetCode Hot 100,快速學習,不斷更

工作做多了有時候需要回歸本心&#xff0c;認真刷題記憶一下算法。那就用我這練習時長兩年半的代碼農民工來嘗試著快速解析LeetCode 100吧 快速解析 哈希 1. 兩數之和 - 力扣&#xff08;LeetCode&#xff09; 這題很簡單啊&#xff0c;思路也很多 1. 暴力搜索&#xff0c;…

MySQL的子查詢:

目錄 子查詢的相關概念&#xff1a; 子查詢的分類&#xff1a; 角度1&#xff1a; 單行子查詢&#xff1a; 單行比較操作符&#xff1a; 子查詢的空值情況&#xff1a; 多行子查詢&#xff1a; 多行比較操作符&#xff1a; ANY和ALL的區別&#xff1a; 子查詢為空值的…

Python批處理深度解析:構建高效大規模數據處理系統

引言&#xff1a;批處理的現代價值在大數據時代&#xff0c;批處理&#xff08;Batch Processing&#xff09; 作為數據處理的核心范式&#xff0c;正經歷著復興。盡管實時流處理備受關注&#xff0c;但批處理在數據倉庫構建、歷史數據分析、報表生成等場景中仍不可替代。Pytho…

是德科技的BenchVue和納米軟件的ATECLOUD有哪些區別?

是德科技的BenchVue和納米軟件的ATECLOUD雖然都是針對儀器儀表測試的軟件&#xff0c;但是在功能設計、測試場景、技術架構等方面有著明顯的差異。BenchVue&#xff08;是德科技&#xff09;由全球領先的測試測量設備供應商開發&#xff0c;專注于高端儀器控制與數據分析&#…

線上redis的使用

一.String1.緩存玩家單個數據&#xff0c;但是我覺得還是用hash好2.結合過期時間&#xff0c;比如:某個東西結算了&#xff0c;redis記錄一下&#xff0c;并設置過期時間3.分布式鎖二.Hash1.緩存一個單位的數據&#xff0c;比如&#xff1a;聯盟信息2.被封禁的列表&#xff0c;…

【實踐記錄】github倉庫的更新

首先登錄&#xff0c;參考&#xff1a;記一次github連接本地git_如何連接github-CSDN博客 SSH&#xff1a; git config --global user.name "GitHubUsername" git config --global user.email "emailexample.com" ssh-keygen -t ed25519 -C "emailex…

Nature圖形復現—Graphpad繪制帶P值的含數據點的小提琴圖

帶 P 值的含數據點的小提琴圖是一種科研數據可視化圖表&#xff0c;它同時呈現數據的分布特征、原始觀測值和統計顯著性&#xff1a;通過小提琴形狀展示概率密度分布&#xff08;反映數據集中趨勢和離散程度&#xff09;&#xff0c;疊加抖動散點顯示所有原始數據點&#xff08…

mongodb源代碼分析createCollection命令由create.idl變成create_gen.cpp過程

mongodb命令db.createCollection(name, options)創建一個新集合。由于 MongoDB 在命令中首次引用集合時會隱式創建集合&#xff0c;因此此方法主要用于創建使用特定選項的新集合。例如&#xff0c;您使用db.createCollection()創建&#xff1a;固定大小集合&#xff1b;集群化集…

達夢(DM8)常用管理SQL命令(3)

達夢(DM8)常用管理SQL命令(3) 1.表空間 -- 查看表空間信息 SQL> SELECT * FROM v$tablespace;-- 查看數據文件 SQL> SELECT * FROM v$datafile;-- 表空間使用情況 SQL> SELECT df.tablespace_name "表空間名稱",df.bytes/1024/1024 "總大小(MB)&q…

【Django】-5- ORM的其他用法

一、&#x1f680; ORM 新增數據魔法&#xff01;核心目標教你用 Django ORM 給數據庫 新增數據 &#xff01;就像給數據庫 “生小數據寶寶”&#x1f476;方法 1&#xff1a;實例化 Model save&#xff08;一步步喂數據&#xff09;obj Feedback() # 實例化 obj.quality d…

Flink Checkpoint機制:大數據流處理的堅固護盾

引言在大數據技術蓬勃發展的當下&#xff0c;數據處理框架層出不窮&#xff0c;Flink 憑借其卓越的流批一體化處理能力&#xff0c;在大數據流處理領域占據了舉足輕重的地位 。它以高吞吐量、低延遲和精準的一次性語義等特性&#xff0c;成為眾多企業處理實時數據的首選工具。在…

【STM32-HAL】 SPI通信與Flash數據寫入實戰

文章目錄1.參考教程2. 4種時間模式3. 3個編程接口3.1 HAL_StatusTypeDef HAL_SPI_Transmit(...) &#xff1a;3.1.1 參數說明3.1.2 例子3.2 HAL_StatusTypeDef HAL_SPI_Receive(...) &#xff1a;3.2.1參數說明3.2.2 例子3.3 HAL_StatusTypeDef HAL_SPI_TransmitReceive(...) &…

SNR-Aware Low-light Image Enhancement 論文閱讀

信噪比感知的低光照圖像增強 摘要 本文提出了一種新的低光照圖像增強解決方案&#xff0c;通過聯合利用信噪比&#xff08;SNR&#xff09;感知的變換器&#xff08;transformer&#xff09;和卷積模型&#xff0c;以空間變化的操作方式動態增強像素。對于極低信噪比&#xff0…