Compartir a través de


Introducción a las redes de bucle interno .NET.NET Aspire

Una de las ventajas de desarrollar con .NET.NET Aspire es que permite desarrollar, probar y depurar aplicaciones nativas de nube localmente. Las redes de bucle interno son un aspecto clave de .NET.NET Aspire que permite que las aplicaciones se comuniquen entre sí en el entorno de desarrollo. En este artículo, obtendrá información sobre cómo .NET.NET Aspire controla varios escenarios de red con servidores proxy, puntos de conexión, configuraciones de punto de conexión e perfiles de inicio.

Redes en el bucle interno

El bucle interno es el proceso de desarrollar y probar la aplicación localmente antes de implementarla en un entorno de destino. .NET .NET Aspire proporciona varias herramientas y características para simplificar y mejorar la experiencia de red en el bucle interno, como:

  • Perfiles de inicio: los perfiles de inicio son archivos de configuración que especifican cómo ejecutar la aplicación localmente. Puede usar perfiles de inicio (como el launchSettings.json archivo) para definir los puntos de conexión, las variables de entorno y la configuración de inicio de la aplicación.
  • configuración de Kestrel: la configuración de Kestrel permite especificar los puntos de conexión en los que escucha la server web de Kestrel. Puede configurar los puntos de conexión de Kestrel en la configuración de la aplicación y .NET.NET Aspire usa automáticamente estas opciones para crear puntos de conexión.
  • Puntos de conexión/Configuraciones de punto de conexión: Los puntos de conexión son las conexiones entre tu aplicación y los servicios de los que depende, como bases de datos, colas de mensajes o API. Los puntos de conexión proporcionan información como el nombre del servicio, el puerto de host, el esquema y la variable de entorno. Puede agregar puntos de conexión a tu aplicación implícitamente (a través de perfiles de inicio) o explícitamente llamando a WithEndpoint.
  • Servidores proxy: .NET.NET Aspire inicia automáticamente un proxy para cada enlace de servicio que agregas a tu aplicación y asigna un puerto para que el proxy escuche. Luego, el proxy reenvía las solicitudes al puerto en el que escucha tu aplicación, que puede ser diferente al puerto del proxy. De este modo, puedes evitar conflictos de puertos y acceder a la aplicación y los servicios mediante direcciones URL coherentes y predecibles.

Funcionamiento de los puntos de conexión

Un enlace de servicio en .NET.NET Aspire implica dos integraciones: un servicio de que representa un recurso externo que requiere la aplicación (por ejemplo, una base de datos, una cola de mensajes o una API) y un enlace que establece una conexión entre la aplicación y el servicio y proporciona información necesaria.

.NET .NET Aspire admite dos tipos de enlace de servicio: implícitos , creados automáticamente en función de los perfiles de inicio especificados que definen el comportamiento de la aplicación en distintos entornos y explícito, creado manualmente mediante WithEndpoint.

Al crear un enlace, ya sea implícito o explícito, .NET.NET Aspire inicia un proxy inverso ligero en un puerto especificado, controlando el enrutamiento y el equilibrio de carga para las solicitudes de la aplicación al servicio. El proxy es un .NET.NET Aspire detalle de implementación y no requiere ninguna preocupación de configuración o administración.

Para ayudar a visualizar cómo funcionan los endpoints, considere el diagrama de redes de las plantillas de inicio de bucle interno .NET.NET Aspire.

Diagrama de red de ciclo interno de plantilla de aplicación de inicio .NET.NET Aspire.

Perfiles de lanzamiento

Al llamar a AddProject, el host de la aplicación busca Propiedades/launchSettings.json para determinar el conjunto predeterminado de puntos de conexión. El host de la aplicación selecciona un perfil de inicio específico mediante las siguientes reglas:

  1. Argumento de launchProfileName explícito pasado al llamar a AddProject.
  2. Variable de entorno DOTNET_LAUNCH_PROFILE. Para obtener más información, consulte .NET variables de entorno.
  3. Primer perfil de inicio definido en launchSettings.json.

Tenga en cuenta los siguientes launchSettings.json archivo:

{
  "$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"
      }
    }
  }
}

En el resto de este artículo, imagina que has creado un IDistributedApplicationBuilder asignado a una variable llamada builder usando la API CreateBuilder().

var builder = DistributedApplication.CreateBuilder(args);

Para especificar los perfiles de inicio de http y https, configure los valores de applicationUrl para ambos en el archivo launchSettings de .json archivo. Estas direcciones URL se usan para crear puntos de conexión para este proyecto. Este es el equivalente de:

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

Importante

Si no hay ningún launchSettings.json (o perfil de inicio), no hay vinculaciones por defecto.

Para obtener más información, vea .NET.NET Aspire y lanzar perfiles.

Puntos de conexión configurados de Kestrel

.NET .NET Aspire admite la configuración de endpoints de Kestrel. Por ejemplo, considere el archivo appsettings.json de un proyecto que define un punto de conexión de Kestrel con el esquema HTTPS y el puerto 5271.

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

La configuración anterior especifica un punto de conexión Https. La propiedad Url se establece en https://*:5271, lo que significa que el punto de conexión escucha en todas las interfaces del puerto 5271. Para obtener más información, consulte Configurar los puntos de conexión para el ASP.NET Core Kestrel web server.

Con el punto de conexión de Kestrel configurado, el proyecto debe quitar cualquier applicationUrl configurado del archivo de launchSettings.json.

Nota

Si el applicationUrl está presente en el launchSettings.json archivo y el punto de conexión Kestrel está configurado, el host de la aplicación producirá una excepción.

Al agregar un recurso de proyecto, hay una sobrecarga que le permite especificar que se debe usar el punto de conexión de Kestrel en lugar del archivo de configuración de inicio json.

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

Para obtener más información, consulte AddProject.

Puertos y servidores proxy

Al definir un enlace de servicio, el puerto host se siempre se asigna al proxy que se encuentra delante del servicio. Esto permite que una o varias réplicas de un servicio se comporten de forma similar. Además, todas las dependencias de recursos que usan la API de WithReference dependen del punto de conexión de proxy desde la variable de entorno.

Tenga en cuenta la siguiente cadena de métodos que llama a AddProject, WithHttpEndpointy, a continuación, WithReplicas:

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

El código anterior da como resultado el siguiente diagrama de redes:

.NET.NET Aspire diagrama de redes de aplicaciones de front-end con puerto de host específico y dos réplicas.

En el diagrama anterior se muestra lo siguiente:

  • Un explorador web como punto de entrada para la aplicación.
  • Un puerto de servidor 5066.
  • Proxy de front-end que se encuentra entre el explorador web y las réplicas del servicio front-end, escuchando en el puerto 5066.
  • La réplica del servicio frontend frontend_0 que escucha en el puerto 65001 asignado aleatoriamente.
  • La réplica del servicio frontend frontend_1 que escucha en el puerto 65002 asignado aleatoriamente.

Sin la llamada a WithReplicas, solo hay un servicio de front-end. El proxy sigue escuchando en el puerto 5066, pero el servicio de front-end escucha en un puerto aleatorio:

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

Hay dos puertos definidos:

  • Un puerto de servidor 5066.
  • Puerto proxy aleatorio al que se enlazará el servicio subyacente.

.NET.NET Aspire diagrama de redes de aplicaciones de front-end con puerto host específico y puerto aleatorio.

En el diagrama anterior se muestra lo siguiente:

  • Un explorador web como punto de entrada para la aplicación.
  • Un puerto de servidor 5066.
  • Proxy de frontend que se encuentra entre el navegador web y el servicio frontend, escuchando en el puerto 5066.
  • El servicio de frontend que escucha en un puerto aleatorio, por lo general el 65001.

El servicio subyacente se alimenta de este puerto a través de ASPNETCORE_URLS para los recursos del proyecto. Otros recursos acceden a este puerto especificando una variable de entorno en el enlace de servicio:

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

El código anterior hace que el puerto aleatorio esté disponible en la variable de entorno PORT. La aplicación usa este puerto para escuchar las conexiones entrantes desde el proxy. Tenga en cuenta el siguiente diagrama:

.NET.NET Aspire diagrama de redes de aplicaciones de front-end con puerto de host específico y puerto de variable de entorno.

En el diagrama anterior se muestra lo siguiente:

  • Un explorador web como punto de entrada para la aplicación.
  • Un puerto host de 5067.
  • Proxy de front-end que se encuentra entre el explorador web y el servicio front-end, escuchando en el puerto 5067.
  • El servicio front-end que escucha en un entorno 65001.

Propina

Para evitar que se proxie un punto de conexión, establezca la propiedad IsProxied en false al llamar al método de extensión WithEndpoint. Para obtener más información, consulte Extensiones de punto de conexión: consideraciones adicionales.

Omitir el puerto de host

Al omitir el puerto de host, .NET.NET Aspire genera un puerto aleatorio para el puerto de host y servicio. Esto resulta útil cuando desea evitar conflictos de puertos y no le importa el puerto de host o servicio. Tenga en cuenta el código siguiente:

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

En este escenario, los puertos de host y servicio son aleatorios, como se muestra en el diagrama siguiente:

.NET.NET Aspire diagrama de redes de aplicaciones de front-end con puerto de host aleatorio y puerto proxy.

En el diagrama anterior se muestra lo siguiente:

  • Un explorador web como punto de entrada para la aplicación.
  • Puerto de host aleatorio de 65000.
  • Proxy de frontend que se encuentra entre el navegador web y el servicio frontend, escuchando en el puerto 65000.
  • El servicio frontend que escucha en un puerto aleatorio que es 65001.

Puertos de contenedor

Al agregar un recurso de contenedor, .NET.NET Aspire asigna automáticamente un puerto aleatorio al contenedor. Para especificar un puerto de contenedor, configure el recurso de contenedor con el puerto deseado:

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

El código anterior:

  • Crea un recurso de contenedor denominado frontend, a partir de la imagen de mcr.microsoft.com/dotnet/samples:aspnetapp.
  • Expone un punto de conexión de http enlazando el host al puerto 8000 y asignándolo al puerto 8080 del contenedor.

Tenga en cuenta el siguiente diagrama:

.NET Aspire diagrama de redes de aplicaciones de front-end con un host de docker.

Métodos de extensión de punto de conexión

Cualquier recurso que implemente la interfaz IResourceWithEndpoints puede usar los métodos de extensión WithEndpoint. Existen varias sobrecargas de esta extensión, lo que le permite especificar el esquema, el puerto de contenedor, el puerto host, el nombre de la variable de entorno y si el extremo está proxiado.

También hay una sobrecarga que permite especificar un delegado para configurar el punto de conexión. Esto resulta útil cuando es necesario configurar el punto de conexión en función del entorno u otros factores. Tenga en cuenta el código siguiente:

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

El código anterior proporciona un delegado de callback para configurar el punto de conexión. El punto de conexión se denomina admin y se configura para usar el esquema y el transporte de http, así como el puerto host 17003. El consumidor hace referencia a este punto de conexión por su nombre, tenga en cuenta la siguiente llamada AddHttpClient:

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

El Uri se construye mediante el nombre del punto de conexión de admin prefijo con el _ sentinel. Se trata de una convención para indicar que el segmento de admin es el nombre del punto de conexión que pertenece al servicio apiservice. Para obtener más información, consulte .NET.NET Aspire descubrimiento de servicios.

Consideraciones adicionales

Al invocar el método de extensión WithEndpoint, la sobrecarga de callback revela el EndpointAnnotationen su forma sin procesar, lo que permite al consumidor personalizar muchos aspectos del punto de conexión.

La propiedad AllocatedEndpoint permite obtener o establecer el punto de conexión de un servicio. Las propiedades IsExternal y IsProxied determinan cómo se administra y expone el punto de conexión: IsExternal decide si debe ser accesible públicamente, mientras que IsProxied garantiza que DCP lo administre, lo que permite diferencias internas de puerto y replicación.

Propina

Si hospeda un ejecutable externo que ejecuta su propio proxy y encuentra problemas de asignación de puerto debido a que DCP ya está asignando el puerto, intente establecer la propiedad IsProxied en false. Esto evita que DCP administre el proxy, lo que permite que el ejecutable asigne el puerto correctamente.

La propiedad Name identifica el servicio, mientras que las propiedades Port y TargetPort especifican los puertos deseados y de escucha, respectivamente.

Para la comunicación de red, la propiedad Protocol admite tcp y UDP, con potencial para más en el futuro, y la propiedad Transport indica el protocolo de transporte (HTTP, HTTP2, HTTP3). Por último, si el servicio es direccionable por URI, la propiedad UriScheme proporciona el esquema de URI para construir la URI del servicio.

Para obtener más información, consulte las propiedades disponibles de EndpointAnnotation.

Filtrado de puntos de conexión

Todos los puntos de conexión de los recursos del proyecto .NET.NET Aspire siguen un conjunto de heurísticas predeterminadas. Algunos puntos de conexión se incluyen en ASPNETCORE_URLS en tiempo de ejecución, algunos se publican como HTTP/HTTPS_PORTSy algunas configuraciones se resuelven desde la configuración de Kestrel. Independientemente del comportamiento predeterminado, puede filtrar los puntos de conexión que se incluyen en las variables de entorno mediante el método de extensión 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";
        });

El código anterior agrega un punto de conexión HTTPS predeterminado, así como un punto de conexión de admin en el puerto 19227. Sin embargo, el endpoint admin se excluye de las variables de entorno. Esto resulta útil cuando desea exponer un punto de conexión solo para uso interno.