.NET .NET Aspire visão geral da rede de circuito interno
Uma das vantagens de desenvolver com .NET.NET Aspire é que ele permite que você desenvolva, teste e depure aplicativos nativos de nuvem localmente. A rede de ciclo interno é um aspecto fundamental do .NET.NET Aspire que permite a comunicação entre seus aplicativos no ambiente de desenvolvimento. Neste artigo, você aprenderá como .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.
Conectividade 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 aprimorar a experiência de rede no loop interno, como:
- perfis de inicialização: os perfis de inicialização são arquivos de configuração que especificam como executar seu aplicativo localmente. Você pode usar perfis de inicialização (como o launchSettings.json arquivo) para definir os pontos de extremidade, as variáveis de ambiente e as configurações de inicialização do aplicativo.
- de configuração do Kestrel: a configuração do Kestrel permite que você especifique os pontos de extremidade que o server web do Kestrel escuta. Você pode configurar endpoints Kestrel nas configurações do aplicativo, e .NET.NET Aspire usa automaticamente essas configurações para criar endpoints.
- configurações de pontos de extremidade/ponto de extremidade: pontos de extremidade são as conexões entre seu aplicativo e os serviços dos quais ele 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 endpoints ao seu aplicativo, seja 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 que você adiciona ao seu aplicativo e atribui uma porta para o proxy escutar. Em seguida, o proxy encaminha as solicitações para a porta em que seu aplicativo escuta, o 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 pontos de extremidade
Uma associação de serviço em .NET.NET Aspire envolve duas integrações: um serviço que representa um recurso externo que seu aplicativo requer (por exemplo, um banco de dados, fila de mensagens ou API) e uma associação que estabelece uma conexão entre seu aplicativo e o serviço e fornece as informações necessárias.
.NET .NET Aspire dá suporte a dois tipos de associação de serviço: implícito, criados automaticamente com base em perfis de inicialização especificados que definem o comportamento do aplicativo em ambientes diferentes e explícitas, criados manualmente usando WithEndpoint.
Ao estabelecer uma ligação, implícita ou explícita, .NET.NET Aspire inicia um proxy reverso ligeiro em uma porta especificada, fazendo o roteamento e balanceamento de carga para as solicitações do seu aplicativo ao serviço. O proxy é um .NET.NET Aspire detalhe de implementação que não exige nenhuma preocupação com configuração ou gerenciamento.
Para ajudar a visualizar como os pontos de extremidade funcionam, considere o diagrama de rede de ciclo interno dos templates iniciais .NET.NET Aspire:
Perfis de inicialização
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 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 nas configurações de lançamento .json.
Considere o seguinte arquivo de configurações de lançamento .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 uma IDistributedApplicationBuilder atribuída 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 de applicationUrl
para ambos no arquivo launchSettingsjson. Essas URLs são usadas para criar endpoints para este projeto. Isso é 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 há associações por padrão.
Para obter mais informações, consulte .NET.NET Aspire e perfis de inicialização.
Configurações de pontos de extremidade do Kestrel
.NET .NET Aspire dá suporte à configuração de endpoint Kestrel. Por exemplo, considere um appsettings.json arquivo para um projeto que define um ponto de extremidade Kestrel com o esquema HTTPS e a porta 5271:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"Kestrel": {
"Endpoints": {
"Https": {
"Url": "https://*:5271"
}
}
}
}
A configuração anterior especifica um endpoint Https
. A propriedade Url
é definida como https://*:5271
, o que significa que o endpoint escuta em todas as interfaces na porta 5271. Para obter mais informações, consulte serverweb do Kestrel.
Com o endpoint Kestrel configurado, o projeto deve remover qualquer applicationUrl
configurado do arquivo de launchSettings json.
Nota
Se o applicationUrl
estiver presente no arquivo launchSettingsjson e o ponto de extremidade Kestrel estiver configurado, o host do aplicativo gerará uma exceção.
Quando você adiciona um recurso de projeto, existe 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 associação de serviço, a porta de host é sempre fornecida ao proxy que fica na frente do serviço. Isso permite que réplicas simples ou múltiplas de um serviço se comportem da mesma forma. Além disso, todas as dependências de recursos que usam a API WithReference dependem no endpoint proxy da variável de ambiente.
Considere a cadeia de métodos a seguir 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 ilustra o seguinte:
- Um navegador da Web como um ponto de entrada para o aplicativo.
- Uma porta de host 5066.
- O proxy de front-end posicionado entre o navegador da web e as réplicas do serviço de front-end, ouvindo na porta 5066.
- A réplica do serviço de front-end
frontend_0
ouvindo a porta 65001 atribuída aleatoriamente. - A réplica de serviço frontend
frontend_1
ouvindo na porta 65002 atribuída aleatoriamente.
Sem a chamada para WithReplicas
, há apenas um serviço de front-end. 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);
Há duas portas definidas:
- Uma porta de host 5066.
- Uma porta proxy aleatória à qual o serviço subjacente será associado.
O diagrama anterior ilustra o seguinte:
- Um navegador da Web como um ponto de entrada para o aplicativo.
- Uma porta de host 5066.
- O proxy de front-end situado entre o navegador da web e o serviço de front-end, monitorando a porta 5066.
- O serviço de front-end está escutando em uma porta atribuída aleatoriamente, como 65001.
O serviço subjacente recebe esta porta através do ASPNETCORE_URLS
para recursos do projeto. Outros recursos acessam essa porta especificando uma variável de ambiente na associação de serviço:
builder.AddNpmApp("frontend", "../NodeFrontend", "watch")
.WithHttpEndpoint(port: 5067, env: "PORT");
O código anterior disponibiliza a porta aleatória na variável de ambiente PORT
. O aplicativo usa essa porta para ouvir conexões de entrada do proxy. Considere o seguinte diagrama:
O diagrama anterior ilustra o seguinte:
- Um navegador da Web como um ponto de entrada para o aplicativo.
- Uma porta de host 5067.
- O proxy de front-end posicionado entre o navegador da web e o serviço de front-end, ouvindo na porta 5067.
- O serviço de front-end está escutando em um ambiente 65001.
Dica
Para evitar que um ponto de extremidade seja proxie, defina a propriedade IsProxied
para false
ao chamar o método de extensão WithEndpoint
. Para obter mais informações, consulte extensões de ponto de extremidade: considerações adicionais.
Omita a porta do host
Quando você omite a porta de host, .NET.NET Aspire gera uma porta aleatória para a porta de host e 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 ilustra o seguinte:
- Um navegador da Web como um ponto de entrada para o aplicativo.
- Uma porta de host aleatória de 65000.
- O proxy de front-end localizado entre o navegador da Web e o serviço de front-end, monitorando na porta 65000.
- O serviço de front-end escutando em uma porta aleatória de 65001.
Portas de contêiner
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
, da imagemmcr.microsoft.com/dotnet/samples:aspnetapp
. - Expõe um ponto de extremidade
http
associando o host à porta 8000 e mapeando-o para a porta 8080 do contêiner.
Considere o seguinte diagrama:
Métodos de extensões de endpoints
Qualquer recurso que implemente a interface IResourceWithEndpoints pode usar os métodos de extensão WithEndpoint
. Existem várias versões dessa extensão, permitindo que você especifique o esquema, a porta do contêiner, a porta do host, o nome da variável de ambiente e se o endpoint está configurado como proxy.
Há também uma sobrecarga que permite que você especifique 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 para configurar o endpoint. O endpoint é nomeado admin
e configurado para usar o esquema e o transporte http
, assim como a porta do host 17003. O consumidor faz referência a este endpoint pelo nome, considere 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 de extremidade admin
prefixado com o sentinela _
. Essa é uma convenção para indicar que o segmento admin
é o nome do ponto de extremidade que pertence ao serviço apiservice
. Para obter mais informações, consulte a descoberta de serviço .NET.NET Aspire.
Considerações adicionais
Ao chamar o método de extensão WithEndpoint
, a sobrecarga de callback
expõe a versão bruta de EndpointAnnotation, permitindo ao consumidor personalizar muitos elementos do endpoint.
A propriedade AllocatedEndpoint
permite que você obtenha ou defina 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 internas de porta 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á ter vinculado a porta, tente ajustar a propriedade IsProxied
para false
. Isso impede que o DCP gerencie o proxy, permitindo que o executável associe 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
dá suporte a 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 das propriedades EndpointAnnotation.
Filtragem de ponto de extremidade
Todos os pontos finais de recursos do projeto .NET.NET Aspire seguem um conjunto de heurísticas padrão. Alguns pontos de extremidade são incluídos em ASPNETCORE_URLS
em tempo de execução, alguns são publicados como HTTP/HTTPS_PORTS
e algumas configurações são resolvidas a partir das configurações do Kestrel. Independentemente do comportamento padrão, você pode filtrar os pontos de extremidade incluídos em 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. Isso é útil quando você deseja expor um ponto de extremidade somente para uso interno.