Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Petunjuk / Saran
Konten ini adalah kutipan dari eBook, Arsitektur Layanan Mikro .NET untuk Aplikasi .NET Kontainer, tersedia di .NET Docs atau sebagai PDF gratis yang dapat diunduh yang dapat dibaca secara offline.
Tugas latar belakang dan pekerjaan terjadwal adalah sesuatu yang mungkin perlu Anda gunakan dalam aplikasi apa pun, apakah itu mengikuti pola arsitektur layanan mikro atau tidak. Perbedaan saat menggunakan arsitektur layanan mikro adalah Anda dapat menerapkan tugas latar belakang dalam proses/kontainer terpisah untuk hosting sehingga Anda dapat menurunkan/meningkatkannya berdasarkan kebutuhan Anda.
Dari sudut pandang umum, di .NET kami memanggil jenis tugas Layanan yang Dihosting ini, karena ini adalah layanan/logika yang Anda host dalam host/aplikasi/layanan mikro Anda. Perhatikan bahwa dalam kasus ini, layanan hosting hanya mengacu pada sebuah kelas dengan logika tugas latar belakang.
Sejak .NET Core 2.0, kerangka kerja menyediakan antarmuka baru bernama IHostedService membantu Anda menerapkan layanan yang dihosting dengan mudah. Ide dasarnya adalah Anda dapat mendaftarkan beberapa tugas latar belakang (layanan yang dihosting) yang berjalan di latar belakang saat host web atau host Anda berjalan, seperti yang ditunjukkan pada gambar 6-26.
Gambar 6-26. Menggunakan IHostedService di WebHost vs. Host
ASP.NET Core 1.x dan 2.x mendukung IWebHost
untuk proses latar belakang di aplikasi web. .NET Core 2.1 dan versi yang lebih baru mendukung IHost
untuk menjalankan proses latar belakang dengan aplikasi konsol biasa. Perhatikan perbedaan yang dibuat antara WebHost
dan Host
.
WebHost
(kelas dasar yang mengimplementasikan IWebHost
) di ASP.NET Core 2.0 adalah artefak infrastruktur yang Anda gunakan untuk menyediakan fitur peladen HTTP untuk proses yang Anda kerjakan, seperti saat Anda mengimplementasikan aplikasi web MVC atau layanan API Web. Ini memberikan semua kebaikan infrastruktur baru di ASP.NET Core, memungkinkan Anda menggunakan injeksi dependensi, menyisipkan middleware dalam alur permintaan, dan yang serupa.
WebHost
ini menggunakan IHostedServices
yang sama persis untuk tugas latar belakang.
Host
(kelas dasar yang mengimplementasikan IHost
) diperkenalkan di .NET Core 2.1. Pada dasarnya, Host
memungkinkan Anda memiliki infrastruktur yang sama dari apa yang Anda miliki dengan WebHost
(injeksi dependensi, layanan yang dihosting, dll.), tetapi dalam hal ini, Anda hanya ingin memiliki proses yang sederhana dan lebih ringan sebagai host, tanpa ada yang terkait dengan fitur MVC, API Web, atau server HTTP.
Oleh karena itu, Anda dapat memilih dan membuat proses host khusus dengan IHost
untuk menangani layanan yang dihosting dan tidak ada yang lain, seperti layanan mikro yang dibuat hanya untuk menghosting IHostedServices
, atau Anda dapat memperluas ASP.NET Core WebHost
yang ada, seperti ASP.NET Core Web API atau aplikasi MVC yang ada.
Setiap pendekatan memiliki pro dan kontra tergantung pada kebutuhan bisnis dan skalabilitas Anda. Intinya pada dasarnya adalah bahwa jika tugas latar belakang Anda tidak ada hubungannya dengan HTTP (IWebHost
) Anda harus menggunakan IHost
.
Mendaftarkan layanan yang dihosting di WebHost atau Host Anda
Mari kita telusuri lebih dalam antarmuka IHostedService
karena penggunaannya cukup mirip dalam sebuah WebHost
atau Host
.
SignalR adalah salah satu contoh artefak menggunakan layanan yang dihosting, tetapi Anda juga dapat menggunakannya untuk hal-hal yang jauh lebih sederhana seperti:
- Tugas latar belakang yang memeriksa database untuk mencari perubahan.
- Tugas terjadwal memperbarui beberapa cache secara berkala.
- Implementasi QueueBackgroundWorkItem untuk mengeksekusi tugas pada utas latar belakang.
- Memproses pesan dari antrean pesan di latar belakang aplikasi web sambil berbagi layanan umum seperti
ILogger
. - Tugas latar belakang dimulai dengan
Task.Run()
.
Anda pada dasarnya dapat memindahkan salah satu tindakan tersebut ke tugas latar belakang yang mengimplementasikan IHostedService
.
Cara Anda menambahkan satu atau beberapa IHostedServices
ke dalam WebHost
atau Host
Anda adalah dengan cara mendaftarkannya melalui metode ekstensi AddHostedService dalam ASP.NET Core WebHost
(atau dalam Host
di .NET Core 2.1 ke atas). Pada dasarnya, Anda harus mendaftarkan layanan yang dihosting dalam startup aplikasi di Program.cs.
//Other DI registrations;
// Register Hosted Services
builder.Services.AddHostedService<GracePeriodManagerService>();
builder.Services.AddHostedService<MyHostedServiceB>();
builder.Services.AddHostedService<MyHostedServiceC>();
//...
Dalam kode itu, layanan yang dihosting GracePeriodManagerService
adalah kode nyata dari layanan mikro Pemesanan di eShopOnContainers, sedangkan dua lainnya hanyalah contoh tambahan.
IHostedService
Eksekusi tugas latar belakang dikoordinasikan dengan masa pakai aplikasi (host atau layanan mikro, dalam hal ini). Anda mendaftarkan tugas ketika aplikasi dimulai dan Anda memiliki kesempatan untuk melakukan beberapa tindakan anggun atau pembersihan saat aplikasi dimatikan.
Tanpa menggunakan IHostedService
, Anda selalu dapat memulai utas latar belakang untuk menjalankan tugas apa pun. Perbedaannya tepatnya pada waktu matikan aplikasi ketika utas tersebut hanya akan dimatikan tanpa memiliki kesempatan untuk menjalankan tindakan pembersihan yang anggun.
Antarmuka IHostedService
Ketika Anda mendaftarkan IHostedService
, .NET memanggil metode-metode StartAsync()
dan StopAsync()
dari jenis IHostedService
Anda masing-masing saat aplikasi mulai dan berhenti. Untuk detail selengkapnya, lihat Antarmuka IHostedService.
Seperti yang dapat Anda bayangkan, Anda dapat membuat beberapa implementasi IHostedService dan mendaftarkan masing-masing di Program.cs, seperti yang ditunjukkan sebelumnya. Semua layanan yang dihosting akan dimulai dan dihentikan bersama dengan aplikasi/layanan mikro.
Sebagai pengembang, Anda bertanggung jawab untuk menangani tindakan menghentikan layanan Anda ketika StopAsync()
metode dipicu oleh host.
Menerapkan IHostedService dengan kelas layanan yang dihosting kustom yang berasal dari kelas dasar BackgroundService
Anda dapat melanjutkan dan membuat kelas layanan kustom yang dihosting dari awal dan menerapkan IHostedService
, seperti yang perlu Anda lakukan saat menggunakan .NET Core 2.0 dan yang lebih baru.
Namun, karena sebagian besar tugas latar belakang akan memiliki kebutuhan yang sama sehubungan dengan manajemen token pembatalan dan operasi khas lainnya, ada kelas dasar abstrak yang nyaman yang dapat Anda dapatkan, bernama BackgroundService
(tersedia sejak .NET Core 2.1).
Kelas tersebut menyediakan pekerjaan utama yang diperlukan untuk menyiapkan tugas latar belakang.
Kode berikutnya adalah kelas dasar BackgroundService abstrak seperti yang diimplementasikan dalam .NET.
// 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();
}
}
Saat menggunakan kelas dasar abstrak sebelumnya, berkat implementasi yang diwariskan, Anda hanya perlu menerapkan metode ExecuteAsync()
di dalam kelas layanan yang dihost kustom Anda sendiri, seperti pada kode yang disederhanakan berikut dari eShopOnContainers, yang melakukan polling terhadap basis data dan menerbitkan peristiwa integrasi ke dalam Event Bus ketika diperlukan.
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.");
}
.../...
}
Dalam kasus spesifik ini untuk eShopOnContainers, aplikasi ini menjalankan metode yang mengkueri tabel database untuk mencari pesanan dengan status spesifik, dan saat menerapkan perubahan, itu menerbitkan peristiwa integrasi melalui bus peristiwa (di bawahnya, misalnya, dapat menggunakan RabbitMQ atau Azure Service Bus).
Tentu saja, Anda dapat menjalankan tugas latar belakang bisnis lainnya, sebagai gantinya.
Secara default, token pembatalan diatur dengan batas waktu 5 detik, meskipun Anda dapat mengubah nilai tersebut dengan menggunakan ekstensi WebHost
dari UseShutdownTimeout
saat membangun IWebHostBuilder
Anda. Ini berarti bahwa layanan kami diharapkan akan dibatalkan dalam waktu 5 detik, jika tidak, layanan tersebut akan dihentikan secara tiba-tiba.
Kode berikut akan mengubah waktu tersebut menjadi 10 detik.
WebHost.CreateDefaultBuilder(args)
.UseShutdownTimeout(TimeSpan.FromSeconds(10))
...
Diagram ringkasan kelas
Gambar berikut menunjukkan ringkasan visual kelas dan antarmuka yang terlibat saat menerapkan IHostedServices.
Gambar 6-27. Diagram kelas memperlihatkan beberapa kelas dan antarmuka yang terkait dengan IHostedService
Diagram kelas: IWebHost dan IHost dapat menghosting banyak layanan yang merupakan turunan dari BackgroundService serta mengimplementasikan IHostedService.
Pertimbangan penyebaran dan pelajaran penting
Penting untuk dicatat bahwa cara Anda menyebarkan ASP.NET Core WebHost
atau .NET Host
dapat memengaruhi solusi akhir. Misalnya, jika Anda menyebarkan WebHost
di IIS atau Azure App Service biasa, host Anda dapat dimatikan karena daur ulang kumpulan aplikasi. Tetapi jika Anda menyebarkan host sebagai kontainer ke dalam orkestrator seperti Kubernetes, Anda dapat memastikan jumlah instans host yang tetap aktif. Selain itu, Anda dapat mempertimbangkan pendekatan lain di cloud yang terutama dibuat untuk skenario ini, seperti Azure Functions. Terakhir, jika Anda memerlukan layanan untuk berjalan sepanjang waktu dan menyebarkan di Windows Server, Anda dapat menggunakan Layanan Windows.
Tetapi bahkan untuk yang WebHost
disebarkan ke dalam kumpulan aplikasi, ada skenario seperti mengisi ulang atau menghapus cache dalam memori aplikasi yang masih akan berlaku.
Antarmuka IHostedService
menyediakan cara mudah untuk memulai tugas latar belakang dalam aplikasi web ASP.NET Core (di .NET Core 2.0 dan versi yang lebih baru) atau dalam proses/host apa pun (dimulai di .NET Core 2.1 dengan IHost
). Manfaat utamanya adalah kesempatan yang Anda dapatkan dengan pembatalan yang anggun untuk membersihkan kode tugas latar belakang Anda ketika host itu sendiri dimatikan.
Sumber daya tambahan
Membangun tugas terjadwal di ASP.NET Core/Standard 2.0
https://blog.maartenballiauw.be/post/2017/08/01/building-a-scheduled-cache-updater-in-aspnet-core-2.htmlMenerapkan IHostedService di ASP.NET Core 2.0
https://www.stevejgordon.co.uk/asp-net-core-2-ihostedserviceSampel GenericHost menggunakan ASP.NET Core 2.1
https://github.com/aspnet/Hosting/tree/release/2.1/samples/GenericHostSample