.NET'te çalışan hizmetleri
Uzun süre çalışan hizmetler oluşturmanın çeşitli nedenleri vardır:
- Yoğun CPU kullanan verileri işleme.
- Arka planda iş öğelerini kuyruğa alma.
- Zamanlamaya göre zaman tabanlı bir işlem gerçekleştirme.
Arka plan hizmeti işleme genellikle bir kullanıcı arabirimi (UI) içermez, ancak bunların etrafında URI'ler oluşturulabilir. .NET Framework ile ilk günlerde, Windows geliştiricileri bu amaçlar için Windows Hizmetleri oluşturabilirdi. Artık .NET ile uygulamasını kullanabilir BackgroundServiceveya kendi uygulamanızı IHostedServiceuygulayabilirsiniz.
.NET ile artık Windows ile sınırlı değilsiniz. Platformlar arası arka plan hizmetleri geliştirebilirsiniz. Barındırılan hizmetler günlüğe kaydetmeye, yapılandırmaya ve bağımlılık eklemeye (DI) hazırdır. Bunlar, kitaplıkların uzantı paketinin bir parçasıdır ve genel konakla çalışan tüm .NET iş yükleri için temeldir.
Önemli
.NET SDK'sını yüklemek ve çalışan şablonunu da yükler Microsoft.NET.Sdk.Worker
. Başka bir deyişle, .NET SDK'sını yükledikten sonra dotnet new worker komutunu kullanarak yeni bir çalışan oluşturabilirsiniz. Visual Studio kullanıyorsanız, isteğe bağlı ASP.NET ve web geliştirme iş yükü yüklenene kadar şablon gizlenir.
Terminoloji
Birçok terim yanlışlıkla eş anlamlı olarak kullanılır. Bu bölüm, bu makaledeki amaçlarını daha belirgin hale getirmek için bu terimlerden bazılarını tanımlar.
- Arka Plan Hizmeti: Türü BackgroundService .
- Barındırılan IHostedServiceHizmet: uygulaması veya IHostedService kendisi.
- Uzun süre çalışan Hizmet: Sürekli çalışan tüm hizmetler.
- Windows Hizmeti: Başlangıçta .NET Framework merkezli olan ancak artık .NET üzerinden erişilebilen Windows Hizmeti altyapısı.
- Çalışan Hizmeti: Çalışan Hizmeti şablonu.
Çalışan Hizmeti şablonu
Çalışan Hizmeti şablonu .NET CLI ve Visual Studio'da kullanılabilir. Daha fazla bilgi için bkz . .NET CLI, dotnet new worker
- şablonu. Şablon bir Program
ve Worker
sınıfından oluşur.
using App.WorkerService;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<Worker>();
IHost host = builder.Build();
host.Run();
Önceki Program
sınıf:
- oluşturur HostApplicationBuilder.
- öğesini barındırılan
Worker
hizmet olarak kaydetmek için çağrılarAddHostedService. - Oluşturucudan bir IHost oluşturur.
host
Uygulamayı çalıştıran örnekte çağrılarRun
.
Şablon varsayılanları
Çalışan şablonu varsayılan olarak sunucu çöp toplamayı (GC) etkinleştirmez çünkü gerekliliğini belirlemede rol oynayan çok sayıda faktör vardır. Uzun süre çalışan hizmetler gerektiren tüm senaryolar bu varsayılanın performans üzerindeki etkilerini dikkate almalıdır. Sunucu GC'yi etkinleştirmek için düğümü proje dosyasına ekleyin ServerGarbageCollection
:
<PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection>
</PropertyGroup>
Dengeler ve dikkat edilmesi gerekenler
Etkin | Devre Dışı |
---|---|
Verimli bellek yönetimi: Bellek sızıntılarını önlemek ve kaynak kullanımını iyileştirmek için kullanılmayan belleği otomatik olarak geri alır. | Geliştirilmiş gerçek zamanlı performans: Gecikme süresine duyarlı uygulamalarda atık toplamanın neden olduğu olası duraklamaları veya kesintileri önler. |
Uzun vadeli kararlılık: Uzun süreler boyunca belleği yöneterek uzun süre çalışan hizmetlerde kararlı performansın korunmasına yardımcı olur. | Kaynak verimliliği: Kaynak kısıtlanmış ortamlarda CPU ve bellek kaynaklarından tasarruf edebilir. |
Daha az bakım: El ile bellek yönetimi gereksinimini en aza indirerek bakımı basitleştirir. | El ile bellek denetimi: Özel uygulamalar için bellek üzerinde ayrıntılı denetim sağlar. |
Öngörülebilir davranış: Tutarlı ve öngörülebilir uygulama davranışına katkıda bulunur. | Kısa süreli işlemler için uygundur: Kısa süreli veya kısa ömürlü işlemler için çöp toplama yükünü en aza indirir. |
Performansla ilgili dikkat edilmesi gerekenler hakkında daha fazla bilgi için bkz . Sunucu GC. Sunucu GC'sini yapılandırma hakkında daha fazla bilgi için bkz . Sunucu GC yapılandırma örnekleri.
Çalışan sınıfı
şablonuna Worker
gelince, şablon basit bir uygulama sağlar.
namespace App.WorkerService;
public sealed class Worker(ILogger<Worker> logger) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1_000, stoppingToken);
}
}
}
Yukarıdaki Worker
sınıf, uygulamasını uygulayan bir alt sınıfıdırBackgroundServiceIHostedService. BackgroundService, ve abstract class
alt sınıfının uygulamasını BackgroundService.ExecuteAsync(CancellationToken)gerektirir. Şablon uygulamasında, ExecuteAsync
işlem iptal etmek için işaretlenene kadar geçerli tarih ve saati günlüğe kaydetmek için saniyede bir döngü yapılır.
Proje dosyası
Çalışan şablonu aşağıdaki proje dosyasına Sdk
dayanır:
<Project Sdk="Microsoft.NET.Sdk.Worker">
Daha fazla bilgi için bkz . .NET proje SDK'ları.
NuGet paketi
Çalışan şablonunu temel alan bir uygulama SDK'yi Microsoft.NET.Sdk.Worker
kullanır ve Microsoft.Extensions.Hosting paketine açık bir paket başvurusuna sahiptir.
Kapsayıcılar ve buluta uyarlanabilirlik
Çoğu modern .NET iş yükünde kapsayıcılar uygulanabilir bir seçenektir. Visual Studio'da Çalışan şablonundan uzun süre çalışan bir hizmet oluştururken Docker desteğini kabul edebilirsiniz. Bunu yaptığınızda .NET uygulamanızı kapsayıcılı hale getiren bir Dockerfile oluşturulur. Dockerfile, görüntü oluşturmaya yönelik yönergeler kümesidir. .NET uygulamaları için Dockerfile genellikle bir çözüm dosyasının yanındaki dizinin kökünde yer alır.
# See https://aka.ms/containerfastmode to understand how Visual Studio uses this
# Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/runtime:8.0@sha256:e6b552fd7a0302e4db30661b16537f7efcdc0b67790a47dbf67a5e798582d3a5 AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:8.0@sha256:35792ea4ad1db051981f62b313f1be3b46b1f45cadbaa3c288cd0d3056eefb83 AS build
WORKDIR /src
COPY ["background-service/App.WorkerService.csproj", "background-service/"]
RUN dotnet restore "background-service/App.WorkerService.csproj"
COPY . .
WORKDIR "/src/background-service"
RUN dotnet build "App.WorkerService.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "App.WorkerService.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "App.WorkerService.dll"]
Yukarıdaki Dockerfile adımları şunlardır:
- temel görüntüsünü
mcr.microsoft.com/dotnet/runtime:8.0
diğer adbase
olarak ayarlama. - Çalışma dizini /app olarak değiştiriliyor.
- Görüntüden
build
mcr.microsoft.com/dotnet/sdk:8.0
diğer adı ayarlama. - Çalışma dizini /src olarak değiştiriliyor.
- İçeriği kopyalama ve .NET uygulamasını yayımlama:
- Uygulama komutu kullanılarak
dotnet publish
yayımlanır.
- Uygulama komutu kullanılarak
- .NET SDK görüntüsünün
mcr.microsoft.com/dotnet/runtime:8.0
geçişini (base
diğer ad) gerçekleştirme. - Yayımlanan derleme çıktısı /publish'dan kopyalanıyor.
- öğesini temsil
dotnet App.BackgroundService.dll
eden giriş noktasını tanımlama.
İpucu
içindeki mcr.microsoft.com
MCR, "Microsoft Container Registry" anlamına gelir ve Microsoft'un resmi Docker hub'ından gelen genel kapsayıcı kataloğudur. Microsoft syndicates kapsayıcı kataloğu makalesi ek ayrıntılar içerir.
Docker'ı .NET Çalışan Hizmetiniz için dağıtım stratejisi olarak hedeflediğinizde, proje dosyasında dikkat edilmesi gereken birkaç nokta vardır:
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
<RootNamespace>App.WorkerService</RootNamespace>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
</ItemGroup>
</Project>
Yukarıdaki proje dosyasında öğesi <DockerDefaultTargetOS>
hedefi olarak belirtir Linux
. Windows kapsayıcılarını hedeflemek için bunun yerine kullanın Windows
. Microsoft.VisualStudio.Azure.Containers.Tools.Targets
Şablondan Docker desteği seçildiğinde NuGet paketi otomatik olarak paket başvurusu olarak eklenir.
.NET ile Docker hakkında daha fazla bilgi için bkz . Öğretici: .NET uygulamasını kapsayıcıya alma. Azure'a dağıtma hakkında daha fazla bilgi için bkz . Öğretici: Azure'a Çalışan Hizmeti Dağıtma.
Önemli
Çalışan şablonuyla Kullanıcı Gizli Dizileri'ni kullanmak istiyorsanız NuGet paketine Microsoft.Extensions.Configuration.UserSecrets
açıkça başvurmanız gerekir.
Barındırılan Hizmet genişletilebilirliği
IHostedService Arabirimi iki yöntem tanımlar:
Bu iki yöntem yaşam döngüsü yöntemi görevi görür. Bunlar sırasıyla konak başlatma ve durdurma olayları sırasında çağrılır.
Not
veya StopAsync yöntemlerini geçersiz kıldığınızdaStartAsync, hizmetin düzgün şekilde başlatıldığından base
ve/veya kapandığından emin olmak için ve await
sınıf yöntemini çağırmalısınız.
Önemli
Arabirim, uzantı yönteminde AddHostedService<THostedService>(IServiceCollection) genel tür parametre kısıtlaması görevi görür, yani yalnızca uygulamalara izin verilir. Sağlanan BackgroundService öğesini bir alt sınıfla kullanabilir veya tamamen kendi sınıfınızı uygulayabilirsiniz.
Sinyal tamamlama
Çoğu yaygın senaryoda, barındırılan bir hizmetin tamamlanmasını açıkça işaret etmeniz gerekmez. Konak hizmetleri başlattığında, konak durdurulana kadar çalışacak şekilde tasarlanmıştır. Ancak bazı senaryolarda, hizmet tamamlandığında konak uygulamasının tamamının tamamlanmasının sinyalini vermeniz gerekebilir. Tamamlanma sinyali vermek için aşağıdaki Worker
sınıfı göz önünde bulundurun:
namespace App.SignalCompletionService;
public sealed class Worker(
IHostApplicationLifetime hostApplicationLifetime,
ILogger<Worker> logger) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// TODO: implement single execution logic here.
logger.LogInformation(
"Worker running at: {Time}", DateTimeOffset.Now);
await Task.Delay(1_000, stoppingToken);
// When completed, the entire app host will stop.
hostApplicationLifetime.StopApplication();
}
}
Önceki kodda ExecuteAsync
yöntemi döngü yapmaz ve tamamlandığında öğesini çağırır IHostApplicationLifetime.StopApplication().
Önemli
Bu, konağa durması gerektiğini bildirir ve bu çağrı olmadan konağa StopApplication
süresiz olarak çalışmaya devam eder.
Daha fazla bilgi için bkz.
- .NET Genel Ana Bilgisayarı: IHostApplicationLifetime
- .NET Genel Ana Bilgisayarı: Ana bilgisayar kapatma
- .NET Genel Ana Bilgisayarı: Barındırma kapatma işlemi