ASP.NET Core in Reliable Services di Service FabricASP.NET Core in Service Fabric Reliable Services

ASP.NET Core è un nuovo framework open source e multipiattaforma per la compilazione di applicazioni Internet moderne basate sul cloud, ad esempio app Web, app per IoT e back-end per dispositivi mobili.ASP.NET Core is a new open-source and cross-platform framework for building modern cloud-based Internet-connected applications, such as web apps, IoT apps, and mobile backends.

Questo articolo è una guida dettagliata per l'hosting dei servizi ASP.NET Core in Reliable Services di Service Fabric mediante il set di pacchetti NuGet Microsoft.ServiceFabric.AspNetCore..This article is an in-depth guide to hosting ASP.NET Core services in Service Fabric Reliable Services using the **Microsoft.ServiceFabric.AspNetCore.** set of NuGet packages.

Per un'esercitazione introduttiva su ASP.NET Core in Service Fabric e istruzioni per la configurazione dell'ambiente di sviluppo, vedere Compilare un front-end di servizio Web per l'applicazione tramite ASP.NET Core.For an introductory tutorial on ASP.NET Core in Service Fabric and instructions on getting your development environment set up, see Building a web front-end for your application using ASP.NET Core.

La parte restante di questo articolo presuppone che si conosca il funzionamento di ASP.NET Core.The rest of this article assumes you are already familiar with ASP.NET Core. In caso contrario è consigliabile vedere ASP.NET Core fundamentals overview (Panoramica sulle nozioni fondamentali di ASP.NET Core).If not, we recommend reading through the ASP.NET Core fundamentals.

ASP.NET Core nell'ambiente Service FabricASP.NET Core in the Service Fabric environment

Anche se le app ASP.NET Core possono essere eseguite in .NET o nella versione completa di .NET Framework, i servizi di Service Fabric possono essere attualmente eseguiti solo nella versione completa di .NET Framework.While ASP.NET Core apps can run on .NET Core or on the full .NET Framework, Service Fabric services currently can only run on the full .NET Framework. Ciò significa che quando si compila un servizio di Service Fabric in ASP.NET Core è comunque necessario usare la versione completa di .NET Framework.This means when you build an ASP.NET Core Service Fabric service, you must still target the full .NET Framework.

ASP.NET Core può essere usato in due modi diversi in Service Fabric:ASP.NET Core can be used in two different ways in Service Fabric:

  • Ospitato come eseguibile guest.Hosted as a guest executable. Questa modalità viene usata principalmente per eseguire applicazioni ASP.NET Core esistenti in Service Fabric senza apportare modifiche al codice.This is primarily used to run existing ASP.NET Core applications on Service Fabric with no code changes.
  • Eseguito in un servizio Reliable Services.Run inside a Reliable Service. Questa modalità offre una migliore integrazione con il runtime di Service Fabric e consente servizi ASP.NET Core con stato.This allows better integration with the Service Fabric runtime and allows stateful ASP.NET Core services.

Il resto di questo articolo illustra come usare ASP.NET Core in un servizio Reliable Services usando i componenti di integrazione ASP.NET Core forniti con Service Fabric SDK.The rest of this article explains how to use ASP.NET Core inside a Reliable Service using the ASP.NET Core integration components that ship with the Service Fabric SDK.

Hosting di servizi di Service FabricService Fabric service hosting

In Service Fabric, una o più istanze e/o repliche del servizio vengono eseguite in un processo host del servizio, un file eseguibile che esegue il codice del servizio.In Service Fabric, one or more instances and/or replicas of your service run in a service host process, an executable file that runs your service code. L'autore del servizio è il proprietario del processo host del servizio, che verrà attivato e monitorato automaticamente da Service Fabric.You, as a service author, own the service host process and Service Fabric activates and monitors it for you.

La versione tradizionale di ASP.NET, fino a MVC 5, è strettamente associata a IIS tramite System.Web.dll.Traditional ASP.NET (up to MVC 5) is tightly coupled to IIS through System.Web.dll. ASP.NET Core fornisce una separazione tra il server Web e l'applicazione Web.ASP.NET Core provides a separation between the web server and your web application. Ciò consente la portabilità delle applicazioni Web tra server Web diversi e il self-hosting dei server Web, vale a dire che è possibile avviare un server Web nel proprio processo, invece di un processo gestito da software del server Web dedicato, ad esempio IIS.This allows web applications to be portable between different web servers and also allows web servers to be self-hosted, which means you can start a web server in your own process, as opposed to a process that is owned by dedicated web server software such as IIS.

Per combinare un servizio di Service Fabric e ASP.NET, come eseguibile guest o servizio Reliable Services, è necessario poter avviare ASP.NET all'interno del processo host del servizio.In order to combine a Service Fabric service and ASP.NET, either as a guest executable or in a Reliable Service, you must be able to start ASP.NET inside your service host process. Il self-hosting di ASP.NET Core consente di eseguire questa operazione.ASP.NET Core self-hosting allows you to do this.

Hosting di ASP.NET Core in un servizio Reliable ServicesHosting ASP.NET Core in a Reliable Service

Le applicazioni ASP.NET Core con self-hosting creano in genere un WebHost in un punto di ingresso dell'applicazione, ad esempio il metodo static void Main() in Program.cs.Typically, self-hosted ASP.NET Core applications create a WebHost in an application's entry point, such as the static void Main() method in Program.cs. In questo caso, il ciclo di vita del WebHost è associato al ciclo di vita del processo.In this case, the lifecycle of the WebHost is bound to the lifecycle of the process.

Hosting di ASP.NET Core in un processo

Il punto di ingresso dell'applicazione non è tuttavia la posizione corretta per creare un WebHost in un servizio Reliable Services, perché il punto di ingresso dell'applicazione viene usato solo per registrare un tipo di servizio con il runtime di Service Fabric per poter creare istanze di quel tipo di servizio.However, the application entry point is not the right place to create a WebHost in a Reliable Service, because the application entry point is only used to register a service type with the Service Fabric runtime, so that it may create instances of that service type. Il WebHost deve essere creato in un servizio Reliable Services.The WebHost should be created in a Reliable Service itself. Nel processo host del servizio, le istanze e/o le repliche del servizio possono attraversare più cicli di vita.Within the service host process, service instances and/or replicas can go through multiple lifecycles.

Un'istanza di Reliable Services è rappresentata dalla classe del servizio derivante da StatelessService o StatefulService.A Reliable Service instance is represented by your service class deriving from StatelessService or StatefulService. Lo stack di comunicazione di un servizio è contenuto in un'implementazione ICommunicationListener nella classe del servizio.The communication stack for a service is contained in an ICommunicationListener implementation in your service class. I pacchetti NuGet Microsoft.ServiceFabric.Services.AspNetCore.* contengono implementazioni di ICommunicationListener che avviano e gestiscono WebHost ASP.NET Core per Kestrel o HttpSys in un servizio Reliable Services.The Microsoft.ServiceFabric.Services.AspNetCore.* NuGet packages contain implementations of ICommunicationListener that start and manage the ASP.NET Core WebHost for either Kestrel or HttpSys in a Reliable Service.

Hosting di ASP.NET Core in un servizio Reliable Services

ICommunicationListeners ASP.NET CoreASP.NET Core ICommunicationListeners

Le implementazioni di ICommunicationListener per Kestrel e HttpSys nei pacchetti NuGet Microsoft.ServiceFabric.Services.AspNetCore.* hanno modelli di uso simili, ma eseguono azioni leggermente specifiche per ogni server Web.The ICommunicationListener implementations for Kestrel and HttpSys in the Microsoft.ServiceFabric.Services.AspNetCore.* NuGet packages have similar use patterns but perform slightly different actions specific to each web server.

Entrambi i listener di comunicazione forniscono un costruttore che accetta gli argomenti seguenti:Both communication listeners provide a constructor that takes the following arguments:

  • ServiceContext serviceContext: oggetto ServiceContext che contiene informazioni sul servizio in esecuzione.ServiceContext serviceContext: The ServiceContext object that contains information about the running service.
  • string endpointName: nome di una configurazione Endpoint in ServiceManifest.xml.string endpointName: the name of an Endpoint configuration in ServiceManifest.xml. È principalmente qui che i due listener di comunicazione differiscono: HttpSys richiede una configurazione Endpoint che non è invece necessaria per Kestrel.This is primarily where the two communication listeners differ: HttpSys requires an Endpoint configuration, while Kestrel does not.
  • Func<string, AspNetCoreCommunicationListener, IWebHost> build: espressione lambda implementata in cui viene creato e restituito un elemento IWebHost.Func<string, AspNetCoreCommunicationListener, IWebHost> build: a lambda that you implement in which you create and return an IWebHost. È così possibile configurare IWebHost come si farebbe normalmente in un'applicazione ASP.NET Core.This allows you to configure IWebHost the way you normally would in an ASP.NET Core application. L'espressione lambda fornisce un URL che viene generato automaticamente a seconda delle opzioni di integrazione di Service Fabric usate e della configurazione Endpoint specificata.The lambda provides a URL which is generated for you depending on the Service Fabric integration options you use and the Endpoint configuration you provide. L'URL può quindi essere modificato o usato così com'è per avviare il server Web.That URL can then be modified or used as-is to start the web server.

Middleware di integrazione di Service FabricService Fabric integration middleware

Il pacchetto NuGet Microsoft.ServiceFabric.Services.AspNetCore include il metodo di estensione UseServiceFabricIntegration in IWebHostBuilder che aggiunge middleware compatibile con Service Fabric.The Microsoft.ServiceFabric.Services.AspNetCore NuGet package includes the UseServiceFabricIntegration extension method on IWebHostBuilder that adds Service Fabric-aware middleware. Questo middleware configura l'elemento ICommunicationListener di Kestrel o HttpSys per la registrazione di un URL di servizio univoco con Service Fabric Naming Service e quindi convalida le richieste dei client per assicurare che i client si connettano al servizio corretto.This middleware configures the Kestrel or HttpSys ICommunicationListener to register a unique service URL with the Service Fabric Naming Service and then validates client requests to ensure clients are connecting to the right service. Ciò è necessario in un ambiente host condiviso, ad esempio Service Fabric, in cui più applicazioni Web possono essere eseguite nello stesso computer fisico o nella stessa macchina virtuale ma non usano nomi host univoci, per impedire ai client di connettersi erroneamente al servizio sbagliato.This is necessary in a shared-host environment such as Service Fabric, where multiple web applications can run on the same physical or virtual machine but do not use unique host names, to prevent clients from mistakenly connecting to the wrong service. Questo scenario è descritto più dettagliatamente nella sezione successiva.This scenario is described in more detail in the next section.

Un caso di identità errataA case of mistaken identity

Le repliche del servizio, indipendentemente dal protocollo, sono in ascolto in una combinazione IP:porta univoca.Service replicas, regardless of protocol, listen on a unique IP:port combination. Quando è in ascolto su un endpoint IP:porta, la replica del servizio segnala l'indirizzo dell'endpoint a Service Fabric Naming Service, dove può essere individuato dai client o da altri servizi.Once a service replica has started listening on an IP:port endpoint, it reports that endpoint address to the Service Fabric Naming Service where it can be discovered by clients or other services. Se i servizi usano porte delle applicazioni assegnate dinamicamente, una replica del servizio può usare per coincidenza lo stesso endpoint IP:porta di un altro servizio che si trovava precedentemente nello stesso computer fisico o nella stessa macchina virtuale.If services use dynamically-assigned application ports, a service replica may coincidentally use the same IP:port endpoint of another service that was previously on the same physical or virtual machine. In questo modo un client può connettersi per errore al servizio sbagliato.This can cause a client to mistakely connect to the wrong service. Questa situazione può verificarsi in presenza di questa sequenza di eventi:This can happen if the following sequence of events occur:

  1. Il servizio A è in ascolto in 10.0.0.1:30000 su HTTP.Service A listens on 10.0.0.1:30000 over HTTP.
  2. Il client risolve il servizio A e ottiene l'indirizzo 10.0.0.1:30000Client resolves Service A and gets address 10.0.0.1:30000
  3. Il servizio A si sposta in un nodo diverso.Service A moves to a different node.
  4. Il servizio B si trova in 10.0.0.1 e usa per coincidenza la stessa porta 30000.Service B is placed on 10.0.0.1 and coincidentally uses the same port 30000.
  5. Il client prova a connettersi al servizio A con l'indirizzo 10.0.0.1:30000 memorizzato nella cache.Client attempts to connect to service A with cached address 10.0.0.1:30000.
  6. Il client è ora connesso al servizio B e non rileva di essersi connesso al servizio sbagliato.Client is now successfully connected to service B not realizing it is connected to the wrong service.

Ciò può causare bug in momenti casuali che possono essere difficili da diagnosticare.This can cause bugs at random times that can be difficult to diagnose.

Uso di URL di servizio univociUsing unique service URLs

Per evitare questo problema, i servizi possono inviare un endpoint al servizio Naming con un identificatore univoco e quindi convalidare tale identificatore univoco durante le richieste client.To prevent this, services can post an endpoint to the Naming Service with a unique identifier, and then validate that unique identifier during client requests. Si tratta di un'azione cooperativa tra servizi in un ambiente attendibile di tenant non ostili.This is a cooperative action between services in a non-hostile-tenant trusted environment. Non offre l'autenticazione sicura dei servizi in un ambiente di tenant ostili.This does not provide secure service authentication in a hostile-tenant environment.

In un ambiente attendibile, il middleware aggiunto dal metodo UseServiceFabricIntegration accoda automaticamente un identificatore univoco all'indirizzo inviato al servizio Naming e convalida l'identificatore a ogni richiesta.In a trusted environment, the middleware that's added by the UseServiceFabricIntegration method automatically appends a unique identifier to the address that is posted to the Naming Service and validates that identifier on each request. Se l'identificatore non corrisponde, il middleware restituisce immediatamente una risposta HTTP 410 - Non più disponibile.If the identifier does not match, the middleware immediately returns an HTTP 410 Gone response.

I servizi che usano una porta assegnata dinamicamente devono usare questo middleware.Services that use a dynamically-assigned port should make use of this middleware.

I servizi che usano una porta fissa univoca non hanno questo problema in un ambiente collaborativo.Services that use a fixed unique port do not have this problem in a cooperative environment. Una porta fissa univoca viene in genere usata per i servizi esterni che richiedono una porta nota per la connessione delle applicazioni client.A fixed unique port is typically used for externally-facing services that need a well-known port for client applications to connect to. La maggior parte delle applicazioni Web per Internet, ad esempio, usa la porta 80 o 443 per connessioni tramite Web browser.For example, most Internet-facing web applications will use port 80 or 443 for web browser connections. In questo caso, l'identificatore univoco non deve essere abilitato.In this case, the unique identifier should not be enabled.

Il diagramma seguente illustra il flusso della richiesta con il middleware abilitato:The following diagram shows the request flow with the middleware enabled:

Integrazione ASP.NET Core di Service Fabric

Le implementazioni di ICommunicationListener di Kestrel e HttpSys usano questo meccanismo nello stesso identico modo.Both Kestrel and HttpSys ICommunicationListener implementations use this mechanism in exactly the same way. Anche se HttpSys può differenziare internamente le richieste in base a percorsi URL univoci usando la funzionalità di condivisione delle porte http.sys sottostante, questa funzionalità non viene usata dall'implementazione ICommunicationListener di HttpSys perché provocherebbe i codici di stato di errore HTTP 503 e HTTP 404 nello scenario descritto in precedenza.Although HttpSys can internally differentiate requests based on unique URL paths using the underlying http.sys port sharing feature, that functionality is not used by the HttpSys ICommunicationListener implementation because that will result in HTTP 503 and HTTP 404 error status codes in the scenario described earlier. Ciò rende a sua volta molto difficile per i client determinare la finalità dell'errore, perché i codici HTTP 503 e HTTP 404 sono già comunemente usati per indicare altri errori.That in turn makes it very difficult for clients to determine the intent of the error, as HTTP 503 and HTTP 404 are already commonly used to indicate other errors. Le implementazioni di ICommunicationListener di Kestrel e HttpSys vengono quindi standardizzate con il middleware fornito dal metodo di estensione UseServiceFabricIntegration, in modo che i client debbano solo eseguire nuovamente la risoluzione dell'endpoint del servizio nelle risposte HTTP 410.Thus, both Kestrel and HttpSys ICommunicationListener implementations standardize on the middleware provided by the UseServiceFabricIntegration extension method so that clients only need to perform a service endpoint re-resolve action on HTTP 410 responses.

HttpSys in Reliable ServicesHttpSys in Reliable Services

HttpSys può essere usato in un servizio Reliable Services importando il pacchetto NuGet Microsoft.ServiceFabric.AspNetCore.HttpSys.HttpSys can be used in a Reliable Service by importing the Microsoft.ServiceFabric.AspNetCore.HttpSys NuGet package. Questo pacchetto contiene HttpSysCommunicationListener, un'implementazione di ICommunicationListener, che consente di creare un WebHost ASP.NET Core all'interno di un servizio Reliable Services usando HttpSys come server Web.This package contains HttpSysCommunicationListener, an implementation of ICommunicationListener, that allows you to create an ASP.NET Core WebHost inside a Reliable Service using HttpSys as the web server.

HttpSys si basa sull'API server HTTP di Windows,HttpSys is built on the Windows HTTP Server API. che usa il driver del kernel http.sys usato da IIS per elaborare le richieste HTTP e indirizzarle ai processi che eseguono le applicazioni Web.This uses the http.sys kernel driver used by IIS to process HTTP requests and route them to processes running web applications. Ciò consente a più processi nello stesso computer fisico o nella stessa macchina virtuale di ospitare applicazioni Web sulla stessa porta, identificate senza ambiguità dal nome host o dal percorso URL univoco.This allows multiple processes on the same physical or virtual machine to host web applications on the same port, disambiguated by either a unique URL path or hostname. Queste funzionalità sono utili in Service Fabric per ospitare più siti Web nello stesso cluster.These features are useful in Service Fabric for hosting multiple websites in the same cluster.

Il diagramma seguente illustra il modo in cui HttpSys usa il driver del kernel http.sys in Windows per la condivisione delle porte:The following diagram illustrates how HttpSys uses the http.sys kernel driver on Windows for port sharing:

http.sys

HttpSys in un servizio senza statoHttpSys in a stateless service

Per usare HttpSys in un servizio senza stato, eseguire l'override del metodo CreateServiceInstanceListeners e restituire un'istanza HttpSysCommunicationListener:To use HttpSys in a stateless service, override the CreateServiceInstanceListeners method and return a HttpSysCommunicationListener instance:

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()))
    };
}

HttpSys in un servizio con statoHttpSys in a stateful service

HttpSysCommunicationListener non è attualmente progettato per l'uso in servizi con stato, a causa di problemi con la funzionalità di condivisione delle porte http.sys sottostante.HttpSysCommunicationListener is currently not designed for use in stateful services due to complications with the underlying http.sys port sharing feature. Per altre informazioni, vedere la sezione seguente sull'allocazione dinamica delle porte con HttpSys.For more information, see the following section on dynamic port allocation with HttpSys. Per i servizi con stato, Kestrel è il server Web consigliato.For stateful services, Kestrel is the recommended web server.

Configurazione dell'endpointEndpoint configuration

È necessaria una configurazione Endpoint per i server Web che usano l'API server HTTP di Windows, tra cui HttpSys.An Endpoint configuration is required for web servers that use the Windows HTTP Server API, including HttpSys. I server Web che usano l'API server HTTP di Windows devono prima riservare i rispettivi URL con http.sys. Questa operazione viene in genere eseguita con lo strumento netsh.Web servers that use the Windows HTTP Server API must first reserve their URL with http.sys (this is normally accomplished with the netsh tool). Questa azione richiede privilegi elevati che i servizi non hanno per impostazione predefinita.This action requires elevated privileges that your services by default do not have. Le opzioni "http" o "https" per la proprietà Protocol della configurazione Endpoint in ServiceManifest.xml vengono usate specificamente per indicare al runtime di Service Fabric di registrare un URL con http.sys per conto dell'utente con il prefisso URL con caratteri jolly complessi.The "http" or "https" options for the Protocol property of the Endpoint configuration in ServiceManifest.xml are used specifically to instruct the Service Fabric runtime to register a URL with http.sys on your behalf using the strong wildcard URL prefix.

Per riservare ad esempio http://+:80 per un servizio, è necessario usare la configurazione seguente in ServiceManifest.xml:For example, to reserve http://+:80 for a service, the following configuration should be used in ServiceManifest.xml:

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

</ServiceManifest>

Il nome dell'endpoint deve essere passato al costruttore HttpSysCommunicationListener:And the endpoint name must be passed to the HttpSysCommunicationListener constructor:

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

Usare HttpSys con una porta staticaUse HttpSys with a static port

Per usare una porta statica con HttpSys, specificare il numero della porta nella configurazione Endpoint:To use a static port with HttpSys, provide the port number in the Endpoint configuration:

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

Usare HttpSys con una porta dinamicaUse HttpSys with a dynamic port

Per usare una porta assegnata dinamicamente con HttpSys, omettere la proprietà Port nella configurazione Endpoint:To use a dynamically assigned port with HttpSys, omit the Port property in the Endpoint configuration:

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

Si noti che una porta dinamica allocata da una configurazione Endpoint fornisce una sola porta per ogni processo host.Note that a dynamic port allocated by an Endpoint configuration only provides one port per host process. Il modello di hosting corrente di Service Fabric consente l'hosting di più istanze e/o repliche del servizio nello stesso processo, vale a dire che ognuna condivide la stessa porta, se allocata tramite la configurazione Endpoint.The current Service Fabric hosting model allows multiple service instances and/or replicas to be hosted in the same process, meaning that each one will share the same port when allocated through the Endpoint configuration. Più istanze di HttpSys possono condividere una porta usando la funzionalità di condivisione delle porte http.sys sottostante, ma questa funzionalità non è supportata da HttpSysCommunicationListener a causa dei problemi che provoca per le richieste dei client.Multiple HttpSys instances can share a port using the underlying http.sys port sharing feature, but that is not supported by HttpSysCommunicationListener due to the complications it introduces for client requests. Per l'uso delle porte dinamiche, Kestrel è il server Web consigliato.For dynamic port usage, Kestrel is the recommended web server.

Kestrel in Reliable ServicesKestrel in Reliable Services

Kestrel può essere usato in un servizio Reliable Services importando il pacchetto NuGet Microsoft.ServiceFabric.AspNetCore.Kestrel.Kestrel can be used in a Reliable Service by importing the Microsoft.ServiceFabric.AspNetCore.Kestrel NuGet package. Questo pacchetto contiene KestrelCommunicationListener, un'implementazione di ICommunicationListener, che consente di creare un WebHost ASP.NET Core all'interno di un servizio Reliable Services usando Kestrel come server Web.This package contains KestrelCommunicationListener, an implementation of ICommunicationListener, that allows you to create an ASP.NET Core WebHost inside a Reliable Service using Kestrel as the web server.

Kestrel è che un server Web multipiattaforma per ASP.NET Core basato su libuv, una libreria I/O asincrona multipiattaforma.Kestrel is a cross-platform web server for ASP.NET Core based on libuv, a cross-platform asynchronous I/O library. A differenza di HttpSys, Kestrel non usa una gestione centralizzata dell'endpoint come http.sys.Unlike HttpSys, Kestrel does not use a centralized endpoint manager such as http.sys. A differenza di HttpSys, Kestrel non supporta la condivisione delle porte tra più processi.And unlike HttpSys, Kestrel does not support port sharing between multiple processes. Ogni istanza di Kestrel deve usare una porta univoca.Each instance of Kestrel must use a unique port.

kestrel

Kestrel in un servizio senza statoKestrel in a stateless service

Per usare Kestrel in un servizio senza stato, eseguire l'override del metodo CreateServiceInstanceListeners e restituire un'istanza KestrelCommunicationListener:To use Kestrel in a stateless service, override the CreateServiceInstanceListeners method and return a KestrelCommunicationListener instance:

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 in un servizio con statoKestrel in a stateful service

Per usare Kestrel in un servizio con stato, eseguire l'override del metodo CreateServiceReplicaListeners e restituire un'istanza KestrelCommunicationListener:To use Kestrel in a stateful service, override the CreateServiceReplicaListeners method and return a KestrelCommunicationListener instance:

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();
            ))
    };
}

In questo esempio viene fornita un'istanza singleton di IReliableStateManager al contenitore di inserimento delle dipendenze WebHost.In this example, a singleton instance of IReliableStateManager is provided to the WebHost dependency injection container. Questa operazione non è strettamente necessaria, ma consente di usare IReliableStateManager e Reliable Collections nei metodi di azione del controller MVC.This is not strictly necessary, but it allows you to use IReliableStateManager and Reliable Collections in your MVC controller action methods.

Si noti che non viene fornito un nome di configurazione Endpoint a KestrelCommunicationListener in un servizio con stato,Note that an Endpoint configuration name is not provided to KestrelCommunicationListener in a stateful service. come spiegato più dettagliatamente nella sezione seguente.This is explained in more detail in the following section.

Configurazione dell'endpointEndpoint configuration

Non è necessaria una configurazione Endpoint per usare Kestrel.An Endpoint configuration is not required to use Kestrel.

Kestrel è un server Web autonomo semplice e a differenza di HttpSys (o HttpListener) non necessita di una configurazione Endpoint in ServiceManifest.xml perché non richiede la registrazione dell'URL prima dell'avvio.Kestrel is a simple stand-alone web server; unlike HttpSys (or HttpListener), it does not need an Endpoint configuration in ServiceManifest.xml because it does not require URL registration prior to starting.

Usare Kestrel con una porta staticaUse Kestrel with a static port

È possibile definire una porta statica nella configurazione Endpoint di ServiceManifest.xml per l'uso con Kestrel.A static port can be configured in the Endpoint configuration of ServiceManifest.xml for use with Kestrel. Anche se non è strettamente necessaria, questa operazione offre due vantaggi potenziali:Although this is not strictly necessary, it provides two potential benefits:

  1. Se la porta non rientra nell'intervallo di porte dell'applicazione, verrà aperta da Service Fabric nel firewall del sistema operativo.If the port does not fall in the application port range, it is opened through the OS firewall by Service Fabric.
  2. L'URL fornito all'utente tramite KestrelCommunicationListener userà questa porta.The URL provided to you through KestrelCommunicationListener will use this port.
  <Resources>
    <Endpoints>
      <Endpoint Protocol="http" Name="ServiceEndpoint" Port="80" />
    </Endpoints>
  </Resources>

Se è configurato un Endpoint, il nome deve essere passato al costruttore KestrelCommunicationListener:If an Endpoint is configured, its name must be passed into the KestrelCommunicationListener constructor:

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

Se non viene usata una configurazione Endpoint, omettere il nome nel costruttore KestrelCommunicationListener.If an Endpoint configuration is not used, omit the name in the KestrelCommunicationListener constructor. In questo caso verrà usata una porta dinamica.In this case, a dynamic port will be used. Per altre informazioni, vedere la sezione seguente.See the next section for more information.

Usare Kestrel con una porta dinamicaUse Kestrel with a dynamic port

Kestrel non può usare l'assegnazione automatica delle porte della configurazione Endpoint in ServiceManifest.xml, perché l'assegnazione automatica delle porte di una configurazione Endpoint assegna una porta univoca per ogni processo host e un singolo processo host può contenere più istanze di Kestrel.Kestrel cannot use the automatic port assignment from the Endpoint configuration in ServiceManifest.xml, because automatic port assignment from an Endpoint configuration assigns a unique port per host process, and a single host process can contain multiple Kestrel instances. Poiché Kestrel non supporta la condivisione delle porte, questa modalità di assegnazione non funziona perché ogni istanza di Kestrel deve essere aperta in una porta univoca.Since Kestrel does not support port sharing, this does not work as each Kestrel instance must be opened on a unique port.

Per usare l'assegnazione dinamica delle porte con Kestrel è sufficiente omettere del tutto la configurazione Endpoint in ServiceManifest.xml e non passare un nome endpoint al costruttore KestrelCommunicationListener:To use dynamic port assignment with Kestrel, simply omit the Endpoint configuration in ServiceManifest.xml entirely, and do not pass an endpoint name to the KestrelCommunicationListener constructor:

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

In questa configurazione, KestrelCommunicationListener selezionerà automaticamente una porta non usata dall'intervallo di porte dell'applicazione.In this configuration, KestrelCommunicationListener will automatically select an unused port from the application port range.

Scenari e configurazioniScenarios and configurations

Questa sezione descrive gli scenari seguenti e offre la combinazione consigliata di server Web, configurazione delle porte, opzioni di integrazione di Service Fabric e altre impostazioni per ottenere un servizio che funzioni correttamente:This section describes the following scenarios and provides the recommended combination of web server, port configuration, Service Fabric integration options, and miscellaneous settings to achieve a properly functioning service:

  • Servizio ASP.NET Core senza stato esposto all'esternoExternally exposed ASP.NET Core stateless service
  • Servizio ASP.NET Core senza stato solo internoInternal-only ASP.NET Core stateless service
  • Servizio ASP.NET Core con stato solo internoInternal-only ASP.NET Core stateful service

Un servizio esposto all'esterno è un servizio che espone un endpoint raggiungibile dall'esterno del cluster, in genere tramite un servizio di bilanciamento del carico.An externally exposed service is one that exposes an endpoint reachable from outside the cluster, usually through a load balancer.

Un servizio solo interno è un servizio il cui endpoint è raggiungibile solo dall'interno del cluster.An internal-only service is one whose endpoint is only reachable from within the cluster.

Nota

Gli endpoint di servizio con stato non devono essere in genere esposti a Internet.Stateful service endpoints generally should not be exposed to the Internet. I cluster che si trovano dietro a servizi di bilanciamento del carico che non rilevano la risoluzione del servizio di Service Fabric, ad esempio Azure Load Balancer, non possono esporre i servizi con stato perché il servizio di bilanciamento del carico non può individuare e instradare il traffico alla replica del servizio con stato appropriata.Clusters that are behind load balancers that are unaware of Service Fabric service resolution, such as the Azure Load Balancer, will be unable to expose stateful services because the load balancer will not be able to locate and route traffic to the appropriate stateful service replica.

Servizi ASP.NET Core senza stato esposti all'esternoExternally exposed ASP.NET Core stateless services

Kestrel è il server Web consigliato per i servizi front-end che espongono endpoint HTTP Internet esterni.Kestrel is the recommended web server for front-end services that expose external, Internet-facing HTTP endpoints. In Windows HttpSys può essere usato per fornire la funzionalità di condivisione delle porte, che consente di ospitare più servizi Web sullo stesso set di nodi tramite la stessa porta, dove ogni servizio Web è differenziato per nome host o percorso senza basarsi su un proxy o gateway front-end per implementare un routing HTTP.On Windows, HttpSys may be used to provide port sharing capability which allows you to host multiple web services on the same set of nodes using the same port, differentiated by hostname or path, without relying on a front-end proxy or gateway to provide HTTP routing.

Quando è esposto a Internet, un servizio senza stato deve usare un endpoint noto e stabile raggiungibile tramite un servizio di bilanciamento del carico.When exposed to the Internet, a stateless service should use a well-known and stable endpoint that is reachable through a load balancer. Si tratta dell'URL che verrà fornito agli utenti dell'applicazione.This is the URL you will provide to users of your application. È consigliabile la configurazione seguente:The following configuration is recommended:

NoteNotes
Server WebWeb server KestrelKestrel Kestrel è il server Web preferito perché è supportato in Windows e Linux.Kestrel is the preferred web server as it is supported across Windows and Linux.
Configurazione delle portePort configuration Staticastatic È necessario configurare una porta statica nota nella configurazione Endpoints di ServiceManifest.xml, ad esempio 80 per HTTP o 443 per HTTPS.A well-known static port should be configured in the Endpoints configuration of ServiceManifest.xml, such as 80 for HTTP or 443 for HTTPS.
ServiceFabricIntegrationOptionsServiceFabricIntegrationOptions NoneNone È necessario usare l'opzione ServiceFabricIntegrationOptions.None quando si configura il middleware di integrazione di Service Fabric, in modo che il servizio non provi a convalidare le richieste in ingresso per un identificatore univoco.The ServiceFabricIntegrationOptions.None option should be used when configuring Service Fabric integration middleware so that the service does not attempt to validate incoming requests for a unique identifier. Gli utenti esterni dell'applicazione non saranno a conoscenza delle informazioni di identificazione univoche usate dal middleware.External users of your application will not know the unique identifying information used by the middleware.
Conteggio istanzeInstance Count -1-1 In casi d'uso tipici, l'impostazione del numero di istanze deve essere "-1" in modo che un'istanza sia disponibile in tutti i nodi che ricevono il traffico da un servizio di bilanciamento del carico.In typical use cases, the instance count setting should be set to "-1" so that an instance is available on all nodes that receive traffic from a load balancer.

Se più servizi esposti all'esterno condividono lo stesso set di nodi, HttpSys può essere usato con un percorso URL univoco ma stabile,If multiple externally exposed services share the same set of nodes, HttpSys can be used with a unique but stable URL path. modificando l'URL specificato durante la configurazione di IWebHost.This can be accomplished by modifying the URL provided when configuring IWebHost. Ciò è valido solo per HttpSys.Note this applies to HttpSys only.

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

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

Servizio ASP.NET Core senza stato solo internoInternal-only stateless ASP.NET Core service

I servizi senza stato che vengono chiamati solo dall'interno del cluster devono usare URL univoci e porte assegnate dinamicamente per assicurare la cooperazione tra più servizi.Stateless services that are only called from within the cluster should use unique URLs and dynamically assigned ports to ensure cooperation between multiple services. È consigliabile la configurazione seguente:The following configuration is recommended:

NoteNotes
Server WebWeb server KestrelKestrel Anche se è possibile usare HttpSys per i servizi interni senza stato, Kestrel è il server consigliato per consentire la condivisione di un host da parte di più istanze del servizio.Although HttpSys may be used for internal stateless services, Kestrel is the recommended server to allow multiple service instances to share a host.
Configurazione delle portePort configuration assegnate in modo dinamicodynamically assigned Più repliche di un servizio con stato possono condividere un processo host o un sistema operativo host e richiedono quindi porte univoche.Multiple replicas of a stateful service may share a host process or host operating system and thus will need unique ports.
ServiceFabricIntegrationOptionsServiceFabricIntegrationOptions UseUniqueServiceUrlUseUniqueServiceUrl Con l'assegnazione dinamica delle porte, questa impostazione evita il problema di errata identificazione descritto in precedenza.With dynamic port assignment, this setting prevents the mistaken identity issue described earlier.
InstanceCountInstanceCount qualsiasiany Il numero di istanze può essere impostato su qualsiasi valore necessario per il funzionamento del servizio.The instance count setting can be set to any value necessary to operate the service.

Servizio ASP.NET Core con stato solo internoInternal-only stateful ASP.NET Core service

I servizi con stato che vengono chiamati solo dall'interno del cluster devono usare porte assegnate dinamicamente per assicurare la cooperazione tra più servizi.Stateful services that are only called from within the cluster should use dynamically assigned ports to ensure cooperation between multiple services. È consigliabile la configurazione seguente:The following configuration is recommended:

NoteNotes
Server WebWeb server KestrelKestrel HttpSysCommunicationListener non può essere usato dai servizi con stato in cui le repliche condividono un processo host.The HttpSysCommunicationListener is not designed for use by stateful services in which replicas share a host process.
Configurazione delle portePort configuration assegnate in modo dinamicodynamically assigned Più repliche di un servizio con stato possono condividere un processo host o un sistema operativo host e richiedono quindi porte univoche.Multiple replicas of a stateful service may share a host process or host operating system and thus will need unique ports.
ServiceFabricIntegrationOptionsServiceFabricIntegrationOptions UseUniqueServiceUrlUseUniqueServiceUrl Con l'assegnazione dinamica delle porte, questa impostazione evita il problema di errata identificazione descritto in precedenza.With dynamic port assignment, this setting prevents the mistaken identity issue described earlier.

Passaggi successiviNext steps

Debug dell'applicazione di Service Fabric mediante Visual StudioDebug your Service Fabric application by using Visual Studio