Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Jótanács
Ez a tartalom egy részlet a '.NET Microservices Architecture for Containerized .NET Applications' című eBook-ból, amely elérhető a .NET Docs oldalon, vagy ingyenesen letölthető PDF formátumban, amely offline módban is olvasható.
A háttérfeladatokat és az ütemezett feladatokat minden alkalmazásban használnia kell, függetlenül attól, hogy az követi-e a mikroszolgáltatás-architektúra mintáját. A mikroszolgáltatás-architektúra használatakor az a különbség, hogy a háttérfeladatot egy külön folyamatban/tárolóban implementálhatja üzemeltetésre, hogy igény szerint le- vagy felskálázhassa azt.
Általánosságban véve a .NET-ben az ilyen típusú feladatokat üzemeltetett szolgáltatásoknak nevezzük, mivel ezek olyan szolgáltatások vagy logikák, amelyeket a gazdagépen, alkalmazáson vagy mikroszolgáltatáson belül üzemeltetünk. Vegye figyelembe, hogy ebben az esetben a üzemeltetett szolgáltatás egyszerűen egy háttérfeladat-logikával rendelkező osztályt jelent.
A .NET Core 2.0 óta a keretrendszer egy új interfészt biztosít, amely segít az üzemeltetett szolgáltatások egyszerű megvalósításában. Az alapötlet az, hogy több háttérfeladatot és hosztolt szolgáltatást regisztrálhat, amelyek a háttérben futnak, miközben a webkiszolgáló vagy szerver működik, ahogyan az a 6–26. képen látható.
6–26. ábra. Az IHostedService használata webes fogadó vs gazdagépen.
ASP.NET Core 1.x és 2.x támogatja IWebHost a webalkalmazások háttérfolyamatait. A .NET Core 2.1 és újabb verziói támogatják IHost a háttérfolyamatokat egyszerű konzolalkalmazásokkal. Figyelje meg a különbséget a WebHost és a Host között.
Az WebHost az ASP.NET Core 2.0-ban használható alaposztály, amely implementálja IWebHost, és ezáltal infrastruktúra-összetevőként szolgál HTTP-kiszolgálói funkciók biztosításához a munkafolyamathoz, például MVC-webalkalmazás vagy web API-szolgáltatás implementálása esetén. Ez biztosítja a ASP.NET Core összes új infrastruktúra-jóságát, lehetővé téve a függőséginjektálás használatát, köztes szoftverek beszúrását a kérelemfolyamatba és hasonlókat. A WebHost ezeket a IHostedServices használja a háttérfeladatokhoz.
Az Host (alaposztály, amely implementálja IHost) bevezetésre került a .NET Core 2.1-ben. Alapvetően egy Host lehetővé teszi, hogy hasonló infrastruktúrával rendelkezzen, mint amilyen WebHost esetén van (függőséginjektálás, üzemeltetett szolgáltatások stb.), de ebben az esetben csak egy egyszerűbb és könnyebb háttérfolyamattal szeretne dolgozni, az MVC-vel, Web API-val vagy HTTP szerver funkciókkal kapcsolatos összefüggések nélkül.
Ezért választhat, és létrehozhat egy speciális gazdagépfolyamatot IHost az üzemeltetett szolgáltatások kezeléséhez, és semmi mást, például egy olyan mikroszolgáltatást, amelyet csak a IHostedServicesszolgáltatás üzemeltetésére hoztak létre, vagy kiterjeszthet egy meglévő ASP.NET Core-t WebHost, például egy meglévő ASP.NET Core Web API-t vagy MVC-alkalmazást.
Minden megközelítésnek vannak előnyei és hátrányai az üzleti és skálázhatósági igényektől függően. A lényeg az, hogy ha a háttérfeladatoknak semmi köze a HTTP-hez (IWebHost) akkor érdemes használni IHost.
Hosztolt szolgáltatások regisztrálása a WebHostban vagy a hoston
Vizsgáljuk meg részletesebben a IHostedService felületet, mivel a használata meglehetősen hasonló egy WebHost vagy egy Host.
A SignalR egy példa egy üzemeltetett szolgáltatásokat használó összetevőre, de sokkal egyszerűbb dolgokhoz is használhatja, például:
- Egy háttérfeladat, amely egy adatbázist kérdez le, és módosításokat keres.
- Ütemezett feladat, amely időnként frissíti a gyorsítótárat.
- A QueueBackgroundWorkItem implementációja, amely lehetővé teszi a tevékenységek háttérszálon való végrehajtását.
- Üzenetek feldolgozása egy üzenetsorból egy webalkalmazás háttérfolyamata során, közös szolgáltatásokat megosztva, mint például a
ILogger. - Egy háttérfeladat elkezdődött
Task.Run()-val.
Lehetőség van ezen műveletek kiszervezésére egy háttérfeladatba, ami implementálja a IHostedService.
Egy vagy több IHostedServices-t úgy adhat hozzá a WebHost és Host elemekhez, hogy regisztrálja őket az ASP.NET Core AddHostedService bővítménymetódusán keresztül (vagy egy WebHost-ben, a .NET Core 2.1 vagy újabb verzióban). Alapvetően regisztrálnia kell a hosztolt szolgáltatásokat az alkalmazásindításkor a Program.cs fájlban.
//Other DI registrations;
// Register Hosted Services
builder.Services.AddHostedService<GracePeriodManagerService>();
builder.Services.AddHostedService<MyHostedServiceB>();
builder.Services.AddHostedService<MyHostedServiceC>();
//...
Ebben a kódban a GracePeriodManagerService üzemeltetett szolgáltatás valódi kód az eShopOnContainers rendelési üzleti mikroszolgáltatásából, míg a másik kettő csak két további minta.
A IHostedService háttérfeladat végrehajtása az alkalmazás élettartamával (gazdagép vagy mikroszolgáltatás) van összehangolva. A feladatokat az alkalmazás indításakor regisztrálhatja, és az alkalmazás leállításakor lehetősége van némi kecses műveletre vagy törlésre.
A IHostedService használata nélkül elindíthat egy háttérszálat bármely feladat futtatásához. A különbség pontosan az alkalmazás leállítási idején van, amikor a szál egyszerűen megszakítható anélkül, hogy lehetősége lenne kíméletes tisztítási műveleteket végrehajtani.
Az IHostedService felület
Amikor regisztrál egy IHostedService, a .NET az alkalmazás indításakor meghívja a StartAsync() típus StopAsync() és leállításakor a IHostedService metódusait. További részletekért lásd az IHostedService felületét.
Ahogy elképzelheti, az IHostedService több implementációját is létrehozhatja, és mindegyiket regisztrálhatja a Program.cs-ben a korábbi példák szerint. Az összes üzemeltetett szolgáltatás az alkalmazással/mikroszolgáltatással együtt elindul és le lesz állítva.
Fejlesztőként Ön felelős a szolgáltatások leállítási műveletének kezeléséért, amikor a gazdagép aktiválja a StopAsync() metódust.
Az IHostedService implementálása a BackgroundService alaposztályból származó egyéni üzemeltetett szolgáltatásosztálysal
.NET Core 2.0 és újabb verzióinak használatakor az alapoktól létrehozhatja az egyéni hostolt szolgáltatási osztályt, és implementálhatja azt IHostedService.
Mivel azonban a legtöbb háttérfeladatnak hasonló igényei vannak a lemondási jogkivonatok kezelése és más tipikus műveletek tekintetében, van egy kényelmes, absztrakt alaposztály, amelyből származtatható, elnevezve BackgroundService (a .NET Core 2.1 óta érhető el).
Ez az osztály biztosítja a háttérfeladat beállításához szükséges fő munkát.
A következő kód a .NET-ben implementált absztrakt BackgroundService alaposztály.
// Copyright (c) .NET Foundation. Licensed under the Apache License, Version 2.0.
/// <summary>
/// Base class for implementing a long running <see cref="IHostedService"/>.
/// </summary>
public abstract class BackgroundService : IHostedService, IDisposable
{
private Task _executingTask;
private readonly CancellationTokenSource _stoppingCts =
new CancellationTokenSource();
protected abstract Task ExecuteAsync(CancellationToken stoppingToken);
public virtual Task StartAsync(CancellationToken cancellationToken)
{
// Store the task we're executing
_executingTask = ExecuteAsync(_stoppingCts.Token);
// If the task is completed then return it,
// this will bubble cancellation and failure to the caller
if (_executingTask.IsCompleted)
{
return _executingTask;
}
// Otherwise it's running
return Task.CompletedTask;
}
public virtual async Task StopAsync(CancellationToken cancellationToken)
{
// Stop called without start
if (_executingTask == null)
{
return;
}
try
{
// Signal cancellation to the executing method
_stoppingCts.Cancel();
}
finally
{
// Wait until the task completes or the stop token triggers
await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite,
cancellationToken));
}
}
public virtual void Dispose()
{
_stoppingCts.Cancel();
}
}
Ha az előző absztrakt alaposztályból származik, az örökölt implementációnak köszönhetően csak saját egyéni üzemeltetett szolgáltatásosztályban kell implementálnia a ExecuteAsync() metódust, ahogyan az alábbi egyszerűsített kódban az eShopOnContainerstől, amely lekérdez egy adatbázist, és szükség esetén közzéteszi az integrációs eseményeket az Event Busban.
public class GracePeriodManagerService : BackgroundService
{
private readonly ILogger<GracePeriodManagerService> _logger;
private readonly OrderingBackgroundSettings _settings;
private readonly IEventBus _eventBus;
public GracePeriodManagerService(IOptions<OrderingBackgroundSettings> settings,
IEventBus eventBus,
ILogger<GracePeriodManagerService> logger)
{
// Constructor's parameters validations...
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogDebug($"GracePeriodManagerService is starting.");
stoppingToken.Register(() =>
_logger.LogDebug($" GracePeriod background task is stopping."));
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogDebug($"GracePeriod task doing background work.");
// This eShopOnContainers method is querying a database table
// and publishing events into the Event Bus (RabbitMQ / ServiceBus)
CheckConfirmedGracePeriodOrders();
try {
await Task.Delay(_settings.CheckUpdateTime, stoppingToken);
}
catch (TaskCanceledException exception) {
_logger.LogCritical(exception, "TaskCanceledException Error", exception.Message);
}
}
_logger.LogDebug($"GracePeriod background task is stopping.");
}
.../...
}
Ebben a konkrét esetben az eShopOnContainers esetében egy olyan alkalmazásmetódus végrehajtása, amely egy adott állapotú megrendeléseket kereső adatbázistáblát kérdez le, és a módosítások alkalmazásakor az eseménybuszon keresztül teszi közzé az integrációs eseményeket (alatta lehet a RabbitMQ vagy az Azure Service Bus).
Természetesen bármilyen más üzleti háttérfeladatot is futtathat helyette.
Alapértelmezés szerint a törlési token 5 másodperces időkorláttal van beállítva, bár ezt az értéket megváltoztathatja a WebHostUseShutdownTimeout kiterjesztésének IWebHostBuilderlétrehozásakor. Ez azt jelenti, hogy szolgáltatásunk várhatóan 5 másodpercen belül lemondásra kerül, különben sokkal hirtelenebbül leállítják.
Az alábbi kód ezt az időt 10 másodpercre módosítaná.
WebHost.CreateDefaultBuilder(args)
.UseShutdownTimeout(TimeSpan.FromSeconds(10))
...
Összefoglaló osztálydiagram
Az alábbi képen az IHostedServices megvalósítása során érintett osztályok és felületek vizuális összegzése látható.
6–27. ábra. Az IHostedService-hez kapcsolódó osztályok és felületek osztálydiagramja
Osztálydiagram: Az IWebHost és az IHost számos szolgáltatást üzemeltethet, amelyek öröklődnek a BackgroundService szolgáltatástól, amely implementálja az IHostedService szolgáltatást.
Üzembe helyezési szempontok és tanulságok
Fontos megjegyezni, hogy a ASP.NET Core WebHost vagy a .NET Host üzembe helyezése hatással lehet a végső megoldásra. Például, ha az IIS-en vagy egy szokásos Azure App Service-en üzemelteti a WebHost alkalmazást, előfordulhat, hogy a gazdagép leáll az alkalmazáskészletek újrahasznosítása miatt. Ha azonban tárolóként helyezi üzembe a gazdagépet egy olyan vezénylőben, mint a Kubernetes, szabályozhatja a gazdagép biztonságos élő példányainak számát. Emellett a felhőben más megközelítéseket is megfontolhat, különösen ezekhez a forgatókönyvekhez, például az Azure Functionshez. Végül, ha a szolgáltatásnak folyamatosan futnia kell, és Windows Serveren van üzembe helyezve, használhat windowsos szolgáltatást.
De még egy WebHost alkalmazáskészletben üzembe helyezett alkalmazás esetében is vannak olyan forgatókönyvek, mint például az alkalmazás memóriabeli gyorsítótárának újratöltése vagy kiürítése, amely továbbra is alkalmazható lenne.
A IHostedService felület kényelmes módot kínál háttérfeladatok indítására egy ASP.NET Core-webalkalmazásban (.NET Core 2.0-s és újabb verziókban), vagy bármilyen folyamat/gazdagép esetében (a .NET Core 2.1-től IHostkezdve). A fő előnye az a lehetőség, hogy a kecses lemondással megtisztíthatja a háttérfeladatok kódját, amikor maga a gazdagép leáll.
További erőforrások
Ütemezett feladat létrehozása a ASP.NET Core/Standard 2.0-ban
https://blog.maartenballiauw.be/post/2017/08/01/building-a-scheduled-cache-updater-in-aspnet-core-2.htmlAz IHostedService implementálása a ASP.NET Core 2.0-ban
https://www.stevejgordon.co.uk/asp-net-core-2-ihostedserviceGenericHost-minta az ASP.NET Core 2.1 használatával
https://github.com/aspnet/Hosting/tree/release/2.1/samples/GenericHostSample