Sdílet prostřednictvím


ASP.NET Core ve službě Azure Service Fabric Reliable Services

ASP.NET Core je opensourcová a multiplatformní architektura. Tato architektura je určená pro vytváření cloudových aplikací připojených k internetu, jako jsou webové aplikace, aplikace IoT a mobilní back-endy.

Tento článek je podrobný průvodce hostováním služeb ASP.NET Core ve službě Service Fabric Reliable Services pomocí sady balíčků NuGet Microsoft.ServiceFabric.AspNetCore.

Úvodní kurz ASP.NET Core v Service Fabric a pokyny k nastavení vývojového prostředí najdete v tématu Kurz: Vytvoření a nasazení aplikace s front-endovou službou ASP.NET Core Web API a stavovou back-endovou službou.

Zbývající část tohoto článku předpokládá, že už znáte ASP.NET Core. Pokud ne, přečtěte si základní informace o ASP.NET Core.

ASP.NET Core v prostředí Service Fabric

Aplikace ASP.NET Core i Service Fabric se můžou spouštět v rozhraní .NET Core nebo v plném rozhraní .NET Framework. V Service Fabric můžete ASP.NET Core používat dvěma různými způsoby:

  • Hostovaný jako spustitelný soubor hosta. Tímto způsobem se primárně používají ke spouštění existujících aplikací ASP.NET Core v Service Fabric beze změn kódu.
  • Spusťte v rámci spolehlivé služby. Tímto způsobem umožňuje lepší integraci s modulem runtime Service Fabric a umožňuje stavové služby ASP.NET Core.

Zbytek tohoto článku vysvětluje, jak používat ASP.NET Core v rámci spolehlivé služby prostřednictvím komponent integrace ASP.NET Core, které se dodávají se sadou Service Fabric SDK.

Hostování služby Service Fabric

V Service Fabric se jedna nebo více instancí a/nebo replik vaší služby spouští v hostitelském procesu služby: spustitelný soubor, který spouští kód služby. Jako autor služby vlastníte proces hostitele služby a Service Fabric ho aktivujete a monitorujete za vás.

Tradiční ASP.NET (až MVC 5) je úzce svázaná se službou IIS prostřednictvím System.Web.dll. ASP.NET Core poskytuje oddělení mezi webovým serverem a vaší webovou aplikací. Toto oddělení umožňuje přenos webových aplikací mezi různými webovými servery. Umožňuje také hostování webových serverů. To znamená, že webový server můžete spustit ve vlastním procesu, na rozdíl od procesu vlastněného vyhrazeným softwarem webového serveru, jako je služba IIS.

Pokud chcete kombinovat službu Service Fabric a ASP.NET jako spustitelný soubor hosta nebo ve spolehlivé službě, musíte být schopni spustit ASP.NET uvnitř hostitelského procesu služby. ASP.NET samoobslužné hostování core vám to umožní.

Hostování ASP.NET Core ve spolehlivé službě

Obvykle místní ASP.NET Core aplikace vytvářejí webhost v vstupním bodu aplikace, například metodu static void Main() v Program.cs. V tomto případě je životní cyklus webového hostitele vázán na životní cyklus procesu.

Hostování ASP.NET Core v procesu

Vstupní bod aplikace ale není správným místem pro vytvoření webového hostitele ve spolehlivé službě. Je to proto, že vstupní bod aplikace slouží pouze k registraci typu služby v modulu runtime Service Fabric, aby mohl vytvořit instance tohoto typu služby. WebHost by se měl vytvořit v samotné spolehlivé službě. V rámci hostitelského procesu služby můžou instance služby nebo repliky procházet více životních cyklů.

Instance Reliable Service je reprezentována vaší třídou služby odvozenou z StatelessService nebo StatefulService. Komunikační zásobník pro službu je obsažen v ICommunicationListener implementaci ve vaší třídě služby. Balíčky Microsoft.ServiceFabric.AspNetCore.* NuGet obsahují implementace ICommunicationListener tohoto spuštění a správu ASP.NET Core WebHost pro Kestrel nebo HTTP.sys ve spolehlivé službě.

Diagram hostování ASP.NET Core ve spolehlivé službě

ASP.NET Core ICommunicationListeners

Implementace ICommunicationListener pro Kestrel a HTTP.sys v Microsoft.ServiceFabric.AspNetCore.* balíčcích NuGet mají podobné vzory použití. Provádějí ale mírně odlišné akce specifické pro každý webový server.

Oba naslouchací procesy komunikace poskytují konstruktor, který přijímá následující argumenty:

  • ServiceContext serviceContext: Toto je ServiceContext objekt, který obsahuje informace o spuštěné službě.
  • string endpointName: Toto je název Endpoint konfigurace v ServiceManifest.xml. Je to především tam, kde se dva naslouchací procesy komunikace liší. HTTP.sys vyžaduje Endpoint konfiguraci, zatímco Kestrel ne.
  • Func<string, AspNetCoreCommunicationListener, IWebHost> build: Toto je lambda, kterou implementujete, ve které vytvoříte a vrátíte .IWebHost Umožňuje nakonfigurovat IWebHost způsob, jakým byste normálně v aplikaci ASP.NET Core. Lambda poskytuje adresu URL, která se pro vás vygeneruje v závislosti na možnostech integrace Service Fabric, které používáte, a konfiguraci Endpoint , kterou zadáte. Potom můžete tuto adresu URL upravit nebo použít ke spuštění webového serveru.

Middleware integrace Service Fabric

Balíček Microsoft.ServiceFabric.AspNetCore NuGet obsahuje metodu UseServiceFabricIntegration IWebHostBuilder rozšíření, která přidává middleware s podporou Service Fabric. Tento middleware nakonfiguruje Kestrel nebo HTTP.sys ICommunicationListener tak, aby registrovali jedinečnou adresu URL služby ve službě Pojmenování Service Fabric. Potom ověří požadavky klientů, aby se zajistilo, že se klienti připojují ke správné službě.

Tento krok je nezbytný, aby se klienti omylem připojili k nesprávné službě. Je to proto, že v prostředí sdíleného hostitele, jako je Service Fabric, může několik webových aplikací běžet na stejném fyzickém nebo virtuálním počítači, ale nepoužívá jedinečné názvy hostitelů. Tento scénář je podrobněji popsán v další části.

Případ chybné identity

Repliky služeb bez ohledu na protokol naslouchají jedinečné kombinaci IP:port. Jakmile replika služby začne naslouchat na koncovém bodu IP:port, hlásí adresu koncového bodu službě Pojmenování Service Fabric. Klienti nebo jiné služby ji mohou zjistit. Pokud služby používají dynamicky přiřazené aplikační porty, replika služby může shodou okolností používat stejný koncový bod IP:port jiné služby dříve na stejném fyzickém nebo virtuálním počítači. To může způsobit, že se klient omylem připojí k nesprávné službě. Tento scénář může mít za následek následující posloupnost událostí:

  1. Služba A naslouchá na adrese 10.0.0.1:30000 přes protokol HTTP.
  2. Klient přeloží službu A a získá adresu 10.0.0.1:30000.
  3. Služba A se přesune na jiný uzel.
  4. Služba B je umístěna na 10.0.0.1 a shodou okolností používá stejný port 30000.
  5. Klient se pokusí připojit ke službě A s adresou uloženou v mezipaměti 10.0.0.1:30000.
  6. Klient je teď úspěšně připojený ke službě B, ale neuvědomuje si, že je připojený k nesprávné službě.

To může způsobit chyby v náhodných časech, které mohou být obtížné diagnostikovat.

Použití jedinečných adres URL služby

Aby se těmto chybám zabránilo, můžou služby publikovat koncový bod do služby pojmenování s jedinečným identifikátorem a pak tento jedinečný identifikátor ověřit během požadavků klientů. Jedná se o spolupráci mezi službami v nehostinném důvěryhodném prostředí tenanta. Neposkytuje zabezpečené ověřování služby v prostředí nehostinných tenantů.

V důvěryhodném prostředí middleware přidaný UseServiceFabricIntegration metodou automaticky připojí k adrese publikované službě pojmenování jedinečný identifikátor. Ověří tento identifikátor u každého požadavku. Pokud se identifikátor neshoduje, middleware okamžitě vrátí odpověď HTTP 410 Gone.

Služby, které používají dynamicky přiřazený port, by měly tento middleware využívat.

Služby, které používají pevný jedinečný port, tento problém nemají v kooperativním prostředí. Pevný jedinečný port se obvykle používá pro externě přístupné služby, které potřebují dobře známý port pro připojení klientských aplikací. Například většina internetových webových aplikací bude pro připojení webového prohlížeče používat port 80 nebo 443. V takovém případě by neměl být povolený jedinečný identifikátor.

Následující diagram znázorňuje tok požadavku s povoleným middlewarem:

Integrace Service Fabric ASP.NET Core

Kestrel i HTTP.sys ICommunicationListener implementace používají tento mechanismus stejným způsobem. Přestože HTTP.sys může interně rozlišovat požadavky na základě jedinečných cest URL pomocí základní funkce sdílení portů HTTP.sys, tato funkce není používána implementací HTTP.sysICommunicationListener. Důvodem je to, že výsledkem jsou stavové kódy chyb HTTP 503 a HTTP 404 ve scénáři popsaném výše. To zase znesnadňuje klientům určit záměr chyby, protože http 503 a HTTP 404 se běžně používají k označení jiných chyb.

Proto jak Kestrel, tak HTTP.sys ICommunicationListener implementace standardizují middleware poskytované rozšiřující metodou UseServiceFabricIntegration . Klienti proto potřebují provést pouze akci opětovného překladu koncového bodu služby u odpovědí HTTP 410.

HTTP.sys v Reliable Services

V Reliable Services můžete použít HTTP.sys importem balíčku NuGet Microsoft.ServiceFabric.AspNetCore.HttpSys . Tento balíček obsahuje HttpSysCommunicationListenerimplementaci ICommunicationListener. HttpSysCommunicationListener umožňuje vytvořit ASP.NET Core WebHost uvnitř spolehlivé služby pomocí HTTP.sys jako webového serveru.

HTTP.sys je založená na rozhraní API windows HTTP Serveru. Toto rozhraní API používá ovladač jádra HTTP.sys ke zpracování požadavků HTTP a jejich směrování do procesů, které spouští webové aplikace. To umožňuje více procesům na stejném fyzickém nebo virtuálním počítači hostovat webové aplikace na stejném portu, nejednoznačné jedinečným názvem adresy URL nebo názvem hostitele. Tyto funkce jsou užitečné v Service Fabric pro hostování více webů ve stejném clusteru.

Poznámka:

HTTP.sys implementace funguje jenom na platformě Windows.

Následující diagram znázorňuje, jak HTTP.sys používá ovladač jádra HTTP.sys ve Windows ke sdílení portů:

diagram HTTP.sys

HTTP.sys ve bezstavové službě

Pokud chcete použít HttpSys bezstavovou službu, přepište metodu CreateServiceInstanceListeners a vraťte HttpSysCommunicationListener instanci:

protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
    return new ServiceInstanceListener[]
    {
        new ServiceInstanceListener(serviceContext =>
            new HttpSysCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
                new WebHostBuilder()
                    .UseHttpSys()
                    .ConfigureServices(
                        services => services
                            .AddSingleton<StatelessServiceContext>(serviceContext))
                    .UseContentRoot(Directory.GetCurrentDirectory())
                    .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
                    .UseStartup<Startup>()
                    .UseUrls(url)
                    .Build()))
    };
}

HTTP.sys ve stavové službě

HttpSysCommunicationListener není momentálně navržen pro použití ve stavových službách kvůli komplikacím se základní funkcí sdílení portů HTTP.sys . Další informace najdete v následující části věnované dynamickému přidělování portů s HTTP.sys. Pro stavové služby je Kestrel navrhovaný webový server.

Konfigurace koncového bodu

Pro Endpoint webové servery, které používají rozhraní API Windows HTTP Serveru, včetně HTTP.sys, se vyžaduje konfigurace. Webové servery, které používají rozhraní API systému Windows HTTP Server, musí nejprve rezervovat adresu URL s HTTP.sys (to se obvykle provádí pomocí nástroje netsh ).

Tato akce vyžaduje zvýšená oprávnění, která vaše služby ve výchozím nastavení nemají. Možnosti http nebo https pro Protocol vlastnost Endpoint konfigurace v ServiceManifest.xml se používají speciálně k tomu, aby modul runtime Service Fabric zaregistroval adresu URL HTTP.sys vaším jménem. Dělá to pomocí silné předpony adresy URL se zástupnými čísly .

Pokud chcete například rezervovat http://+:80 službu, použijte v ServiceManifest.xml následující konfiguraci:

<ServiceManifest ... >
    ...
    <Resources>
        <Endpoints>
            <Endpoint Name="ServiceEndpoint" Protocol="http" Port="80" />
        </Endpoints>
    </Resources>

</ServiceManifest>

A název koncového bodu musí být předán konstruktoru HttpSysCommunicationListener :

 new HttpSysCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
 {
     return new WebHostBuilder()
         .UseHttpSys()
         .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
         .UseUrls(url)
         .Build();
 })

Použití HTTP.sys se statickým portem

Pokud chcete použít statický port s HTTP.sys, zadejte číslo portu v Endpoint konfiguraci:

  <Resources>
    <Endpoints>
      <Endpoint Protocol="http" Name="ServiceEndpoint" Port="80" />
    </Endpoints>
  </Resources>

Použití HTTP.sys s dynamickým portem

Pokud chcete použít dynamicky přiřazený port s HTTP.sys, v konfiguraci tuto vlastnost Endpoint vynechátePort:

  <Resources>
    <Endpoints>
      <Endpoint Protocol="http" Name="ServiceEndpoint" />
    </Endpoints>
  </Resources>

Dynamický port přidělený Endpoint konfigurací poskytuje pouze jeden port na hostitelský proces. Aktuální model hostování Service Fabric umožňuje hostování více instancí služby nebo replik ve stejném procesu. To znamená, že každý z nich bude sdílet stejný port při přidělení prostřednictvím Endpoint konfigurace. Několik HTTP.sys instancí může sdílet port pomocí základní funkce sdílení portů HTTP.sys . Není ale podporována HttpSysCommunicationListener kvůli komplikacím, které zavádí pro požadavky klientů. Pro dynamické použití portů je Kestrel navrhovaným webovým serverem.

Kestrel ve službě Reliable Services

Kestrel v Reliable Services můžete použít importem balíčku NuGet Microsoft.ServiceFabric.AspNetCore.Kestrel . Tento balíček obsahuje KestrelCommunicationListenerimplementaci ICommunicationListener. KestrelCommunicationListener umožňuje vytvořit ASP.NET Core WebHost uvnitř spolehlivé služby pomocí Kestrel jako webového serveru.

Kestrel je multiplatformní webový server pro ASP.NET Core. Na rozdíl od HTTP.sys Kestrel nepoužívá centralizovaný správce koncových bodů. Na rozdíl od HTTP.sys také Kestrel nepodporuje sdílení portů mezi více procesy. Každá instance Kestrel musí používat jedinečný port. Další informace o Kestrel naleznete v podrobnostech implementace.

Diagram Kestrel

Kestrel ve bezstavové službě

Pokud chcete použít Kestrel bezstavovou službu, přepište metodu CreateServiceInstanceListeners a vraťte KestrelCommunicationListener instanci:

protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
    return new ServiceInstanceListener[]
    {
        new ServiceInstanceListener(serviceContext =>
            new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
                new WebHostBuilder()
                    .UseKestrel()
                    .ConfigureServices(
                        services => services
                            .AddSingleton<StatelessServiceContext>(serviceContext))
                    .UseContentRoot(Directory.GetCurrentDirectory())
                    .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.UseUniqueServiceUrl)
                    .UseStartup<Startup>()
                    .UseUrls(url)
                    .Build();
            ))
    };
}

Kestrel ve stavové službě

Pokud chcete použít Kestrel ve stavové službě, přepište metodu CreateServiceReplicaListeners a vraťte KestrelCommunicationListener instanci:

protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
{
    return new ServiceReplicaListener[]
    {
        new ServiceReplicaListener(serviceContext =>
            new KestrelCommunicationListener(serviceContext, (url, listener) =>
                new WebHostBuilder()
                    .UseKestrel()
                    .ConfigureServices(
                         services => services
                             .AddSingleton<StatefulServiceContext>(serviceContext)
                             .AddSingleton<IReliableStateManager>(this.StateManager))
                    .UseContentRoot(Directory.GetCurrentDirectory())
                    .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.UseUniqueServiceUrl)
                    .UseStartup<Startup>()
                    .UseUrls(url)
                    .Build();
            ))
    };
}

V tomto příkladu je do kontejneru injektáže závislostí webhost poskytována jedna instance IReliableStateManager . To není nezbytně nutné, ale umožňuje používat IReliableStateManager a spolehlivé kolekce v metodách akcí kontroleru MVC.

Endpoint Ve stavové službě není zadaný KestrelCommunicationListener název konfigurace. Toto je podrobněji vysvětleno v následující části.

Nakonfigurovat Kestrel k používání HTTPS

Při povolování PROTOKOLU HTTPS s Kestrel ve vaší službě budete muset nastavit několik možností naslouchání. ServiceInstanceListener Aktualizujte koncový bod EndpointHttps a naslouchejte na konkrétním portu (například na portu 443). Při konfiguraci webového hostitele pro použití webového serveru Kestrel musíte nakonfigurovat Kestrel tak, aby naslouchal adresám IPv6 ve všech síťových rozhraních:

new ServiceInstanceListener(
serviceContext =>
    new KestrelCommunicationListener(
        serviceContext,
        "EndpointHttps",
        (url, listener) =>
        {
            ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");

            return new WebHostBuilder()
                .UseKestrel(opt =>
                {
                    int port = serviceContext.CodePackageActivationContext.GetEndpoint("EndpointHttps").Port;
                    opt.Listen(IPAddress.IPv6Any, port, listenOptions =>
                    {
                        listenOptions.UseHttps(GetCertificateFromStore());
                        listenOptions.NoDelay = true;
                    });
                })
                .ConfigureAppConfiguration((builderContext, config) =>
                {
                    config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
                })

                .ConfigureServices(
                    services => services
                        .AddSingleton<HttpClient>(new HttpClient())
                        .AddSingleton<FabricClient>(new FabricClient())
                        .AddSingleton<StatelessServiceContext>(serviceContext))
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseStartup<Startup>()
                .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
                .UseUrls(url)
                .Build();
        }))

Úplný příklad v kurzu najdete v tématu Konfigurace Kestrel pro použití HTTPS.

Konfigurace koncového bodu

Konfigurace Endpoint není nutná k použití Kestrelu.

Kestrel je jednoduchý samostatný webový server. Na rozdíl od HTTP.sys (nebo HttpListener) Endpoint nepotřebuje konfiguraci v ServiceManifest.xml, protože před spuštěním nevyžaduje registraci adresy URL.

Použití Kestrel se statickým portem

Statický port můžete nakonfigurovat v Endpoint konfiguraci ServiceManifest.xml pro použití s Kestrel. I když to není nezbytně nutné, nabízí dvě potenciální výhody:

  • Pokud port nepřepadá do rozsahu portů aplikace, otevře se přes bránu firewall operačního systému service Fabric.
  • Tato adresa URL, kterou jste získali prostřednictvím KestrelCommunicationListener , bude používat tento port.
  <Resources>
    <Endpoints>
      <Endpoint Protocol="http" Name="ServiceEndpoint" Port="80" />
    </Endpoints>
  </Resources>

Endpoint Pokud je nakonfigurovaný, musí být jeho název předán do konstruktoruKestrelCommunicationListener:

new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) => ...

Pokud ServiceManifest.xml nepoužívá Endpoint konfiguraci, vynecháte název v konstruktoru KestrelCommunicationListener . V tomto případě použije dynamický port. Další informace o tom najdete v další části.

Použití Kestrel s dynamickým portem

Kestrel nemůže použít automatické přiřazení portu z Endpoint konfigurace v ServiceManifest.xml. Je to proto, že automatické přiřazení portu z Endpoint konfigurace přiřadí jedinečný port na hostitelský proces a jeden hostitelský proces může obsahovat více instancí Kestrel. To nefunguje s Kestrel, protože nepodporuje sdílení portů. Proto musí být každá instance Kestrel otevřena na jedinečném portu.

Pokud chcete použít dynamické přiřazení portu s Kestrelem, vynecháte Endpoint konfiguraci v ServiceManifest.xml zcela a nepředávejte do konstruktoru název koncového KestrelCommunicationListener bodu následujícím způsobem:

new KestrelCommunicationListener(serviceContext, (url, listener) => ...

V této konfiguraci KestrelCommunicationListener automaticky vybere nevyužitý port z rozsahu portů aplikace.

Pro PROTOKOL HTTPS by měl mít koncový bod nakonfigurovaný s protokolem HTTPS bez portu zadaného v ServiceManifest.xml a předat název koncového bodu konstruktoru KestrelCommunicationListener.

Integrace hostitele IHost a minimálního hostování

Kromě IWebHost/IWebHostBuilder KestrelCommunicationListener a HttpSysCommunicationListener podpora vytváření ASP.NET core služeb pomocí IHost/IHostBuilder. To je k dispozici od verze 5.2.1363 Microsoft.ServiceFabric.AspNetCore.Kestrel a Microsoft.ServiceFabric.AspNetCore.HttpSys balíčků.

// Stateless Service
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
    return new ServiceInstanceListener[]
    {
        new ServiceInstanceListener(serviceContext =>
            new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
            {
                return Host.CreateDefaultBuilder()
                        .ConfigureWebHostDefaults(webBuilder =>
                        {
                            webBuilder.UseKestrel()
                                .UseStartup<Startup>()
                                .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
                                .UseContentRoot(Directory.GetCurrentDirectory())
                                .UseUrls(url);
                        })
                        .ConfigureServices(services => services.AddSingleton<StatelessServiceContext>(serviceContext))
                        .Build();
            }))
    };
}

// Stateful Service
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
{
    return new ServiceReplicaListener[]
    {
        new ServiceReplicaListener(serviceContext =>
            new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
            {
                return Host.CreateDefaultBuilder()
                        .ConfigureWebHostDefaults(webBuilder =>
                        {
                            webBuilder.UseKestrel()
                                .UseStartup<Startup>()
                                .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.UseUniqueServiceUrl)
                                .UseContentRoot(Directory.GetCurrentDirectory())
                                .UseUrls(url);
                        })
                        .ConfigureServices(services =>
                        {
                            services.AddSingleton<StatefulServiceContext>(serviceContext);
                            services.AddSingleton<IReliableStateManager>(this.StateManager);
                        })
                        .Build();
            }))
    };
}

Poznámka:

Vzhledem k tomu, že jsou KestrelCommunicationListener a HttpSysCommunicationListener určeny pro webové služby, je nutné zaregistrovat nebo nakonfigurovat webový server (pomocí metody ConfigureWebHostDefaults nebo ConfigureWebHost ) přes IHost.

ASP.NET 6 představil model minimálního hostování, který je jednodušším a jednodušším způsobem vytváření webových aplikací. Minimální model hostování lze také použít s KestrelCommunicationListener a HttpSysCommunicationListener.

// Stateless Service
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
    return new ServiceInstanceListener[]
    {
        new ServiceInstanceListener(serviceContext =>
            new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
            {
                var builder = WebApplication.CreateBuilder();

                builder.Services.AddSingleton<StatelessServiceContext>(serviceContext);
                builder.WebHost
                            .UseKestrel()
                            .UseContentRoot(Directory.GetCurrentDirectory())
                            .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
                            .UseUrls(url);

                builder.Services.AddControllersWithViews();

                var app = builder.Build();

                if (!app.Environment.IsDevelopment())
                {
                    app.UseExceptionHandler("/Home/Error");
                }

                app.UseHttpsRedirection();
                app.UseStaticFiles();
                app.UseRouting();
                app.UseAuthorization();
                app.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");

                return app;
            }))
    };
}
// Stateful Service
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
{
    return new ServiceReplicaListener[]
    {
        new ServiceReplicaListener(serviceContext =>
            new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
            {
                var builder = WebApplication.CreateBuilder();

                builder.Services
                            .AddSingleton<StatefulServiceContext>(serviceContext)
                            .AddSingleton<IReliableStateManager>(this.StateManager);
                builder.WebHost
                            .UseKestrel()
                            .UseContentRoot(Directory.GetCurrentDirectory())
                            .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.UseUniqueServiceUrl)
                            .UseUrls(url);

                builder.Services.AddControllersWithViews();

                var app = builder.Build();

                if (!app.Environment.IsDevelopment())
                {
                    app.UseExceptionHandler("/Home/Error");
                }
                app.UseStaticFiles();
                app.UseRouting();
                app.UseAuthorization();
                app.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");

                return app;
            }))
    };
}

Poskytovatel konfigurace Service Fabric

Konfigurace aplikace v ASP.NET Core je založená na párech klíč-hodnota vytvořených poskytovatelem konfigurace. Přečtěte si o konfiguraci v ASP.NET Core , abyste lépe pochopili obecnou podporu konfigurace ASP.NET Core.

Tato část popisuje, jak se poskytovatel konfigurace Service Fabric integruje s konfigurací ASP.NET Core importem Microsoft.ServiceFabric.AspNetCore.Configuration balíčku NuGet.

Spouštěcí rozšíření AddServiceFabricConfiguration

Po importu Microsoft.ServiceFabric.AspNetCore.Configuration balíčku NuGet je potřeba zaregistrovat zdroj konfigurace Service Fabric v rozhraní API konfigurace ASP.NET Core. Provedete to tak, že zkontrolujete rozšíření AddServiceFabricConfiguration v Microsoft.ServiceFabric.AspNetCore.Configuration oboru názvů proti IConfigurationBuilder.

using Microsoft.ServiceFabric.AspNetCore.Configuration;

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
        .AddServiceFabricConfiguration() // Add Service Fabric configuration settings.
        .AddEnvironmentVariables();
    Configuration = builder.Build();
}

public IConfigurationRoot Configuration { get; }

Teď má služba ASP.NET Core přístup k nastavení konfigurace Service Fabric stejně jako jakékoli jiné nastavení aplikace. Pomocí vzoru možností můžete například načíst nastavení do objektů se silnými typy.

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MyOptions>(Configuration);  // Strongly typed configuration object.
    services.AddMvc();
}

Výchozí mapování klíčů

Ve výchozím nastavení poskytovatel konfigurace Service Fabric obsahuje název balíčku, název oddílu a název vlastnosti. Společně tvoří konfigurační klíč ASP.NET Core následujícím způsobem:

$"{this.PackageName}{ConfigurationPath.KeyDelimiter}{section.Name}{ConfigurationPath.KeyDelimiter}{property.Name}"

Pokud máte například konfigurační balíček s názvem MyConfigPackage s následujícím obsahem, bude hodnota konfigurace k dispozici na ASP.NET Core IConfiguration prostřednictvím MyConfigPackage:MyConfigSection:MyParameter.

<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">  
  <Section Name="MyConfigSection">
    <Parameter Name="MyParameter" Value="Value1" />
  </Section>  
</Settings>

Možnosti konfigurace Service Fabric

Zprostředkovatel konfigurace Service Fabric také podporuje ServiceFabricConfigurationOptions změnu výchozího chování mapování klíčů.

Šifrovaná nastavení

Service Fabric podporuje šifrovaná nastavení, stejně jako poskytovatel konfigurace Service Fabric. Šifrovaná nastavení se ve výchozím nastavení nešifrují do ASP.NET Core IConfiguration . Šifrované hodnoty jsou místo toho uloženy. Pokud ale chcete dešifrovat hodnotu uloženou v ASP.NET Core IConfiguration, můžete v rozšíření nastavit příznak DecryptValue na false, jak je znázorněno AddServiceFabricConfiguration níže:

public Startup()
{
    ICodePackageActivationContext activationContext = FabricRuntime.GetActivationContext();
    var builder = new ConfigurationBuilder()        
        .AddServiceFabricConfiguration(activationContext, (options) => options.DecryptValue = false); // set flag to decrypt the value
    Configuration = builder.Build();
}

Několik konfiguračních balíčků

Service Fabric podporuje více konfiguračních balíčků. Ve výchozím nastavení je název balíčku součástí konfiguračního klíče. Příznak ale můžete nastavit IncludePackageName na false následujícím způsobem:

public Startup()
{
    ICodePackageActivationContext activationContext = FabricRuntime.GetActivationContext();
    var builder = new ConfigurationBuilder()        
        // exclude package name from key.
        .AddServiceFabricConfiguration(activationContext, (options) => options.IncludePackageName = false); 
    Configuration = builder.Build();
}

Mapování vlastních klíčů, extrakce hodnot a základní soubor dat

Zprostředkovatel konfigurace Service Fabric podporuje také pokročilejší scénáře přizpůsobení mapování klíčů a ExtractKeyFunc vlastní extrakci hodnot pomocí ExtractValueFunc. Můžete dokonce změnit celý proces naplnění dat z konfigurace Service Fabric na ASP.NET Core konfigurace pomocí ConfigAction.

Následující příklady ilustrují použití ConfigAction k přizpůsobení základního souboru dat:

public Startup()
{
    ICodePackageActivationContext activationContext = FabricRuntime.GetActivationContext();
    
    this.valueCount = 0;
    this.sectionCount = 0;
    var builder = new ConfigurationBuilder();
    builder.AddServiceFabricConfiguration(activationContext, (options) =>
        {
            options.ConfigAction = (package, configData) =>
            {
                ILogger logger = new ConsoleLogger("Test", null, false);
                logger.LogInformation($"Config Update for package {package.Path} started");

                foreach (var section in package.Settings.Sections)
                {
                    this.sectionCount++;

                    foreach (var param in section.Parameters)
                    {
                        configData[options.ExtractKeyFunc(section, param)] = options.ExtractValueFunc(section, param);
                        this.valueCount++;
                    }
                }

                logger.LogInformation($"Config Update for package {package.Path} finished");
            };
        });
  Configuration = builder.Build();
}

Aktualizace konfigurace

Poskytovatel konfigurace Service Fabric podporuje také aktualizace konfigurace. Pomocí ASP.NET Core IOptionsMonitor můžete přijímat oznámení o změnách a pak je použít IOptionsSnapshot k opětovnému načtení konfiguračních dat. Další informace najdete v tématu ASP.NET možnosti jádra.

Tyto možnosti jsou ve výchozím nastavení podporované. K povolení aktualizací konfigurace není potřeba žádné další kódování.

Scénáře a konfigurace

Tato část obsahuje kombinaci webového serveru, konfigurace portů, možností integrace Service Fabric a různých nastavení, které doporučujeme vyřešit následujícími scénáři:

  • Externě vystavené bezstavové služby ASP.NET Core
  • Bezstavové služby jen pro interní ASP.NET Core
  • Stavové služby jen pro interní ASP.NET Core

Externě vystavená služba je služba, která zveřejňuje koncový bod, který je volán mimo cluster, obvykle prostřednictvím nástroje pro vyrovnávání zatížení.

Interní služba je jedna, jejíž koncový bod je volán pouze z clusteru.

Poznámka:

Koncové body stavové služby by obecně neměly být přístupné na internetu. Clustery za nástroji pro vyrovnávání zatížení, které neví o překladu služeb Service Fabric, jako je Azure Load Balancer, nebudou moct zveřejnit stavové služby. Důvodem je to, že nástroj pro vyrovnávání zatížení nebude moct vyhledat a směrovat provoz do příslušné repliky stavové služby.

Externě vystavené bezstavové služby ASP.NET Core

Kestrel je navrhovaný webový server pro front-endové služby, které zpřístupňují externí internetové koncové body HTTP. Ve Windows může HTTP.sys poskytovat funkci sdílení portů, která umožňuje hostovat více webových služeb na stejné sadě uzlů pomocí stejného portu. V tomto scénáři se webové služby rozlišují podle názvu hostitele nebo cesty, aniž by se museli spoléhat na front-endový proxy server nebo bránu, aby poskytovaly směrování HTTP.

Při zpřístupnění internetu by bezstavová služba měla používat dobře známý a stabilní koncový bod, který je dostupný prostřednictvím nástroje pro vyrovnávání zatížení. Tuto adresu URL zadáte uživatelům vaší aplikace. Doporučujeme následující konfiguraci:

Typ Doporučení Notes
Webový server Kestrel Kestrel je upřednostňovaným webovým serverem, protože se podporuje v systémech Windows a Linux.
Konfigurace portů static V konfiguraci ServiceManifest.xml by měl být nakonfigurovaný Endpoints dobře známý statický port, například 80 pro HTTP nebo 443 pro HTTPS.
ServiceFabricIntegrationOptions Nic ServiceFabricIntegrationOptions.None Tuto možnost použijte při konfiguraci middlewaru integrace Service Fabric, aby se služba nepokoušla ověřit příchozí požadavky pro jedinečný identifikátor. Externí uživatelé vaší aplikace nebudou znát jedinečné identifikační informace, které middleware používá.
Počet instancí -1 V typických případech použití by mělo být nastavení počtu instancí nastaveno na hodnotu -1. To se provádí tak, aby instance byla k dispozici na všech uzlech, které přijímají provoz z nástroje pro vyrovnávání zatížení.

Pokud několik externě vystavených služeb sdílí stejnou sadu uzlů, můžete použít HTTP.sys s jedinečnou, ale stabilní cestou URL. Toho můžete dosáhnout úpravou adresy URL, kterou jste zadali při konfiguraci IWebHost. Upozorňujeme, že to platí jenom pro HTTP.sys.

new HttpSysCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
{
    url += "/MyUniqueServicePath";

    return new WebHostBuilder()
        .UseHttpSys()
        ...
        .UseUrls(url)
        .Build();
})

Bezstavová služba ASP.NET Core jen pro interní prostředí

Bezstavové služby, které se volají jenom z clusteru, by měly používat jedinečné adresy URL a dynamicky přiřazené porty k zajištění spolupráce mezi více službami. Doporučujeme následující konfiguraci:

Typ Doporučení Notes
Webový server Kestrel I když můžete použít HTTP.sys pro interní bezstavové služby, Kestrel je nejlepší server, který umožňuje více instancím služby sdílet hostitele.
Konfigurace portů dynamicky přiřazené Několik replik stavové služby může sdílet hostitelský proces nebo hostitelský operační systém, a proto bude potřebovat jedinečné porty.
ServiceFabricIntegrationOptions UseUniqueServiceUrl Při přiřazení dynamického portu toto nastavení brání chybnému problému s identitou popsaným výše.
InstanceCount jakékoliv Nastavení počtu instancí lze nastavit na libovolnou hodnotu potřebnou k provozu služby.

Stavová služba jen pro interní ASP.NET Core

Stavové služby, které jsou volána pouze z clusteru, by měly používat dynamicky přiřazené porty k zajištění spolupráce mezi více službami. Doporučujeme následující konfiguraci:

Typ Doporučení Notes
Webový server Kestrel Není HttpSysCommunicationListener určen pro použití stavovými službami, ve kterých repliky sdílejí hostitelský proces.
Konfigurace portů dynamicky přiřazené Několik replik stavové služby může sdílet hostitelský proces nebo hostitelský operační systém, a proto bude potřebovat jedinečné porty.
ServiceFabricIntegrationOptions UseUniqueServiceUrl Při přiřazení dynamického portu toto nastavení brání chybnému problému s identitou popsaným výše.

Další kroky

Ladění aplikace Service Fabric pomocí Visual Studia