天天看點

.NET 中的 Worker Service 入門介紹

翻譯自 Steve Gordon 2020年3月30日的文章 《WHAT ARE .NET WORKER SERVICES?》 1

随着 .NET Core 3.0 的釋出,ASP.NET 團隊引入了一個新的 Worker Service 項目模闆,該模闆作為 .NET SDK 的一部分釋出。在本文中,我将向您介紹這個新模闆,以及使用它開發的一些實際的服務示例。

譯者注:

請先完成以下準備工作,以便于您了解本文。

1、下載下傳并安裝最新的 .NET SDK:https://dotnet.microsoft.com/download

2、指令行運作

dotnet new Worker -n "MyService"

指令,建立一個 Worker Service 項目。

什麼是 .NET Core Worker Service?

Worker Service 是使用模闆建構的 .NET 項目,該模闆提供了一些有用的功能,可以将正常控制台應用程式變得更加強大。Worker Service 運作于宿主(Host)的概念之上,宿主維護應用程式的生命周期。宿主還提供了一些常見的特性,如依賴注入、日志記錄和配置。

Worker Service 通常是長時間運作的服務,執行一些規律發生的工作負載。

Worker Service 的一些例子

  • 處理來自隊列、服務總線或事件流的消息、事件
  • 響應對象、檔案存儲中的檔案更改
  • 聚合資料存儲中的資料
  • 豐富資料提取管道中的資料
  • AI/ML 資料集的格式化和清理

還可以開發一個這樣的 Worker Service,該服務從頭到尾執行一個過程,然後關閉。結合排程程式,便可以支援定期的批處理工作負載。例如,排程程式每隔一小時啟動一次服務,完成一些彙總資料的計算,然後關閉。

Worker Service 沒有使用者界面,也不支援直接的使用者互動,它們特别适用于設計微服務架構。在微服務體系結構中,職責通常被劃分為不同的、可單獨部署的、可伸縮的服務。随着微服務架構的成長和發展,擁有大量的 Worker Service 會變得越來越常見。

Worker Service 模闆提供了什麼?

完全可以在不使用 Worker Service 模闆的情況下開發長時間運作的 Worker Service。在 .NET Core 的早期版本中我是這樣做的,使用依賴注入容器手動建立宿主,然後啟動我的處理工作負載。

在預設情況下,Worker Service 模闆包含了有用的基礎元件,比如依賴注入,這樣我們就可以集中精力在其上建構業務邏輯。它包含了一個管理應用程式生命周期的宿主。

Worker Service 模闆本身是相當基礎的,它隻包含了三個開箱即用的核心檔案。

1. Program.cs

第一個是 Program 類。該類包含 .NET 控制台應用程式所必需的

Main

方法入口點,.NET 運作時期望在啟動 .NET 應用程式時在 Program 類中查找此方法。

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<Worker>();
            });
}
           

在 Program 類中,作為 Worker Service 模闆一部分的是

CreateHostBuilder

方法,該方法建立一個

IHostBuilder

IHostBuilder

接口定義了一個類型,該類型使用生成器模式生成

IHost

的執行個體。此模闆通過調用 Host 類中的靜态

CreateDefaultBuilder

方法來建立一個新的 HostBuilder。

然後,它使用生成器來配置 IHost,該 IHost 被用于運作 Worker Service 應用程式。宿主提供了依賴注入容器和日志記錄等功能,就像我們可以在 ASP.NET Core 應用程式中使用的那樣。事實上,從 .NET Core 3.0 開始,ASP.NET Core Web 應用程式和 .NET Core Worker Service 都運作在同一 IHost 上的。

預設情況下,它包含了一個服務注冊,稍後我會在本文中介紹,暫時不用擔心。

Main

方法中調用

CreateDefaultBuilder

方法,将建構并立即運作宿主。當 .NET 運作時調用

Main

方法時,應用程式啟動,宿主将保持運作,監聽标準的關閉信号(例如按下

CTRL+C

鍵)。

2. appsettings.json

如果您以前使用過 ASP.NET Core,将會非常熟悉 appsettings.json 檔案,它是應用程式配置的常見來源之一。宿主被設計 為,當啟動應用程式時,使用任意已注冊的配置提供程式從多個來源加載應用程式配置。其中一種提供程式是從 appsettings.json 加載配置,該檔案内容由 JSON 組成,其結構包含表示應用程式配置的鍵和值。這些值可以随意地定義在對相關配置按邏輯分組成的片段(Sections)内。

在 Worker Service 中,啟動時會檢查相同的配置源(包括此 appsettings.json 檔案和環境變量),并從不同的源建構最終的配置。預設情況下會加載多種預設的提供程式,是以也會加載多種源。如果需要,您也可以自定義宿主用來加載配置資料的提供程式。

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}
           

模闆中的預設 appsettings 檔案中包含日志記錄庫的配置設定項,預設對 Worker Service 可用。這裡的配置是為某些日志記錄上下文設定記錄級别的。

3. Worker.cs

Worker 是一個您在預設的 ASP.NET Core 項目模闆中見不到的新類。它是托管服務與宿主相結合的魔力所在,提供了 Worker Service 的基礎。

讓我們來看一下它的代碼:

public class Worker : BackgroundService
{
    private readonly ILogger<Worker> _logger;

    public Worker(ILogger<Worker> logger)
    {
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
            await Task.Delay(1000, stoppingToken);
        }
    }
}
           

此類從 BackgroundService 抽象基類派生。BackgroundService 類實作了一個名為 IHostedService 的接口。

BackgroundService 包含一個名為

ExecuteAsync

的抽象方法,我們必須在子類中重寫該方法,就像 Worker Service 模闆中提供的 Worker 類中所做的那樣。

ExecuteAsync

方法傳回一個 Task,在 BackgroundService 内部,期望此 Task 是一些長時間運作的工作負載。該 Task 會被啟動并在背景運作。

在内部,宿主将啟動 IHostedService 的所有注冊實作(包括從 BackgroundService 抽象類派生的類型)。請記住,BackgroundService 為我們實作了 IHostedService。

4. 如何注冊托管服務(IHostedService)?

下一個顯而易見的問題是,如何注冊 IHostedService ? 如果我們傳回到 Program.cs 的代碼,我們将會找到答案:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureServices((hostContext, services) =>
        {
            services.AddHostedService<Worker>();
        });
           

ConfigureServices

方法中,可以向依賴注入容器注冊類型。

AddHostedService

是為 IServiceCollection 定義的一個擴充方法,它允許我們注冊一個實作了 IHostedService 的類。

該模闆中已将 Worker 類注冊為托管服務。

在啟動時,宿主将找到已注冊的 IHostedService 的所有執行個體,并按順序啟動它們,此時,它們的長時間運作的工作負載會作為背景任務來運作。

為什麼要建構 .NET Core Worker Service?

簡單的答案是——何時以及是否需要它們!如果您需要開發一個微服務,它沒有使用者界面,并執行長時間運作的工作,那麼 Worker Service 很可能是一個好的選擇。

請記住,Worker Service 的底層隻是一個控制台應用程式。該控制台應用程式使用宿主将應用程式轉換為運作的服務,直到收到停止的信号。宿主帶來了您可能已經熟悉的一些特性,比如依賴關系注入。使用和 ASP.NET Core 中可用的相同的日志記錄和配置擴充,使得開發可記錄日志資訊且需要一些配置的 Worker Service 變得相當輕松。當建構運作在雲上的 Worker Service 時,幾乎總會存在這種需求。例如,您可能需要為與您的 Worker Service 互相動的任何外部服務提供配置(比如一個隊列 URL)。

Worker Service 可用于從現有的 ASP.NET Core 應用程式提取職責,設計新的基于 .NET Core 的微服務。

總結

在本文中,我介紹了 Worker Service 項目模闆,以及它的一些潛在用例。我們探索了使用 Worker Service 模闆建立的新項目中所包含的三個預設檔案。

Worker Service 模闆包含哪些檔案?

  • Program.cs: 控制台應用程式的入口點,建立并運作宿主以管理應用程式生命周期并生成一個長期運作的服務。
  • appsettings.json:一個提供應用程式配置值的 JSON 檔案。
  • Worker.cs:派生自 BackgroundService 基類,用于定義作為背景任務執行的長時間運作的工作負載。

Worker Service 是什麼?

  • 不需要使用者互動的應用程式。
  • 使用宿主來維護控制台應用程式的生命周期,直到宿主收到關閉的信号。将控制台應用程式轉換為長時間運作的服務。
  • 包含和 ASP.NET Core 相同的功能,如依賴注入、日志記錄和配置。
  • 執行定期和長時間運作的工作負載。

作者 : Steve Gordon

譯者 : 技術譯民

出品 : 技術譯站

連結 : 英文原文

.NET 中的 Worker Service 入門介紹
  1. https://www.stevejgordon.co.uk/what-are-dotnet-worker-services WHAT ARE .NET WORKER SERVICES? ↩︎