.NET .NET Aspire visão geral da conectividade em circuito interno
Uma das vantagens de desenvolver com o .NET.NET Aspire é que ele permite desenvolver, testar e depurar aplicativos nativos da nuvem localmente. A rede de circuito interno é um aspeto fundamental do .NET.NET Aspire que permite que as suas aplicações comuniquem entre si no seu ambiente de desenvolvimento. Neste artigo, você aprenderá como o .NET.NET Aspire lida com vários cenários de rede com proxies, pontos de extremidade, configurações de ponto de extremidade e perfis de inicialização.
Conexão em rede no loop interno
O loop interno é o processo de desenvolver e testar seu aplicativo localmente antes de implantá-lo em um ambiente de destino. .NET .NET Aspire fornece várias ferramentas e recursos para simplificar e melhorar a experiência de rede no loop interno, tais como:
- Perfis de lançamento: Os perfis de lançamento são arquivos de configuração que especificam como executar a sua aplicação localmente. Você pode usar perfis de inicialização (como o arquivo launchSettings.json) para definir os pontos de extremidade, variáveis de ambiente e configurações de inicialização para seu aplicativo.
- configuração do Kestrel: A configuração do Kestrel permite especificar os endereços nos quais o servidor Web Kestrel ouve. Você pode configurar pontos de extremidade Kestrel nas configurações do seu aplicativo e .NET.NET Aspire usa automaticamente essas configurações para criar pontos de extremidade.
- Configurações de Endpoints/Pontos de Extremidade: Os pontos de extremidade são as conexões entre o seu aplicativo e os serviços dos quais este depende, como bancos de dados, filas de mensagens ou APIs. Os pontos de extremidade fornecem informações como o nome do serviço, a porta do host, o esquema e a variável de ambiente. Você pode adicionar pontos de extremidade à sua aplicação implicitamente (por meio de perfis de inicialização) ou explicitamente chamando WithEndpoint.
- Proxies: .NET.NET Aspire inicia automaticamente um proxy para cada associação de serviço adicionada ao seu aplicativo e atribui uma porta para o proxy escutar. Em seguida, o proxy encaminha as solicitações para a porta na qual seu aplicativo escuta, que pode ser diferente da porta proxy. Dessa forma, você pode evitar conflitos de porta e acessar seu aplicativo e serviços usando URLs consistentes e previsíveis.
Como funcionam os endpoints
Uma associação de serviço no .NET.NET Aspire envolve duas integrações: um serviço de que representa um recurso externo que a sua aplicação requer (por exemplo, um banco de dados, fila de mensagens ou API) e uma vinculação de que estabelece uma conexão entre a sua aplicação e o serviço e fornece as informações necessárias.
.NET .NET Aspire suporta dois tipos de vinculação de serviço: implícito, criado automaticamente com base em perfis de inicialização especificados que definem o comportamento do aplicativo em ambientes diferentes, e explícito , criado manualmente usando WithEndpoint.
Ao criar uma ligação, implícita ou explícita, o .NET.NET Aspire inicia um proxy reverso leve em uma porta especificada, manipulando o roteamento e o balanceamento de carga para solicitações do seu aplicativo para o serviço. O proxy é um detalhe de implementação .NET.NET Aspire, não exigindo nenhuma preocupação de configuração ou gerenciamento.
Para ajudar a visualizar como os pontos de extremidade funcionam, considere o diagrama de rede de loop interno dos modelos de início .NET.NET Aspire:
Perfis de lançamento
Quando você chama AddProject, o host do aplicativo procura Propriedades/launchSettings.json para determinar o conjunto padrão de pontos de extremidade. O host do aplicativo seleciona um perfil de inicialização específico usando as seguintes regras:
- Um argumento
launchProfileName
explícito foi passado ao chamarAddProject
. - A variável de ambiente
DOTNET_LAUNCH_PROFILE
. Para obter mais informações, consulte .NET variáveis de ambiente. - O primeiro perfil de lançamento definido em launchSettings.json.
Considere o seguinte arquivo launchSettings.json:
{
"$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"
}
}
}
}
Para o restante deste artigo, imagine que você criou um IDistributedApplicationBuilder atribuído a uma variável chamada builder
com a API CreateBuilder():
var builder = DistributedApplication.CreateBuilder(args);
Para especificar os perfis de inicialização http e https, configure os valores applicationUrl
para ambos no arquivo launchSettings.json. Estas URLs são utilizadas para criar endpoints para este projeto. Isto é o equivalente a:
builder.AddProject<Projects.Networking_Frontend>("frontend")
.WithHttpEndpoint(port: 5066)
.WithHttpsEndpoint(port: 7239);
Importante
Se não houver launchSettings.json (ou perfil de inicialização), não haverá associações por padrão.
Para obter mais informações, consulte .NET.NET Aspire e iniciar perfis.
Endpoints configurados do Kestrel
.NET .NET Aspire suporta a configuração do endpoint Kestrel. Por exemplo, considere um arquivo appsettings.json para um projeto que define um endpoint Kestrel com o protocolo HTTPS e a porta 5271.
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"Kestrel": {
"Endpoints": {
"Https": {
"Url": "https://*:5271"
}
}
}
}
A configuração anterior especifica o ponto de extremidade Https
. A propriedade Url
é definida como https://*:5271
, o que significa que a extremidade ouve em todas as interfaces na porta 5271. Para obter mais informações, consulte Configurar pontos de extremidade para o servidor Web ASP.NET Core Kestrel.
Com o endpoint do Kestrel configurado, o projeto deve remover qualquer configuração de applicationUrl
do arquivo launchSettings.json.
Observação
Se o applicationUrl
estiver presente no ficheiro launchSettings.json e o ponto de extremidade Kestrel estiver configurado, o host da aplicação gerará uma exceção.
Quando você adiciona um recurso de projeto, há uma sobrecarga que permite especificar que o ponto de extremidade Kestrel deve ser usado em vez do arquivo launchSettings.json:
builder.AddProject<Projects.Networking_ApiService>(
name: "apiservice",
configure: static project =>
{
project.ExcludeLaunchProfile = true;
project.ExcludeKestrelEndpoints = false;
})
.WithHttpsEndpoint();
Para obter mais informações, consulte AddProject.
Portas e proxies
Ao definir uma ligação de serviço, a porta do host é sempre dada ao proxy que fica na frente do serviço. Isso permite que uma ou várias réplicas de um serviço se comportem de forma semelhante. Além disso, todas as dependências de recursos que usam a API WithReference dependem do endpoint proxy da variável de ambiente.
Considere a seguinte cadeia de métodos que chama AddProject, WithHttpEndpointe, em seguida, WithReplicas:
builder.AddProject<Projects.Networking_Frontend>("frontend")
.WithHttpEndpoint(port: 5066)
.WithReplicas(2);
O código anterior resulta no seguinte diagrama de rede:
O diagrama anterior mostra o seguinte:
- Um navegador da Web como ponto de entrada para o aplicativo.
- Uma porta anfitriã de 5066.
- O proxy frontend que fica entre o navegador da Web e as réplicas do serviço frontend, escutando na porta 5066.
- A réplica do serviço de front-end
frontend_0
escuta na porta 65001 atribuída aleatoriamente. - A réplica do serviço frontend
frontend_1
está a ouvir na porta 65002, atribuída aleatoriamente.
Sem a chamada para WithReplicas
, há apenas um serviço de frontend. O proxy ainda escuta na porta 5066, mas o serviço de front-end escuta em uma porta aleatória:
builder.AddProject<Projects.Networking_Frontend>("frontend")
.WithHttpEndpoint(port: 5066);
Existem duas portas definidas:
- Uma porta anfitriã de 5066.
- Uma porta proxy aleatória à qual o serviço subjacente será vinculado.
O diagrama anterior mostra o seguinte:
- Um navegador da Web como ponto de entrada para o aplicativo.
- Uma porta anfitriã de 5066.
- O proxy frontend situado entre o navegador da Web e o serviço frontend, escutando na porta 5066.
- O serviço de frontend está a escutar numa porta aleatória, especificamente 65001.
O serviço subjacente é alimentado com essa porta via ASPNETCORE_URLS
para recursos do projeto. Outros recursos acessam essa porta especificando uma variável de ambiente na ligação de serviço:
builder.AddNpmApp("frontend", "../NodeFrontend", "watch")
.WithHttpEndpoint(port: 5067, env: "PORT");
O código anterior torna a porta aleatória disponível na variável de ambiente PORT
. O aplicativo usa essa porta para ouvir as conexões de entrada do proxy. Considere o seguinte diagrama:
O diagrama anterior mostra o seguinte:
- Um navegador da Web como ponto de entrada para o aplicativo.
- A porta do host 5067.
- O proxy frontend situado entre o navegador da Web e o serviço frontend, escutando na porta 5067.
- O serviço frontend escutando em um ambiente 65001.
Dica
Para evitar que um ponto de extremidade passe por proxy, defina a propriedade IsProxied
como false
ao chamar o método de extensão WithEndpoint
. Para mais informações, consulte extensões do ponto final: considerações adicionais.
Omitir porta do anfitrião
Quando você omite a porta do host, .NET.NET Aspire gera uma porta aleatória para a porta do host e da porta de serviço. Isso é útil quando você deseja evitar conflitos de porta e não se importa com o host ou a porta de serviço. Considere o seguinte código:
builder.AddProject<Projects.Networking_Frontend>("frontend")
.WithHttpEndpoint();
Nesse cenário, as portas de host e de serviço são aleatórias, conforme mostrado no diagrama a seguir:
O diagrama anterior mostra o seguinte:
- Um navegador da Web como ponto de entrada para o aplicativo.
- Uma porta de host aleatória de 65000.
- O proxy frontend situado entre o navegador da Web e o serviço frontend, escutando na porta 65000.
- O serviço de frontend escutando em uma porta aleatória de 65001.
Portos de contentores
Quando você adiciona um recurso de contêiner, .NET.NET Aspire atribui automaticamente uma porta aleatória ao contêiner. Para especificar uma porta de contêiner, configure o recurso de contêiner com a porta desejada:
builder.AddContainer("frontend", "mcr.microsoft.com/dotnet/samples", "aspnetapp")
.WithHttpEndpoint(port: 8000, targetPort: 8080);
O código anterior:
- Cria um recurso de contêiner chamado
frontend
, a partir da imagemmcr.microsoft.com/dotnet/samples:aspnetapp
. - Expõe um ponto de extremidade
http
vinculando o host à porta 8000 e mapeando-o para a porta 8080 do contêiner.
Considere o seguinte diagrama:
Métodos de extensão de endpoint
Qualquer recurso que implemente a interface IResourceWithEndpoints pode usar os métodos de extensão WithEndpoint
. Há várias sobrecargas dessa extensão, permitindo que si especifique o esquema, a porta do contêiner, a porta do host, o nome da variável de ambiente e se o ponto de extremidade está protegido por proxy.
Existe também uma sobrecarga que permite especificar um delegado para configurar o endpoint. Isso é útil quando você precisa configurar o ponto de extremidade com base no ambiente ou em outros fatores. Considere o seguinte código:
builder.AddProject<Projects.Networking_ApiService>("apiService")
.WithEndpoint(
endpointName: "admin",
callback: static endpoint =>
{
endpoint.Port = 17003;
endpoint.UriScheme = "http";
endpoint.Transport = "http";
});
O código anterior fornece um delegado de callback para configurar o endpoint. O ponto de extremidade é denominado admin
e configurado para usar o esquema de http
e transporte, bem como a porta do host 17003. O consumidor faz referência a este endpoint pelo nome, veja a seguinte chamada AddHttpClient
:
builder.Services.AddHttpClient<WeatherApiClient>(
client => client.BaseAddress = new Uri("http://_admin.apiservice"));
O Uri
é construído usando o nome do ponto final admin
prefixado com o sentinela _
. Esta é uma convenção para indicar que admin
é o nome de endpoint pertencente ao serviço apiservice
. Para obter mais informações, consulte .NET.NET Aspire descoberta de serviço.
Considerações adicionais
Ao chamar o método de extensão WithEndpoint
, a sobrecarga de callback
expõe o EndpointAnnotationbruto, o que permite ao consumidor personalizar muitos aspetos do endpoint.
A propriedade AllocatedEndpoint
permite obter ou definir o ponto de extremidade para um serviço. As propriedades IsExternal
e IsProxied
determinam como o ponto de extremidade é gerenciado e exposto: IsExternal
decide se ele deve ser acessível publicamente, enquanto IsProxied
garante que o DCP o gerencie, permitindo diferenças de porta interna e replicação.
Dica
Se você estiver hospedando um executável externo que executa seu próprio proxy e encontrar problemas de vinculação de porta devido ao DCP já vincular a porta, tente definir a propriedade IsProxied
como false
. Isso impede que o DCP gerencie o proxy, permitindo que seu executável vincule a porta com êxito.
A propriedade Name
identifica o serviço, enquanto as propriedades Port
e TargetPort
especificam as portas desejadas e de escuta, respectivamente.
Para comunicação de rede, a propriedade Protocol
suporta TCP e UDP, com potencial para mais no futuro, e a propriedade Transport
indica o protocolo de transporte (HTTP, HTTP2, HTTP3). Por fim, se o serviço for endereçável por URI, a propriedade UriScheme
fornecerá o esquema de URI para construir o URI de serviço.
Para obter mais informações, consulte as propriedades disponíveis de EndpointAnnotation .
Filtragem de pontos finais
Todos os pontos de extremidade de recursos .NET.NET Aspire projeto seguem um conjunto de heurísticas padrão. Alguns endpoints são incluídos em ASPNETCORE_URLS
durante o tempo de execução, alguns são publicados como HTTP/HTTPS_PORTS
, e algumas configurações são resolvidas a partir da configuração do Kestrel. Independentemente do comportamento padrão, você pode filtrar os pontos de extremidade incluídos nas variáveis de ambiente usando o método de extensão 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";
});
O código anterior adiciona um ponto de extremidade HTTPS padrão, bem como um ponto de extremidade admin
na porta 19227. No entanto, o ponto de extremidade admin
é excluído das variáveis de ambiente. Isto é útil quando desejas expor um ponto de extremidade apenas para uso interno.