Genel Ana Bilgisayar
Bu makalede, Microsoft.Extensions.Hosting NuGet paketinde kullanılabilen bir .NET Genel Konağı yapılandırmaya ve oluşturmaya yönelik çeşitli desenler hakkında bilgi ediniyorsunuz. .NET Genel Ana Bilgisayarı, uygulama başlatma ve yaşam süresi yönetiminden sorumludur. Çalışan Hizmeti şablonları bir .NET Genel Ana Bilgisayarı oluşturur. HostApplicationBuilder Genel Ana Bilgisayar, Konsol uygulamaları gibi diğer .NET uygulaması türleriyle kullanılabilir.
Konak, bir uygulamanın kaynaklarını ve yaşam süresi işlevselliğini kapsülleyen bir nesnedir, örneğin:
- Bağımlılık ekleme (DI)
- Günlük Kaydı
- Yapılandırma
- Uygulama kapatma
IHostedService
Uygulama
Bir konak başlatıldığında, hizmet kapsayıcısının barındırılan IHostedService hizmetler koleksiyonunda kayıtlı olan her uygulamasını çağırırIHostedService.StartAsync. Çalışan hizmeti uygulamasında, örnekleri BackgroundService.ExecuteAsync içeren BackgroundService tüm IHostedService
uygulamaların yöntemleri çağrılır.
Uygulamanın tüm birbirine bağlı kaynaklarını tek bir nesneye eklemenin temel nedeni yaşam süresi yönetimidir: uygulama başlatma ve düzgün kapatma üzerinde denetim.
Konak ayarlama
Konak genellikle sınıfında kodla Program
yapılandırılır, oluşturulur ve çalıştırılır. Main
yöntemi:
- CreateApplicationBuilder Oluşturucu nesnesi oluşturmak ve yapılandırmak için bir yöntem çağırır.
- Örnek oluşturmak IHost için çağrılarBuild().
- Konak nesnesinde çağrılar Run veya RunAsync yöntem.
.NET Çalışan Hizmeti şablonları, Genel Konak oluşturmak için aşağıdaki kodu oluşturur:
using Example.WorkerService;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<Worker>();
IHost host = builder.Build();
host.Run();
Çalışan Hizmetleri hakkında daha fazla bilgi için bkz . .NET'te Çalışan Hizmetleri.
Konak oluşturucu ayarları
CreateApplicationBuilder yöntemi:
- İçerik kökünü tarafından GetCurrentDirectory()döndürülen yola ayarlar.
- Konak yapılandırmasını şu kaynaktan yükler:
- ile önekli
DOTNET_
ortam değişkenleri. - Komut satırı bağımsız değişkenleri.
- ile önekli
- Uygulama yapılandırmasını şu kaynaktan yükler:
- appsettings.json.
- appsettings. {Environment}.json.
- Uygulama ortamda çalıştırıldığında
Development
Gizli Dizi Yöneticisi. - Ortam değişkenleri.
- Komut satırı bağımsız değişkenleri.
- Aşağıdaki günlük sağlayıcılarını ekler:
- Konsol
- Hata Ayıklama
- EventSource
- EventLog (yalnızca Windows üzerinde çalışırken)
- Ortam olduğunda
Development
kapsam doğrulamasını ve bağımlılık doğrulamasını etkinleştirir.
HostApplicationBuilder.Services bir Microsoft.Extensions.DependencyInjection.IServiceCollection örnektir. Bu hizmetler, kayıtlı hizmetleri çözümlemek için bağımlılık ekleme ile kullanılan bir IServiceProvider derlemek için kullanılır.
Çerçeve tarafından sağlanan hizmetler
veya HostApplicationBuilder.Build()çağrısı IHostBuilder.Build() yaptığınızda, aşağıdaki hizmetler otomatik olarak kaydedilir:
Ek senaryo tabanlı konak oluşturucuları
Web için oluşturuyorsanız veya dağıtılmış bir uygulama yazıyorsanız, farklı bir konak oluşturucu kullanmanız gerekebilir. Aşağıdaki ek konak oluşturucuları listesini göz önünde bulundurun:
- DistributedApplicationBuilder: Dağıtılmış uygulamalar oluşturmak için bir oluşturucu. Daha fazla bilgi için bkz . .NET Aspire.
- WebApplicationBuilder: Web uygulamaları ve hizmetleri için bir oluşturucu. Daha fazla bilgi için bkz . ASP.NET Core.
- WebHostBuilder: için
IWebHost
bir oluşturucu. Daha fazla bilgi için bkz . ASP.NET Core web konağı.
IHostApplicationLifetime
IHostApplicationLifetime Başlatma sonrası ve düzgün kapatma görevlerini işlemek için hizmeti herhangi bir sınıfa ekleme. Arabirimdeki üç özellik, uygulama başlatma ve uygulama durdurma olay işleyicisi yöntemlerini kaydetmek için kullanılan iptal belirteçleridir. Arabirim bir yöntem de içerir StopApplication() .
Aşağıdaki örnek, olayları kaydeden IHostApplicationLifetime
bir IHostedService ve IHostedLifecycleService uygulamasıdır:
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace AppLifetime.Example;
public sealed class ExampleHostedService : IHostedService, IHostedLifecycleService
{
private readonly ILogger _logger;
public ExampleHostedService(
ILogger<ExampleHostedService> logger,
IHostApplicationLifetime appLifetime)
{
_logger = logger;
appLifetime.ApplicationStarted.Register(OnStarted);
appLifetime.ApplicationStopping.Register(OnStopping);
appLifetime.ApplicationStopped.Register(OnStopped);
}
Task IHostedLifecycleService.StartingAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("1. StartingAsync has been called.");
return Task.CompletedTask;
}
Task IHostedService.StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("2. StartAsync has been called.");
return Task.CompletedTask;
}
Task IHostedLifecycleService.StartedAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("3. StartedAsync has been called.");
return Task.CompletedTask;
}
private void OnStarted()
{
_logger.LogInformation("4. OnStarted has been called.");
}
private void OnStopping()
{
_logger.LogInformation("5. OnStopping has been called.");
}
Task IHostedLifecycleService.StoppingAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("6. StoppingAsync has been called.");
return Task.CompletedTask;
}
Task IHostedService.StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("7. StopAsync has been called.");
return Task.CompletedTask;
}
Task IHostedLifecycleService.StoppedAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("8. StoppedAsync has been called.");
return Task.CompletedTask;
}
private void OnStopped()
{
_logger.LogInformation("9. OnStopped has been called.");
}
}
Çalışan Hizmeti şablonu, uygulamayı eklemek ExampleHostedService
için değiştirilebilir:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using AppLifetime.Example;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<ExampleHostedService>();
using IHost host = builder.Build();
await host.RunAsync();
Uygulama aşağıdaki örnek çıkışı yazacak:
// Sample output:
// info: AppLifetime.Example.ExampleHostedService[0]
// 1.StartingAsync has been called.
// info: AppLifetime.Example.ExampleHostedService[0]
// 2.StartAsync has been called.
// info: AppLifetime.Example.ExampleHostedService[0]
// 3.StartedAsync has been called.
// info: AppLifetime.Example.ExampleHostedService[0]
// 4.OnStarted has been called.
// info: Microsoft.Hosting.Lifetime[0]
// Application started. Press Ctrl+C to shut down.
// info: Microsoft.Hosting.Lifetime[0]
// Hosting environment: Production
// info: Microsoft.Hosting.Lifetime[0]
// Content root path: ..\app-lifetime\bin\Debug\net8.0
// info: AppLifetime.Example.ExampleHostedService[0]
// 5.OnStopping has been called.
// info: Microsoft.Hosting.Lifetime[0]
// Application is shutting down...
// info: AppLifetime.Example.ExampleHostedService[0]
// 6.StoppingAsync has been called.
// info: AppLifetime.Example.ExampleHostedService[0]
// 7.StopAsync has been called.
// info: AppLifetime.Example.ExampleHostedService[0]
// 8.StoppedAsync has been called.
// info: AppLifetime.Example.ExampleHostedService[0]
// 9.OnStopped has been called.
Çıktı, çeşitli yaşam döngüsü olaylarının tümünün sırasını gösterir:
IHostedLifecycleService.StartingAsync
IHostedService.StartAsync
IHostedLifecycleService.StartedAsync
IHostApplicationLifetime.ApplicationStarted
Uygulama durdurulduğunda, örneğin Ctrl+C ile aşağıdaki olaylar tetiklenir:
IHostApplicationLifetime.ApplicationStopping
IHostedLifecycleService.StoppingAsync
IHostedService.StopAsync
IHostedLifecycleService.StoppedAsync
IHostApplicationLifetime.ApplicationStopped
IHostLifetime
Uygulama, IHostLifetime konağın ne zaman başlayacağını ve ne zaman durduğunda denetler. Kaydedilen son uygulama kullanılır. Microsoft.Extensions.Hosting.Internal.ConsoleLifetime
varsayılan IHostLifetime
uygulamadır. Kapatmanın yaşam süresi mekaniği hakkında daha fazla bilgi için bkz . Konak kapatma.
IHostLifetime
Arabirim, başlangıçta çağrılan IHost.StartAsync
ve devam etmeden önce tamamlanana kadar bekleyeceği bir IHostLifetime.WaitForStartAsync yöntemi kullanıma sunar. Bu, bir dış olay tarafından sinyal alınana kadar başlatmayı geciktirmek için kullanılabilir.
Ayrıca arabirim, konağın IHostLifetime
durduğunu ve kapatma zamanının geldiğini belirtmek için 'den IHost.StopAsync
çağrılan bir IHostLifetime.StopAsync yöntemi kullanıma sunar.
IHostEnvironment
IHostEnvironment Aşağıdaki ayarlar hakkında bilgi almak için hizmeti bir sınıfa ekleyin:
- IHostEnvironment.ApplicationName
- IHostEnvironment.ContentRootFileProvider
- IHostEnvironment.ContentRootPath
- IHostEnvironment.EnvironmentName
Ayrıca hizmet, IHostEnvironment
şu uzantı yöntemlerinin yardımıyla ortamı değerlendirme özelliğini kullanıma sunar:
- HostingEnvironmentExtensions.IsDevelopment
- HostingEnvironmentExtensions.IsEnvironment
- HostingEnvironmentExtensions.IsProduction
- HostingEnvironmentExtensions.IsStaging
Konak yapılandırması
Konak yapılandırması, IHostEnvironment uygulamasının özelliklerini yapılandırmak için kullanılır.
Konak yapılandırması özelliğinde HostApplicationBuilderSettings.Configuration ve ortam uygulaması özelliğinde IHostApplicationBuilder.Environment kullanılabilir. Konağı yapılandırmak için özelliğine erişin Configuration
ve kullanılabilir uzantı yöntemlerinden herhangi birini çağırın.
Konak yapılandırması eklemek için aşağıdaki örneği göz önünde bulundurun:
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
HostApplicationBuilderSettings settings = new()
{
Args = args,
Configuration = new ConfigurationManager(),
ContentRootPath = Directory.GetCurrentDirectory(),
};
settings.Configuration.AddJsonFile("hostsettings.json", optional: true);
settings.Configuration.AddEnvironmentVariables(prefix: "PREFIX_");
settings.Configuration.AddCommandLine(args);
HostApplicationBuilder builder = Host.CreateApplicationBuilder(settings);
using IHost host = builder.Build();
// Application code should start here.
await host.RunAsync();
Yukarıdaki kod:
- İçerik kökünü tarafından GetCurrentDirectory()döndürülen yola ayarlar.
- Konak yapılandırmasını şu kaynaktan yükler:
- hostsettings.json.
- ile önekli
PREFIX_
ortam değişkenleri. - Komut satırı bağımsız değişkenleri.
Uygulama yapılandırması
Uygulama yapılandırması, üzerinde IHostApplicationBuilderçağrılarak ConfigureAppConfiguration oluşturulur. OrtakIHostApplicationBuilder.Configuration özellik, kullanılabilir uzantı yöntemlerini kullanarak tüketicilerin mevcut yapılandırmadan okumasına veya bu yapılandırmada değişiklik yapmasına olanak tanır.
Daha fazla bilgi için bkz . .NET'te yapılandırma.
Ana bilgisayar kapatma
Barındırılan bir işlemin durdurulmasının çeşitli yolları vardır. En yaygın olarak, barındırılan bir işlem aşağıdaki yollarla durdurulabilir:
- Birisi aramazsa Run veya HostingAbstractionsHostExtensions.WaitForShutdown uygulama normal bir şekilde
Main
tamamlayarak çıkar. - Uygulama kilitlenirse.
- Uygulama SIGKILL (veya CTRL+Z) kullanılarak zorla kapatılırsa.
Barındırma kodu bu senaryoların işlenmesinden sorumlu değildir. İşlemin sahibinin diğer tüm uygulamalarla aynı şekilde işlem yapması gerekir. Barındırılan bir hizmet işleminin durdurulabilmesinin birkaç yolu daha vardır:
- ( kullanılırsa
ConsoleLifetime
UseConsoleLifetime, aşağıdaki sinyalleri dinler ve konağı düzgün bir şekilde durdurmaya çalışır. - Uygulama tarafından çağrılırsa Environment.Exit.
Yerleşik barındırma mantığı bu senaryoları, özellikle sınıfını ConsoleLifetime
işler. ConsoleLifetime
uygulamaya düzgün bir çıkış sağlamak için SIGINT, SIGQUIT ve SIGTERM "kapatma" sinyallerini işlemeye çalışır.
.NET 6'nın öncesinde .NET kodunun SIGTERM'yi düzgün bir şekilde işlemesi için bir yol yoktu. Bu sınırlamayı ConsoleLifetime
geçici olarak çözmek için öğesine System.AppDomain.ProcessExitabone olur. Yükseltildiğinde ProcessExit
, ConsoleLifetime
konağın durmasını ve iş parçacığını engelleyip konağın ProcessExit
durmasını beklemesi için konağa işaret eder.
İşlem çıkış işleyicisi, uygulamadaki temizleme kodunun (örneğin, IHost.StopAsync yönteminden sonra HostingAbstractionsHostExtensions.Run ) çalıştırılmasına Main
izin verir.
Ancak, bu yaklaşımda başka sorunlar da vardı çünkü tek yol ProcessExit
SIGTERM değildi. Uygulama kodu çağırdığında Environment.Exit
da SIGTERM oluşturulur. Environment.Exit
uygulama modelindeki Microsoft.Extensions.Hosting
bir işlemi kapatmanın zarif bir yolu değildir. Olayı yükseltir ProcessExit
ve işlemden çıkar. yönteminin Main
sonu yürütülmüyor. Arka plan ve ön plan iş parçacıkları sonlandırılır ve finally
bloklar yürütülemez .
ConsoleLifetime
Konağın kapanmasını beklerken engellendiği ProcessExit
için bu davranış, çağrısının beklenmesi için de bloklardan Environment.Exit
kilitlenmelere ProcessExit
yol açtı. Ayrıca, SIGTERM işleme işlemi düzgün bir şekilde kapatmaya çalıştığından, ConsoleLifetime
kullanıcı çıkış kodunun 'a Environment.Exit
0
geçirilmesini engelleyen olarak ayarlanır.ExitCode
.NET 6'da POSIX sinyalleri desteklenir ve işlenir. SIGTERM'yi ConsoleLifetime
düzgün bir şekilde işler ve çağrıldığında Environment.Exit
artık dahil olmaz.
İpucu
.NET 6+ için artık ConsoleLifetime
senaryoyla Environment.Exit
başa çıkabilecek mantığı yoktur. Çağıran Environment.Exit
ve temizleme mantığı gerçekleştirmesi gereken uygulamalar kendilerine abone ProcessExit
olabilir. Barındırma artık bu senaryolarda konağı düzgün bir şekilde durdurmayı denemeyecektir.
Uygulamanız barındırma kullanıyorsa ve konağı düzgün bir şekilde durdurmak istiyorsanız yerine öğesini çağırabilirsiniz IHostApplicationLifetime.StopApplication Environment.Exit
.
Barındırma kapatma işlemi
Aşağıdaki sıralı diyagram, sinyallerin barındırma kodunda dahili olarak nasıl işleneceğini gösterir. Kullanıcıların çoğunun bu işlemi anlaması gerekmez. Ancak derin bir anlayışa ihtiyacı olan geliştiriciler için iyi bir görsel kullanmaya başlamanıza yardımcı olabilir.
Konak başlatıldıktan sonra, bir kullanıcı veya WaitForShutdown
çağrısında Run
için IApplicationLifetime.ApplicationStoppingbir işleyici kaydedilir. Yürütme, içinde duraklatılır WaitForShutdown
ve olayın tetiklenecek şekilde beklenmesine ApplicationStopping
neden olur. Main
yöntemi hemen geri dönmez ve uygulama veya WaitForShutdown
dönene kadar Run
çalışır durumda kalır.
İşleme bir sinyal gönderildiğinde aşağıdaki sırayı başlatır:
- Denetim, olayı yükseltmek
ApplicationStopping
içinApplicationLifetime
öğesineConsoleLifetime
akar. Bu, yürütme kodunun engelini kaldırmaya işaret ederWaitForShutdownAsync
Main
. Bu arada, POSIX sinyali işlendiği için POSIX sinyal işleyicisi ile birlikteCancel = true
döner. Main
Yürütme kodu yeniden yürütülmeye başlar ve konağaStopAsync()
öğesine bildirir; bu da barındırılan tüm hizmetleri durdurur ve durdurulan diğer olayları başlatır.- Son olarak,
WaitForShutdown
çıkışlar, herhangi bir uygulama temizleme kodunun yürütülmesine ve yönteminMain
düzgün bir şekilde çıkabilmesine olanak sağlar.
Web sunucusu senaryolarında konak kapatma
Kestrel'de hem HTTP/1.1 hem de HTTP/2 protokolleri için düzgün kapatmanın çalıştığı ve trafiği sorunsuz bir şekilde boşaltmak için farklı ortamlarda yük dengeleyici ile nasıl yapılandırabileceğinize ilişkin diğer yaygın senaryolar vardır. Web sunucusu yapılandırması bu makalenin kapsamı dışında olsa da, ASP.NET Core Kestrel web sunucusu belgeleri için seçenekleri yapılandırma hakkında daha fazla bilgi bulabilirsiniz.
Konak bir kapatma sinyali aldığında (örneğin, CTL+C veya StopAsync
), sinyal vererek ApplicationStoppinguygulamaya bildirir. Düzgün bir şekilde bitmesi gereken uzun süre çalışan işlemleriniz varsa bu olaya abone olmanız gerekir.
Ardından, Konak yapılandırabileceğiniz bir kapatma zaman aşımıyla (varsayılan 30'lar) çağırır IServer.StopAsync . Kestrel (ve Http.Sys) bağlantı noktası bağlamalarını kapatır ve yeni bağlantıları kabul etmeyi durdurur. Ayrıca geçerli bağlantılara yeni istekleri işlemeyi durdurmalarını söyler. HTTP/2 ve HTTP/3 için istemciye bir ön GOAWAY
ileti gönderilir. HTTP/1.1 için, istekler sırayla işlendiği için bağlantı döngüsünü durdurur. IIS, 503 durum koduyla yeni istekleri reddederek farklı davranır.
Etkin isteklerin kapatma zaman aşımı tamamlanana kadar süresi vardır. Bunların tümü zaman aşımından önce tamamlanırsa, sunucu denetimi konağa daha erken döndürür. Zaman aşımı süresi dolarsa bekleyen bağlantılar ve istekler zorla durdurularak günlüklerde ve istemcilerde hatalara neden olabilir.
Yük dengeleyici ile ilgili dikkat edilmesi gerekenler
Yük dengeleyiciyle çalışırken istemcilerin yeni bir hedefe sorunsuz geçişini sağlamak için şu adımları izleyebilirsiniz:
- Yeni örneği açın ve trafiği dengelemeye başlayın (ölçeklendirme amacıyla zaten çeşitli örnekleriniz olabilir).
- Yeni trafik almayı durdurması için yük dengeleyici yapılandırmasındaki eski örneği devre dışı bırakın veya kaldırın.
- Eski örneğe kapatması için sinyal verin.
- Boşaltmasını veya zaman aşımına geçmesini bekleyin.