.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.
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:
- Argomento esplicito
launchProfileName
passato al momento della chiamata diAddProject
. - Variabile di ambiente
DOTNET_LAUNCH_PROFILE
. Per altre informazioni, vedere .NET variabili di ambiente. - 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:
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.
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:
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:
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'immaginemcr.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:
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_PORTS
e 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.