Aracılığıyla paylaş


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:

.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.
  • 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 Developmentkapsam 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:

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:

  1. IHostedLifecycleService.StartingAsync
  2. IHostedService.StartAsync
  3. IHostedLifecycleService.StartedAsync
  4. IHostApplicationLifetime.ApplicationStarted

Uygulama durdurulduğunda, örneğin Ctrl+C ile aşağıdaki olaylar tetiklenir:

  1. IHostApplicationLifetime.ApplicationStopping
  2. IHostedLifecycleService.StoppingAsync
  3. IHostedService.StopAsync
  4. IHostedLifecycleService.StoppedAsync
  5. 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:

Ayrıca hizmet, IHostEnvironment şu uzantı yöntemlerinin yardımıyla ortamı değerlendirme özelliğini kullanıma sunar:

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:

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ırsaConsoleLifetimeUseConsoleLifetime, aşağıdaki sinyalleri dinler ve konağı düzgün bir şekilde durdurmaya çalışır.
    • SIGINT (veya CTRL+C).
    • SIGQUIT (veya Windows'ta CTRL+BREAK, Unix'te CTRL).+\
    • SIGTERM (gibi docker stopdiğer uygulamalar tarafından gönderilir).
  • 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.Exitda 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 ProcessExityol 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.Exit0geç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.Exitbaş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 WaitForShutdownve 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:

Kapatma dizisi diyagramı barındırıyor.

  1. Denetim, olayı yükseltmek ApplicationStopping için ApplicationLifetime öğesine ConsoleLifetime akar. Bu, yürütme kodunun engelini kaldırmaya işaret eder WaitForShutdownAsync Main . Bu arada, POSIX sinyali işlendiği için POSIX sinyal işleyicisi ile birlikte Cancel = true döner.
  2. Main Yürütme kodu yeniden yürütülmeye başlar ve konağa StopAsync()öğesine bildirir; bu da barındırılan tüm hizmetleri durdurur ve durdurulan diğer olayları başlatır.
  3. Son olarak, WaitForShutdown çıkışlar, herhangi bir uygulama temizleme kodunun yürütülmesine ve yöntemin Main 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.

Ayrıca bkz.