揭秘hangfire實現機制「1」:hangfire工作原理概述

2020-12-11 dotnet小猿

hangfire是一款開源的,可擴展的,不需要基於Windows 服務及Windows 調度任務的,易於上手的,且自帶Dashboard的分布式後臺作業調度框架,本系列文章將基於hangfire[1.7.10]源碼揭秘hangfire的實現機制。

系列目錄

[1]:hangfire工作原理概述

[2]:hangfire的狀態管理

[3]:hangfire中的設計模式

[4]:hangfire總結

可視化監控

儀錶盤

Hangfire Dashboard

隊列

Hangfire Queues

作業詳情

Hangfire Job Detail

hangifre工作原理概述

本文將從以下四個方面講述hangfire的工作原理

目錄

一、幾個基本概念

二、hangfire簡單使用

三、主要對象介紹

四、hangfire如何工作

一、幾個基本概念

伺服器實例[Server]hangfire伺服器實例是hangfire的核心,啟動伺服器實例後臺作業將在他的統一調度下開始運作。

hangfire伺服器實例由執行不同工作的不同組件組成:[worker]偵聽隊列和處理作業,重複的調度程序[recurring scheduler]使重複的作業排隊,調度輪詢器使延遲的作業排隊[delayedJob scheduler],到期管理器刪除過時的作業並保持存儲儘可能乾淨等。

[原文]

Hangfire Server consist of different components that are doing different work: workers listen to queue and process jobs, recurring scheduler enqueues recurring jobs, schedule poller enqueues delayed jobs, expire manager removes obsolete jobs and keeps the storage as clean as possible, etc.

所以啟動一個hangfire的伺服器實例只需要一句代碼後臺調度即開始運行:

varserver=newBackgroundJobServer();// Wait for graceful server shutdown.server.Dispose();

隊列[Queue]隊列是作業的載體,作業經過後臺調度後進入到隊列中,排入到隊列的作業將被[worker]執行並消費。我們可以通過配置設置不同的伺服器實例處理不同的隊列如varoptions=newBackgroundJobServerOptions{Queues=new[]{"alpha","beta","default"}}; (newBackgroundJobServer(options)){/* ... */}

作業[Job]作業是實際要執行的後臺任務實際表現為一個方法,它可以被標記為指定的隊列,如:[Queue("alpha")]publicvoidSomeMethod(){}BackgroundJob.Enqueue(()=>SomeMethod());

二、hangfire簡單使用

在dotnet core web項目中啟用hangfire其實就兩句代碼,第一步注入hangfire,第二部使用hangfire

注入public void ConfigureServices(IServiceCollection services) { services.AddHangfire(); }啟用public void Configure(IApplicationBuilder app, IHostingEnvironment env){app.UseHangfireServer();app.UseHangfireDashboard(); }添加作業等待調度一次性作業[Fire-and-forget jobs] var jobId = BackgroundJob.Enqueue( () => Console.WriteLine("Fire-and-forget!"));

周期性作業[Recurring jobs]基於CRON 表達式進行周期性調度

RecurringJob.AddOrUpdate( () => Console.WriteLine("Recurring!"), Cron.Daily);

延遲調度作業[Delayed jobs]只執行一次但不是立即執行,需延遲一段時間執行

var jobId = BackgroundJob.Schedule( () => Console.WriteLine("Delayed!"), TimeSpan.FromDays(7));

三、主要對象介紹

BackgroundJobServer伺服器實例,前面已經介紹過了。

BackgroundProcessingServer立即在後臺線程中啟動進程。負責發布/刪除綁定到存儲的伺服器。用無限循環包裝所有進程並自動重試。在單個上下文中執行所有進程。在處理方法中使用超時,等待所有組件,取消信號關閉包含一些必需的進程並使用存儲進程。生成唯一的ID。屬性仍然很差。[原文]

Immediately starts the processes in a background thread. Responsible for announcing/removing a server, bound to a storage. Wraps all the processes with a infinite loop and automatic retry. Executes all the processes in a single context. Uses timeout in dispose method, waits for all the components, cancel signals shutdown Contains some required processes and uses storage processes. Generates unique id. Properties are still bad.

BackgroundServerProcess服務主進程,通過該進程在啟動各種後臺進程如worker對應的後臺工作進程,DelayedJobScheduler、RecurringJobScheduler對應的後臺輪詢進程以及一些框架必須的服務監聽進程,心跳進程及作業監聽進程等。

BackgroundDispatcher後臺線程調度者也是後臺線程的實際創建者,職責是創建後臺線程把並對線程進行管理

以下是三類後臺線程[IBackgroundProcess]Worker根據配置的線程數創建1個或多個後臺線程DelayedJobScheduler創建1個後臺線程用於輪詢RecurringJobScheduler創建1個後臺線程用於輪詢

四、hangfire如何工作

ER圖

從前面的介紹我們指定啟用hangfire實際只需要兩句代碼即:

HangfireApplicationBuilderExtensions.AddHangfire該步驟實際進行各種注入包括注入全局配置GlobalConfiguration、JobStorage、JobActivator等HangfireApplicationBuilderExtensions.UseHangfireServer或者通過HostedService方式啟動:AddHangfireServer無論哪種方式其實核心就幹了一件事情,創建一個hangfire服務實例:varserver=newBackgroundJobServer();// Wait for graceful server shutdown.server.Dispose();接下來我們看構造函數中做了什麼?

public BackgroundJobServer( [NotNull] BackgroundJobServerOptions options, [NotNull] JobStorage storage, [NotNull] IEnumerable<IBackgroundProcess> additionalProcesses, [CanBeNull] IJobFilterProvider filterProvider, [CanBeNull] JobActivator activator, [CanBeNull] IBackgroundJobFactory factory, [CanBeNull] IBackgroundJobPerformer performer, [CanBeNull] IBackgroundJobStateChanger stateChanger) {

....

var processes = new List<IBackgroundProcessDispatcherBuilder>(); processes.AddRange(GetRequiredProcesses(filterProvider, activator, factory, performer, stateChanger)); [注釋1] processes.AddRange(additionalProcesses.Select(x => x.UseBackgroundPool(1)));

....

_processingServer = newBackgroundProcessingServer( storage, processes,properties, GetProcessingServerOptions()); [注釋2]

[注釋1]

將必須的IBackgroundProcessDispatcherBuilder加入到集合,這些必須的後臺進程調度對象就包括(Worker、DelayedJobScheduler、RecurringJobScheduler 生成的IBackgroundProcessDispatcherBuilder[調用擴展方法UseBackgroundPool])

[注釋2]

實例化服務主進程對象

接下來看BackgroundProcessingServer構造函數代碼

internal BackgroundProcessingServer(

[NotNull] BackgroundServerProcess process,

[NotNull] BackgroundProcessingServerOptions options) {

....

_dispatcher = CreateDispatcher();[注釋3]

....

}

private IBackgroundDispatcher CreateDispatcher() {

....

return new BackgroundDispatcher(

execution,

RunServer,

execution,

ThreadFactory);

}

private void RunServer(Guid executionId, object state)

{

....

_process.Execute(executionId, (BackgroundExecution)state, _stoppingCts.Token, _stoppedCts.Token, _shutdownCts.Token);

}

[注釋3]

創建調度對象,我們知道_process是BackgroundServerProces所以意思就是創建一個進程調用BackgroundServerProces的Execute方法,接著看執行方法做了什麼:

public void Execute(Guid executionId, BackgroundExecution execution, CancellationToken stoppingToken, CancellationToken stoppedToken, CancellationToken shutdownToken) {

....

StartDispatchers(context, dispatchers);

....

private void StartDispatchers(BackgroundServerContext context, ICollection<IBackgroundDispatcher> dispatchers){

....

foreach (var dispatcherBuilder in _dispatcherBuilders) { dispatchers.Add(dispatcherBuilder.Create(context, _options));[注釋4]

}

....

}

[注釋4]

調用BackgroundProcessDispatcherBuilder的Create方法創建調度:

public IBackgroundDispatcher Create(BackgroundServerContext context, BackgroundProcessingServerOptions options) {

....

return new BackgroundDispatcher(

execution,

ExecuteProcess,

Tuple.Create(_process, context, execution),

_threadFactory);

}

private static void ExecuteProcess(Guid executionId, object state)

{

var tuple = (Tuple<IBackgroundProcess, BackgroundServerContext, BackgroundExecution>)state;

....

while (!context.IsStopping)

{

tuple.Item1.Execute(context);[注釋5]

tuple.Item3.NotifySucceeded();

}

}

[注釋5]

可以看出每一種類型的後臺調度後在執行之個while循環即不停執行具體的IBackgroundProcess如work、DelayedJobScheduler、RecurringJobScheduler中的任務。

至此基本運行機制就清楚了。

相關焦點

  • 您知道hang fire是什麼意思嗎?
    說到hang這個單詞,我們都知道的意思是懸掛、吊。但是,說到與hang有關的習語的時候,就只有一小部分人能知道是什麼意思。今天,我們就一起看一下與hang有關的習語。1、get the hang of sth 掌握…的要領、了解…的用法、找到了訣竅It's not difficult once you get the hang of it.你掌握了要領就不難了。這句話中的hang是一個名詞。
  • play with fire是玩火嗎?是,ball of fire是火球嗎?不是!
    今天我們就來學習一些和fire有關的表達1、ball of fire有ball,有fire,難道ball of fire是「火球」?不,ball of fire通常是指「才智、精力過人的人」,即「an ambitious and enthusiastic person」。
  • Catch fire是「抓住火」?關於火的習語趕緊學起來!
    catch是「抓住」,fire是「火」,catch fire難道是「抓住火」?「catch fire」當然不是「抓住火」,它主要有兩個意思:1.著火;起火;開始燃燒I told you, it doesn't catch fire.
  • catch fire是什麼意思?反正不是你想認為的意思!
    catch是「抓住」,fire是「火」,可catch fire可不是「抓住火」,真正的意思其實是..
  • 英語hang out 和 hang about 的區別
    英語中,hang out 和 hang about 都有「閒逛」的意思,但它們的用法有一定的區別,今天我們一起來學習一下。1. hang out:這個詞組強調「出去無目的的逛」,不側重指在哪裡逛,只強調出去。
  • You're fire不是你被開除了!on fire也不是著火了!
    我們今天學了fire這個地道用法就要把它用起來~fire表示的是一鳴驚人的意思英語老司機鍾叔視頻親授顛覆性教學實現無死角英文蛻變長按識別下圖二維碼「即可獲得免費聽課名額」巧用公式帶你輕鬆實現英語進階👇高效記憶單詞限時免費中長按識別下圖二維碼跟著老鍾一起吃透單詞邏輯實現萬級詞彙突破零基礎get從0到10000詞的高效邏輯👇
  • hang是懸掛,那「hang in there」是掛在哪裡嗎
    歡迎來到英語乾貨街,今天分享一個正能量滿滿的習語「hang in there」 它可不是「掛在那裡」喲!hang in there,Huawei !美國政府無緣無故對華為實施制裁,堅持住啊,華為!hang in there, Cathy Meng !加拿大政府兩年前拘捕並拘禁了孟晚舟,至今都不肯放她出來,挺住啊,孟晚舟!
  • 必知習語 get the hang of it
    那麼今天的 idiom 就是 Get the hang of it 就是熟悉,適應,掌握一門技巧的意思。This is my first time driving, and I can’t get the hang of it.這是我第一次開車,我掌握不好。
  • get the hang of是什麼意思?
    Englishtec2019get the hang of意思get the hang of鑑賞; 理解某事; 熟悉某物的用法; 掌握做某事的竅門;To get the hang of something
  • hang out意思不是出去玩
    很多英文老師,都會把hang out解釋為「出去」玩,其實hang out的意思只是打發時間和玩,並不強調「出去」。
  • 英語on fire 和 on the fire 的區別
    英語中,on fire 和 on the fire 是兩個相似詞組,有時候會被弄混淆。今天我們一起來學習一下這兩個詞組的區別。1. on fire:這個詞組的意思是「著火;起火」例句1:Look, the car is on fire!看,車著火了!例句2:Protesters set cars on fire and burned a building.
  • hang out閱讀理解
    at the mall… American teenagers like to hang out at these places.I want to tell you this is true. American teenagers have far too much time to waste (浪費).
  • hang in there 不是掛在那裡的意思
    英語詞組 hang in there 是一個非常正能量的詞組,它的意思是鼓勵別人不要放棄,要有耐心,或都要保持冷靜,不要失去希望。例句1:Hang in there and you never know what you might achieve.堅持下去,你就遠無法知道你會取得什麼樣的成就。例句2:Hang in there. Things will look up soon.
  • 您知道hang是什麼意思嗎?
    說到hang這個單詞,我們最常用的意思是懸掛、吊。其實,這個單詞還有其它的意思。但是,這個單詞的過去式和過去分詞有一點點複雜。今天,我就一起看一下hang的相關用法。看一下,您都掌握了嗎?首先,我們看一下hang做動詞的用法。
  • 「每天學點英語單詞」hang
    to fasten or support something at the top leaving the other parts free to move, or to be held in this way 音標:[hæŋ] 例句: I was worried I wouldn't be able to hang
  • 英語口語表達:hang out
    今天要和大家分享的口語表達是:hang out. Hang out 的本意是:把上身伸出窗外,把東西掛出窗外。hang out the washing. 把洗好的衣服晾出去。hang out 在口語表達裡,有另一個常用意思:出去玩兒。看電影、逛街、聊天都可以,也不限指異性朋友哦。
  • 「on fire、open fire、take fire」都是啥意思?哪個表示開火?
    fire的意思有很多,比如說「火;熱情、激情;解僱,開除」等,今天我們從與fire有關的表達中,來看看這些短語分別是什麼意思。1、On fire大家可能這麼想,on fire不就是「著火」的意思嗎?有什麼好介紹的。
  • 冷門樂器大盤點,你知道「hang」嗎?
    hang噔噔噔噔,這回沒錯了,這就是hang!它採用鋼鐵經過加工製成,經過多次改良,其發聲原理比較先進,採用空間共振,樂器模仿聲音能力較強,可以模仿鑼,加麥蘭,加塔姆,鼓聲,鐘聲等。好的樂手甚至還可以用它來模仿人的嗓音。
  • iOS網絡庫Alamofire內部實現初探
    ,再以=分割Key-value,傳入的第五個參數為HTTP請求報文中的請求頭通過查看源碼發現返回值中的Manager類是對NSURLSession網絡接口的封裝,sharedIntance方法返回一個採用NSURLSessionConfiguration.defaultSessionConfiguration並對其傳入硬編碼默認HTTP請求頭的Manage類實例,Manage類的具體實現不在這裡講
  • Get the hang of it 是什麼意思呀?
    get the hang of (something)學會做某事、