Condividi tramite


.NET .NET Aspire panoramica della rete del ciclo interno

Uno dei vantaggi dello sviluppo con .NET.NET Aspire è che consente di sviluppare, testare ed eseguire il debug di app native del cloud in locale. La rete a ciclo interno è un aspetto chiave di .NET.NET Aspire che consente alle app di comunicare tra loro nell'ambiente di sviluppo. Questo articolo illustra come .NET.NET Aspire gestisce diversi scenari di rete con proxy, endpoint, configurazioni degli endpoint e profili di avvio.

Connessione nel ciclo interno

Il ciclo interno è il processo di sviluppo e test dell'app in locale prima di distribuirlo in un ambiente di destinazione. .NET .NET Aspire offre diversi strumenti e funzionalità per semplificare e migliorare l'esperienza di rete nel ciclo interno, ad esempio:

  • Profili di avvio: i profili di avvio sono file di configurazione che specificano come eseguire l'app in locale. È possibile usare i profili di avvio (ad esempio il file launchSettings.json) per definire gli endpoint, le variabili di ambiente e le impostazioni di avvio per l'app.
  • configurazione di Kestrel: la configurazione di Kestrel consente di specificare gli endpoint su cui il server Web Kestrel è in ascolto. È possibile configurare gli endpoint Kestrel nelle impostazioni dell'app e .NET.NET Aspire usa automaticamente queste impostazioni per creare gli endpoint.
  • Configurazioni degli endpoint: Gli endpoint sono le connessioni tra l'app e i servizi da cui dipende, come i database, le code di messaggi o le API. Gli endpoint forniscono informazioni quali il nome del servizio, la porta host, lo schema e la variabile di ambiente. È possibile aggiungere endpoint alla tua app in modo implicito (con profili di avvio) o in modo esplicito chiamando WithEndpoint.
  • Proxy: .NET.NET Aspire avvia automaticamente un proxy per ogni associazione di servizio aggiunta all'app e assegna una porta su cui il proxy può ascoltare. Il proxy inoltra quindi le richieste alla porta su cui l'app è in ascolto, che potrebbe essere diversa dalla porta proxy. In questo modo, è possibile evitare conflitti di porte e accedere all'app e ai servizi usando URL coerenti e prevedibili.

Funzionamento degli endpoint

Un'associazione di servizio in .NET.NET Aspire implica due integrazioni: un servizio che rappresenta una risorsa esterna richiesta dall'app (ad esempio, un database, una coda di messaggi o un'API) e un'associazione che stabilisce una connessione tra l'app e il servizio e fornisce le informazioni necessarie.

.NET .NET Aspire supporta due tipi di associazione di servizi: impliciti , creati automaticamente in base ai profili di avvio specificati che definiscono il comportamento dell'app in ambienti diversi e esplicita, creati manualmente usando WithEndpoint.

Quando si crea un collegamento, sia esso implicito o esplicito, .NET.NET Aspire avvia un proxy inverso leggero su una porta specificata, gestendo sia il routing che il bilanciamento del carico per le richieste dall'app al servizio. Il proxy è un .NET.NET Aspire dettaglio di implementazione, senza problemi di configurazione o gestione.

Per aiutare a visualizzare il funzionamento degli endpoint, prendere in considerazione il diagramma di rete del ciclo interno dei modelli di avvio .NET.NET Aspire.

.NET.NET Aspire diagramma di rete del ciclo interno del modello di applicazione iniziale.

Profili di avvio

** Quando chiami AddProject, l'host dell'applicazione cerca Proprietà/launchSettings.json per determinare il set predefinito di endpoint. L'host dell'app seleziona un profilo di avvio specifico usando le regole seguenti:

  1. Argomento esplicito launchProfileName passato al momento della chiamata di AddProject.
  2. Variabile di ambiente DOTNET_LAUNCH_PROFILE. Per altre informazioni, vedere .NET variabili di ambiente.
  3. Il primo profilo di avvio definito in launchSettings.json.

Considerare il file di launchSettings.json seguente:

{
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "profiles": {
    "http": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": false,
      "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "https": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
      "applicationUrl": "https://localhost:7239;http://localhost:5066",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

Per la parte restante di questo articolo, si supponga di aver creato un IDistributedApplicationBuilder assegnato a una variabile denominata builder con l'API CreateBuilder():

var builder = DistributedApplication.CreateBuilder(args);

Per specificare i profili di avvio http e https, configurare i valori di applicationUrl per entrambi nel file launchSettings.json. Questi URL vengono usati per creare endpoint per questo progetto. Questo è l'equivalente di:

builder.AddProject<Projects.Networking_Frontend>("frontend")
       .WithHttpEndpoint(port: 5066)
       .WithHttpsEndpoint(port: 7239);

Importante

Se non sono presenti launchSettings.json (o profilo di avvio), per impostazione predefinita non sono presenti associazioni.

Per ulteriori informazioni, vedere .NET.NET Aspire e i profili di avvio.

Endpoint configurato da Kestrel

.NET .NET Aspire supporta la configurazione dell'endpoint Kestrel. Si consideri ad esempio un file appsettings.json per un progetto che definisce un endpoint Kestrel con lo schema HTTPS e la porta 5271:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://*:5271"
      }
    }
  }
}

La configurazione precedente specifica un endpoint Https. La proprietà Url è impostata su https://*:5271, il che significa che l'endpoint è in ascolto su tutte le interfacce sulla porta 5271. Per ulteriori informazioni, vedere Configurare gli endpoint per il server web ASP.NET Core Kestrel.

Dopo la configurazione dell'endpoint Kestrel, il progetto deve rimuovere qualsiasi applicationUrl configurato dal file di launchSettings.json.

Nota

Se il applicationUrl è presente nel file launchSettings.json e l'endpoint Kestrel è configurato, l'host dell'app genererà un'eccezione.

Quando si aggiunge una risorsa di progetto, è presente un overload che consente di specificare che l'endpoint Kestrel deve essere usato invece del file launchSettings.json:

builder.AddProject<Projects.Networking_ApiService>(
    name: "apiservice",
    configure: static project =>
    {
        project.ExcludeLaunchProfile = true;
        project.ExcludeKestrelEndpoints = false;
    })
    .WithHttpsEndpoint();

Per altre informazioni, vedere AddProject.

Porte e proxy

Quando si definisce un'associazione al servizio, la porta host è sempre assegnata al proxy che si trova davanti al servizio. In questo modo è possibile che una o più repliche di un servizio si comportino in modo analogo. Inoltre, tutte le dipendenze delle risorse che usano l'API WithReference fanno affidamento sull'endpoint proxy fornito dalla variabile di ambiente.

Si consideri la catena di metodi seguente che chiama AddProject, WithHttpEndpointe quindi WithReplicas:

builder.AddProject<Projects.Networking_Frontend>("frontend")
       .WithHttpEndpoint(port: 5066)
       .WithReplicas(2);

Il codice precedente restituisce il diagramma di rete seguente:

.NET.NET Aspire diagramma di rete dell'app front-end con una porta host specifica e due repliche.

Il diagramma precedente illustra quanto segue:

  • Un Web browser come punto di ingresso per l'app.
  • Porta host 5066.
  • Proxy frontend interposto tra il browser web e le repliche del servizio frontend, in ascolto sulla porta 5066.
  • Il servizio replica frontend frontend_0 è in ascolto sulla porta assegnata in modo casuale 65001.
  • Replica del servizio frontend frontend_1 che ascolta sulla porta 65002 assegnata in modo casuale.

Senza la chiamata a WithReplicas, è presente un solo servizio frontend. Il proxy rimane in ascolto sulla porta 5066, ma il servizio front-end rimane in ascolto su una porta casuale:

builder.AddProject<Projects.Networking_Frontend>("frontend")
       .WithHttpEndpoint(port: 5066);

Sono definite due porte:

  • Porta host 5066.
  • Porta proxy casuale a cui verrà associato il servizio sottostante.

.NET.NET Aspire diagramma di rete dell'app front-end con porta specifica dell'host e porta casuale.

Il diagramma precedente illustra quanto segue:

  • Un Web browser come punto di ingresso per l'app.
  • Porta host 5066.
  • Proxy frontend situato tra il browser e il servizio frontend, in ascolto sulla porta 5066.
  • Il servizio front-end è in ascolto sulla porta 65001.

Il servizio sottostante viene alimentato da questa porta tramite ASPNETCORE_URLS per le risorse del progetto. Altre risorse accedono a questa porta specificando una variabile di ambiente nell'associazione al servizio:

builder.AddNpmApp("frontend", "../NodeFrontend", "watch")
       .WithHttpEndpoint(port: 5067, env: "PORT");

Il codice precedente rende disponibile la porta casuale nella variabile di ambiente PORT. L'app usa questa porta per ascoltare le connessioni in ingresso dal proxy. Si consideri il diagramma seguente:

.NET.NET Aspire diagramma di rete dell'app front-end con porta host e porta variabile di ambiente specifica.

Il diagramma precedente illustra quanto segue:

  • Un Web browser come punto di ingresso per l'app.
  • Porta host 5067.
  • Proxy front-end che funge da intermediario tra il browser web e il servizio front-end, in ascolto sulla porta 5067.
  • Servizio front-end in ascolto su un ambiente 65001.

Consiglio

Per evitare che un endpoint venga sottoposto a proxy, impostare la proprietà IsProxied su false quando si chiama il metodo di estensione WithEndpoint. Per altre informazioni, vedere estensioni endpoint : considerazioni aggiuntive.

Omettere la porta host

Quando si omette la porta host, .NET.NET Aspire genera una porta casuale sia per l'host che per la porta del servizio. Ciò è utile quando si vogliono evitare conflitti di porta e non importa la porta host o di servizio. Si consideri il codice seguente:

builder.AddProject<Projects.Networking_Frontend>("frontend")
       .WithHttpEndpoint();

In questo scenario le porte host e di servizio sono casuali, come illustrato nel diagramma seguente:

.NET.NET Aspire diagramma di rete dell'app front-end con porta host casuale e porta proxy.

Il diagramma precedente illustra quanto segue:

  • Un Web browser come punto di ingresso per l'app.
  • Una porta host casualmente assegnata di 65000.
  • Proxy frontend che si trova tra il browser web e il servizio frontend, che ascolta sulla porta 65000.
  • Il servizio front-end è in ascolto sulla porta 65001.

Porte del contenitore

Quando si aggiunge una risorsa contenitore, .NET.NET Aspire assegna automaticamente una porta casuale al contenitore. Per specificare una porta contenitore, configurare la risorsa contenitore con la porta desiderata:

builder.AddContainer("frontend", "mcr.microsoft.com/dotnet/samples", "aspnetapp")
       .WithHttpEndpoint(port: 8000, targetPort: 8080);

Il codice precedente:

  • Crea una risorsa contenitore denominata frontend, dall'immagine mcr.microsoft.com/dotnet/samples:aspnetapp.
  • Espone un endpoint http associando l'host alla porta 8000 e mappandolo alla porta 8080 del contenitore.

Si consideri il diagramma seguente:

.NET.NET Aspire diagramma di rete delle app front-end con un host Docker.

Metodi di estensione dell'endpoint

Qualsiasi risorsa che implementa l'interfaccia IResourceWithEndpoints può usare i metodi di estensione WithEndpoint. Esistono diverse modalità di overload di questa estensione, permettendo di specificare lo schema, la porta del contenitore, la porta host, il nome della variabile di ambiente e se l'endpoint è prossimato.

È anche disponibile un overload che consente di specificare un delegato per configurare l'endpoint. Ciò è utile quando è necessario configurare l'endpoint in base all'ambiente o ad altri fattori. Si consideri il codice seguente:

builder.AddProject<Projects.Networking_ApiService>("apiService")
       .WithEndpoint(
            endpointName: "admin",
            callback: static endpoint =>
       {
           endpoint.Port = 17003;
           endpoint.UriScheme = "http";
           endpoint.Transport = "http";
       });

Il codice precedente fornisce un delegato di callback per configurare l'endpoint. L'endpoint è denominato admin e configurato per l'uso dello schema e del trasporto http, e della porta host 17003. Il consumatore fa riferimento a questo endpoint in base al nome, considera la seguente chiamata AddHttpClient:

builder.Services.AddHttpClient<WeatherApiClient>(
    client => client.BaseAddress = new Uri("http://_admin.apiservice"));

Il Uri viene costruito usando il nome dell'endpoint admin preceduto dal _ sentinel. Si tratta di una convenzione per indicare che il segmento admin è il nome dell'endpoint appartenente al servizio apiservice. Per ulteriori informazioni, vedere .NET.NET Aspire individuazione del servizio.

Considerazioni aggiuntive

Quando si chiama il metodo di estensione WithEndpoint, l'overload callback espone il EndpointAnnotationnon elaborato, il che consente all'utente di personalizzare molti aspetti dell'endpoint.

La proprietà AllocatedEndpoint consente di ottenere o impostare l'endpoint per un servizio. Le proprietà IsExternal e IsProxied determinano il modo in cui l'endpoint viene gestito ed esposto: IsExternal decide se deve essere accessibile pubblicamente, mentre IsProxied garantisce che DCP lo gestisca, consentendo differenze di porta interne e replica.

Consiglio

Se ospiti un eseguibile esterno che gestisce il suo proxy e incontri problemi di associazione delle porte perché DCP ha già effettuato il binding della porta, prova a impostare la proprietà IsProxied su false. Ciò impedisce a DCP di gestire il proxy, consentendo all'eseguibile di associare correttamente la porta.

La proprietà Name identifica il servizio, mentre le proprietà Port e TargetPort specificano rispettivamente le porte desiderate e in ascolto.

Per la comunicazione di rete, la proprietà Protocol supporta TCP e UDP, con un potenziale maggiore in futuro e la proprietà Transport indica il protocollo di trasporto (HTTP, HTTP2, HTTP3). Infine, se il servizio è indirizzabile dall'URI, la proprietà UriScheme fornisce lo schema URI per la costruzione dell'URI del servizio.

Per ulteriori informazioni, consultare le proprietà disponibili di EndpointAnnotation .

Filtraggio degli endpoint

Tutti gli endpoint delle risorse di progetto .NET.NET Aspire seguono un set di euristiche predefinite. Alcuni endpoint sono inclusi in ASPNETCORE_URLS in fase di esecuzione, alcuni sono esposti come HTTP/HTTPS_PORTSe alcune configurazioni vengono risolte dalla configurazione di Kestrel. Indipendentemente dal comportamento predefinito, è possibile filtrare gli endpoint inclusi nelle variabili di ambiente usando il metodo di estensione WithEndpointsInEnvironment:

builder.AddProject<Projects.Networking_ApiService>("apiservice")
    .WithHttpsEndpoint() // Adds a default "https" endpoint
    .WithHttpsEndpoint(port: 19227, name: "admin")
    .WithEndpointsInEnvironment(
        filter: static endpoint =>
        {
            return endpoint.Name is not "admin";
        });

Il codice precedente aggiunge un endpoint HTTPS predefinito, nonché un endpoint admin sulla porta 19227. Tuttavia, l'endpoint admin viene escluso dalle variabili di ambiente. Ciò è utile quando si vuole esporre un endpoint solo per uso interno.