Поделиться через


обзор внутреннего цикла сети .NET.NET Aspire

Одним из преимуществ разработки с помощью .NET.NET Aspire является возможность разработки, тестирования и отладки облачных приложений локально. Внутреннее сетевое взаимодействие — это ключевой аспект .NET.NET Aspire, который позволяет приложениям обмениваться данными друг с другом в вашей среде разработки. В этой статье вы узнаете, как .NET.NET Aspire обрабатывать различные сетевые сценарии с помощью прокси-серверов, конечных точек, конфигураций конечных точек и профилей запуска.

Сетевые операции во внутреннем цикле

Внутренний цикл — это процесс разработки и тестирования приложения локально перед развертыванием в целевой среде. .NET .NET Aspire предоставляет несколько инструментов и функций для упрощения и улучшения взаимодействия в сети на этапе внутренней петли, например:

  • профили запуска: профили запуска — это файлы конфигурации, определяющие локальное выполнение приложения. Профили запуска (например, launchSettings.json файл) можно использовать для определения конечных точек, переменных среды и параметров запуска приложения.
  • Конфигурация Kestrel : позволяет указать конечные точки, на которые прослушивает веб-сервер server Kestrel. Конечные точки Kestrel можно настроить в параметрах приложения, и .NET.NET Aspire автоматически использует эти параметры для создания конечных точек.
  • Конфигурации конечных точек: Конечные точки — это соединения между вашим приложением и службами, от которых оно зависит, такими как базы данных, очереди сообщений или API. Конечные точки предоставляют такие сведения, как имя службы, порт узла, схема и переменная среды. В ваше приложение можно добавлять конечные точки неявно (с помощью профилей запуска) или явно, вызывая WithEndpoint.
  • прокси-серверы: .NET.NET Aspire автоматически запускает прокси-сервер для каждой привязки службы, добавляемой в приложение, и назначает порт для прослушивания прокси-сервера. Затем прокси-сервер перенаправит запросы на порт, на который приложение прослушивает, который может отличаться от порта прокси-сервера. Таким образом, можно избежать конфликтов портов и получить доступ к приложениям и службам с помощью согласованных и прогнозируемых URL-адресов.

Как работают конечные точки

Привязка службы в .NET.NET Aspire включает две интеграции: служба, представляющая внешний ресурс, который требуется вашему приложению (например, база данных, очередь сообщений или API), и привязка , которая устанавливает соединение между вашим приложением и службой и предоставляет необходимые сведения.

.NET .NET Aspire поддерживает два типа привязки службы: неявные, автоматически созданные на основе указанных профилей запуска, определяющих поведение приложения в разных средах, и явные, созданные вручную с помощью WithEndpoint.

При создании привязки, будь то неявная или явная, .NET.NET Aspire запускает упрощенный обратный прокси-сервер на указанном порту, обрабатывая маршрутизацию и балансировку нагрузки для запросов из приложения в службу. Прокси-сервер представляет собой .NET.NET Aspire деталь реализации, не требующую конфигурации или управления.

Чтобы визуализировать работу конечных точек, рассмотрите схему внутренней сети начальных шаблонов .NET.NET Aspire.

.NET.NET Aspire схему внутренних сетевых циклов шаблона начального приложения.

Профили запуска

При вызове AddProjectузел приложения ищет Properties/launchSettings.json определить набор конечных точек по умолчанию. Хост приложения выбирает определенный профиль запуска согласно следующим правилам:

  1. Явный аргумент launchProfileName, переданный при вызове AddProject.
  2. Переменная среды DOTNET_LAUNCH_PROFILE. Дополнительные сведения см. в переменных среды .NET.
  3. Первый профиль запуска, определенный в настройках запуска .json.

Рассмотрим следующие 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"
      }
    }
  }
}

В оставшейся части этой статьи представьте, что вы создаёте IDistributedApplicationBuilder, назначаемую переменной с именем builder, используя API CreateBuilder():

var builder = DistributedApplication.CreateBuilder(args);

Чтобы указать http и профили запуска https, настройте значения applicationUrl для обоих в launchSettings.json файл. Эти URL-адреса используются для создания конечных точек для этого проекта. Это эквивалентно:

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

Важный

Если нет launchSettings.json (или профиль запуска), по умолчанию привязки отсутствуют.

Дополнительные сведения см. в .NET.NET Aspire и профилях запуска.

Настроенные конечные точки Kestrel

.NET .NET Aspire поддерживает конфигурацию конечной точки Kestrel. Например, рассмотрим appsettings.json файл для проекта, который определяет конечную точку Kestrel со схемой HTTPS и портом 5271:

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

Предыдущая конфигурация указывает конечную точку Https. Свойство Url имеет значение https://*:5271, что означает, что конечная точка прослушивает все интерфейсы через порт 5271. Дополнительные сведения см. в разделе server Kestrel.

При настройке конечной точки Kestrel проект должен удалить все настроенные applicationUrl из файла настроек запускаjson.

Заметка

Если applicationUrl присутствует в файле launchSettings.json и настроена конечная точка Kestrel, хост приложения вызовет исключение.

При добавлении ресурса проекта существует перегрузка, которая позволяет указать, что следует использовать конечную точку Kestrel вместо файла launchSettings: файлjson.

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

Дополнительные сведения см. в AddProject.

Порты и прокси-серверы

При определении привязки службы, порт узла всегда предоставляется прокси-серверу, расположенному перед службой. Это позволяет одной или нескольким репликам службы вести себя аналогично. Кроме того, все зависимости ресурсов, использующие API WithReference, полагаются на прокси-адрес из переменной среды.

Рассмотрим следующую цепочку методов, которая вызывает AddProject, WithHttpEndpoint, а затем WithReplicas:

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

Приведенный выше код приводит к следующей сетевой схеме:

.NET.NET Aspire схема сетевого взаимодействия фронтенд-приложения с двумя репликами и с определенным портом хоста.

На приведенной выше схеме показано следующее:

  • Веб-браузер в качестве точки входа в приложение.
  • Порт узла 5066.
  • Интерфейсный прокси-сервер, сидящий между веб-браузером и репликами интерфейсной службы, прослушивает порт 5066.
  • frontend_0 реплика интерфейсной службы, прослушивающая случайным образом назначенный порт 65001.
  • frontend_1 реплика фронтенд-сервиса, прослушивающая порт 65002, назначенный случайным образом.

Без вызова WithReplicasсуществует только один фронтенд-сервис. Прокси-сервер по-прежнему прослушивает порт 5066, но интерфейсная служба прослушивает случайный порт:

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

Существует два порта:

  • Порт узла 5066.
  • Случайный прокси-порт, к которому будет привязана базовая служба.

.NET.NET Aspire схема сетевого взаимодействия фронтенд-приложения с определенным портом хоста и случайным портом.

На приведенной выше схеме показано следующее:

  • Веб-браузер в качестве точки входа в приложение.
  • Порт узла 5066.
  • Интерфейсный прокси-сервер, сидящий между веб-браузером и интерфейсной службой, прослушивает порт 5066.
  • Интерфейсная служба прослушивает случайный порт 65001.

Базовая служба предоставляет этот порт через ASPNETCORE_URLS для ресурсов проекта. Другие ресурсы для доступа к этому порту путем указания переменной среды в привязке службы:

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

Предыдущий код делает случайный порт доступным в переменной среды PORT. Приложение использует этот порт для прослушивания входящих подключений из прокси-сервера. Рассмотрим следующую схему:

.NET.NET Aspire схема сети фронтенд приложения с определенным портом хоста и портом переменной среды.

На приведенной выше схеме показано следующее:

  • Веб-браузер в качестве точки входа в приложение.
  • Порт хоста 5067.
  • Интерфейсный прокси-сервер, сидящий между веб-браузером и интерфейсной службой, прослушивает порт 5067.
  • Сервис фронтенда, работающий в среде 65001.

Совет

Чтобы избежать проксирования конечной точки, задайте для свойства IsProxied значение false при вызове метода расширения WithEndpoint. Дополнительные сведения см. в разделе расширения конечных точек: дополнительные рекомендации.

Исключить порт узла

При опущении порта узла .NET.NET Aspire создает случайный порт для узла и порта службы. Это полезно, если вы хотите избежать конфликтов портов и не заботитесь о узле или порту службы. Рассмотрим следующий код:

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

В этом сценарии порты узла и службы являются случайными, как показано на следующей схеме:

.NET.NET Aspire схема сетевого взаимодействия фронтенд-приложения со случайным портом узла и портом прокси-сервера.

На приведенной выше схеме показано следующее:

  • Веб-браузер в качестве точки входа в приложение.
  • Случайный порт хоста 65000.
  • Интерфейсный прокси-сервер, сидящий между веб-браузером и интерфейсной службой, прослушивает порт 65000.
  • Интерфейсная служба, прослушивающая случайный порт 65001.

Порты контейнеров

При добавлении ресурса контейнера .NET.NET Aspire автоматически назначает случайный порт контейнеру. Чтобы указать порт контейнера, настройте ресурс контейнера с нужным портом:

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

Предыдущий код:

  • Создает ресурс контейнера с именем frontendна основе образа mcr.microsoft.com/dotnet/samples:aspnetapp.
  • Предоставляет точку доступа http, привязывая узел к порту 8000 и сопоставляя его с портом контейнера 8080.

Рассмотрим следующую схему:

.NET Aspire схема сетевого взаимодействия фронтенд-приложения с узлом docker.

Методы расширения конечной точки

Любой ресурс, реализующий интерфейс IResourceWithEndpoints, может использовать методы расширения WithEndpoint. Существует несколько перегрузок этого расширения, позволяющих указать схему, порт контейнера, порт узла, имя переменной среды и является ли конечная точка проксированной.

Существует перегрузка, позволяющая указать делегат для настройки конечной точки. Это полезно, если необходимо настроить конечную точку на основе среды или других факторов. Рассмотрим следующий код:

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

Предыдущий код предоставляет делегат обратного вызова для настройки конечной точки. Конечная точка называется admin и настроена для использования схемы http и транспорта, а также порта узла 17003. Потребитель ссылается на эту конечную точку по имени, рассмотрите следующий вызов AddHttpClient:

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

Uri создается путем добавления стража admin к имени конечной точки _. Это соглашение, указывающее, что сегмент admin является именем конечной точки, принадлежащей службе apiservice. Дополнительные сведения см. в .NET.NET Aspire обнаружении служб.

Дополнительные рекомендации

При вызове метода расширения WithEndpoint перегрузка callback предоставляет необработанные EndpointAnnotation, что позволяет потребителю настраивать множество аспектов конечной точки.

Свойство AllocatedEndpoint позволяет получить или задать конечную точку для службы. Свойства IsExternal и IsProxied определяют, как управляется и предоставляется конечная точка: IsExternal решает, должна ли она быть общедоступной, а IsProxied гарантирует, что DCP управляет ею, что позволяет выполнять внутренние различия портов и репликацию.

Совет

Если вы размещаете внешний исполняемый файл, который запускает собственный прокси-сервер и сталкивается с проблемами привязки портов из-за того, что DCP уже привязывает порт, попробуйте задать для свойства IsProxied значение false. Это предотвращает управление прокси-сервером DCP, позволяя вашему исполняемому файлу успешно привязать порт.

Свойство Name определяет службу, а свойства Port и TargetPort указывают нужные и прослушивающие порты соответственно.

Для сетевого взаимодействия свойство Protocol поддерживает TCP- и UDP-, с возможностью в будущем поддерживать больше, а свойство Transport указывает транспортный протокол (HTTP, HTTP2, HTTP3). Наконец, если служба адресуется по URI, свойство UriScheme предоставляет схему URI для формирования URI службы.

Дополнительные сведения см. в доступных свойствах свойств EndpointAnnotation.

Фильтрация конечных точек

Все конечные точки ресурсов проекта .NET.NET Aspire соответствуют набору эвристики по умолчанию. Некоторые конечные точки динамически включаются в ASPNETCORE_URLS во время выполнения, некоторые публикуются под видом HTTP/HTTPS_PORTS, а некоторые параметры берутся из конфигурации Kestrel. Независимо от поведения по умолчанию можно отфильтровать конечные точки, включенные в переменные среды, с помощью метода расширения 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";
        });

Приведенный выше код добавляет конечную точку HTTPS по умолчанию, а также конечную точку admin на порту 19227. Однако конечная точка admin исключается из переменных среды. Это полезно, если требуется предоставить конечную точку только для внутреннего использования.