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


Aspire Обзор оркестрации

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

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

  • модель приложений: коллекция ресурсов, составляющих распределенное приложение (DistributedApplication), определенное в пространстве имен Aspire.Hosting.ApplicationModel. Более формальное определение см. в разделе Определение модели приложения.
  • Проект AppHost/Orchestrator: .NET проект, который управляет моделью приложения с именем *. Суффикс AppHost (по соглашению).
  • ресурс: ресурс является зависимой частью приложения, например проекта .NET, контейнера, исполняемого файла, базы данных, кэша или облачной службы. Он представляет любую часть приложения, которую можно управлять или ссылаться.
  • Интеграция. Интеграция — это пакет NuGet для AppHost , который моделирует ресурс или пакет, который настраивает клиент для использования в потребляемом приложении. Дополнительные сведения см. в обзореAspire интеграции.
  • Ссылка: Ссылка определяет соединение между ресурсами, выраженное как зависимость с помощью API WithReference. Дополнительные сведения см. в статье Справочные ресурсы или Ссылки на существующие ресурсы.

Заметка

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

Определение модели приложения

Aspire позволяет эффективно создавать, подготавливать, развертывать, настраивать, тестировать, запускать и отслеживать распределенные приложения. Эти возможности поддерживаются моделью приложения, которая определяет ресурсы в Aspire решении и их взаимодействия.

Модель приложения — это не просто список ресурсов, который представляет полную топологию приложения. К ним относятся связи между ресурсами, их зависимостями и их конфигурациями. Ресурсы могут включать проекты, исполняемые файлы, контейнеры, внешние службы и облачные ресурсы, на которые используется ваше приложение.

Aspire В проекте AppHost файл Program определяет модель приложения:

var builder = DistributedApplication.CreateBuilder(args);

// Add resources to the app model

builder.Build().Run();

При вызове DistributedApplication.CreateBuilderвы получите экземпляр IDistributedApplicationBuilder, который используется для настройки модели приложения. Этот построитель предоставляет методы для добавления ресурсов, определения зависимостей и настройки общей структуры приложения. После добавления ресурсов вызовите Build, чтобы создать модель приложения. Шаблоны включают код, который связывает вызов Build(), возвращающий экземпляр DistributedApplication, а затем вызывает Run().

Проект AppHost

Проект AppHost обрабатывает выполнение всех проектов, входящих в Aspire проект. Другими словами, она отвечает за оркестрацию всех приложений в модели приложения. Сам проект — это исполняемый .NET проект, использующий Aspire пакет SDK. Начиная с Aspire версии 13.0, Aspire.AppHost.Sdk можно установить в качестве единственного SDK проекта, который неявно добавляет ссылку на пакет NuGet 📦Aspire.Hosting.AppHost.

<Project Sdk="Aspire.AppHost.Sdk/13.0.0">
    
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net10.0</TargetFramework>
        <!-- Omitted for brevity -->
    </PropertyGroup>

    <!-- Omitted for brevity -->

</Project>

Заметка

Альтернативный подход к явному перечислению пакета SDK и ссылки на пакет по-прежнему работает и не является требованием изменить существующие проекты:

<Project Sdk="Microsoft.NET.Sdk">

    <Sdk Name="Aspire.AppHost.Sdk" Version="13.0.0" />
    
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net10.0</TargetFramework>
        <!-- Omitted for brevity -->
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="Aspire.Hosting.AppHost" Version="13.0.0" />
    </ItemGroup>

    <!-- Omitted for brevity -->

</Project>

В следующем коде описывается AppHost Program с двумя ссылками на проект и Redis кэшом:

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddRedis("cache");

var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice");

builder.AddProject<Projects.AspireApp_Web>("webfrontend")
       .WithExternalHttpEndpoints()
       .WithReference(cache)
       .WaitFor(cache)
       .WithReference(apiService)
       .WaitFor(apiService);

builder.Build().Run();

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

  • Создает конструктор модели приложения, используя метод CreateBuilder.
  • Добавляет Rediscache ресурс с именем cache с помощью метода AddRedis.
  • Добавляет ресурс проекта с именем apiservice с помощью метода AddProject.
  • Добавляет ресурс проекта с именем webfrontend с помощью метода AddProject.
    • Указывает, что проект имеет внешние конечные точки HTTP с помощью метода WithExternalHttpEndpoints.
    • Добавляет ссылку на ресурс cache и ожидает его готовности с помощью методов WithReference и WaitFor.
    • Добавляет ссылку на ресурс apiservice и ожидает его готовности с помощью методов WithReference и WaitFor.
  • Создает и запускает модель приложения с помощью методов Build и Run.

В примере кода используется AspireRedis хостинговая интеграция.

Чтобы визуализировать связь между проектом AppHost и описанными ресурсами, рассмотрим следующую схему:

Связь между проектами в шаблоне начального Aspire приложения.

Каждый ресурс должен иметь уникальное имя. На этой схеме показаны все ресурсы и связи между ними. Ресурс контейнера называется cache, а ресурсы проекта называются apiservice и webfrontend. Проект веб-интерфейса ссылается на проекты кэша и службы API. Когда вы выражаете ссылки таким образом, проект веб-интерфейса говорит, что он зависит от этих двух ресурсов — "кэш" и "api-сервис" соответственно.

Встроенные типы ресурсов

Aspire проекты состоят из набора ресурсов. Базовые типы ресурсов в 📦Aspire.Hosting.AppHost пакета NuGet описаны в следующей таблице.

Метод Тип ресурса Описание
AddProject ProjectResource Проект .NET, например, ASP.NET Core веб-приложение.
AddCSharpApp CSharpAppResource Проект C# или файловое приложение, например файл *.cs , *.csproj-файл или каталог проекта.
AddContainer ContainerResource Образ контейнера, например образ Docker.
AddExecutable ExecutableResource Исполняемый файл, например Node.js приложение.
AddParameter ParameterResource Ресурс параметра, который можно использовать для выражения внешних параметров.

Ресурсы проекта представляют .NET проекты, которые являются частью модели приложения. При добавлении ссылки на проект Aspire AppHost пакет SDK создает тип в Projects пространстве имен для каждого указанного проекта. Дополнительные сведения см. в статье Aspire SDK: ссылки на проект. Кроме того, можно добавить проекты C# или приложения на основе файлов без ссылки на проект с помощью AddCSharpApp метода.

Чтобы добавить проект в модель приложения, используйте метод AddProject:

var builder = DistributedApplication.CreateBuilder(args);

// Adds the project "apiservice" of type "Projects.AspireApp_ApiService".
var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice");

Проекты можно реплицировать и масштабировать, добавив несколько экземпляров одного проекта в модель приложения. Чтобы настроить реплики, используйте метод WithReplicas:

var builder = DistributedApplication.CreateBuilder(args);

// Adds the project "apiservice" of type "Projects.AspireApp_ApiService".
var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
                        .WithReplicas(3);

Приведенный выше код добавляет три реплики ресурса проекта apiservice в модель приложения. Дополнительные сведения см. на Aspire панели мониторинга: реплики ресурсов.

Ресурсы приложений C# представляют проекты C# или файловые приложения, которые являются частью модели приложения. В отличие AddProjectот того, что требуется ссылка на проект, AddCSharpApp метод может добавлять проекты C# или приложения на основе файлов, используя путь к файлу *.cs , файлу *.csproj или каталогу проекта. Это полезно для добавления файловых приложений, представленных в .NET 10 или для включения проектов без добавления ссылки на проект в AppHost.

Чтобы добавить приложение C# в модель приложения, используйте AddCSharpApp этот метод:

var builder = DistributedApplication.CreateBuilder(args);

// Adds a file-based C# app "inventoryservice" from a .cs file.
var inventoryService = builder.AddCSharpApp("inventoryservice", @"..\InventoryService.cs");

// Adds a C# project "catalogservice" from a project directory.
var catalogService = builder.AddCSharpApp("catalogservice", @"..\CatalogService");

Этот AddCSharpApp метод поддерживает те же параметры конфигурации, что и AddProject, включая реплики, переменные среды и зависимости ресурсов.

Заметка

Метод AddCSharpApp помечается как экспериментальный и требует .NET 10 sdk для поддержки приложений на основе файлов C#. Дополнительные сведения о файловых приложениях см. в документации по версии 9.5Aspire.

Справочные ресурсы

Ссылка обозначает зависимость между ресурсами. Например, можно представить сценарий, в котором веб-интерфейс зависит от кэша Redis . Рассмотрим следующий пример кода AppHost Program C#:

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddRedis("cache");

builder.AddProject<Projects.AspireApp_Web>("webfrontend")
       .WithReference(cache);

Ресурс проекта "webfrontend" использует WithReference для добавления зависимости от ресурса контейнера "cache". Эти зависимости могут представлять строки подключения или сведения об обнаружении служб. В предыдущем примере переменная среды внедрена в ресурс webfrontend с именем ConnectionStrings__cache. Эта переменная среды содержит строку подключения, которую webfrontend использует для подключения к Redis через интеграцию AspireRedis, например, ConnectionStrings__cache="localhost:62354".

Ссылки на строку подключения и конечную точку

Обычно выражают зависимости между ресурсами проекта. Рассмотрим следующий пример кода:

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddRedis("cache");

var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice");

builder.AddProject<Projects.AspireApp_Web>("webfrontend")
       .WithReference(cache)
       .WithReference(apiservice);

Ссылки между проектами обрабатываются иначе, чем ресурсы с четко определёнными строками подключения. Вместо внедрения строки подключения в ресурс "webfrontend" внедряются переменные среды, поддерживающие обнаружение служб.

Метод Переменная среды
WithReference(cache) ConnectionStrings__cache="localhost:62354"
WithReference(apiservice) APISERVICE_HTTP="http://localhost:5455"
APISERVICE_HTTPS="https://localhost:7356"
services__apiservice__http__0="http://localhost:5455"
services__apiservice__https__0="https://localhost:7356"

Добавление ссылки на проект apiservice приводит к добавлению переменных среды обнаружения служб в интерфейсную часть. Это связано с тем, что обычно обмен данными между проектами происходит по протоколу HTTP/gRPC.

Aspire внедряет два типа переменных среды для ссылок на службы:

  • Упрощенный формат (например, APISERVICE_HTTP): использует шаблон {RESOURCENAME}_{ENDPOINTNAME} в верхнем регистре. Этот формат проще и более подходит для языков, отличных от .NET, и многоязычных сценариев.
  • .NET Формат обнаружения служб (например, services__apiservice__http__0): использует шаблон services__{servicename}__{endpointname}__{index} в нижнем регистре. Этот формат используется для обнаружения служб .NET на основе конфигурации.

Дополнительные сведения см. в разделе Aspire обнаружения служб.

Чтобы получить определенные конечные точки из ContainerResource или ExecutableResource, используйте один из следующих API конечных точек:

Затем вызовите API GetEndpoint, чтобы получить конечную точку, которую можно использовать для ссылки на конечную точку в методе WithReference:

var builder = DistributedApplication.CreateBuilder(args);

var customContainer = builder.AddContainer("myapp", "mycustomcontainer")
                             .WithHttpEndpoint(port: 9043, name: "endpoint");

var endpoint = customContainer.GetEndpoint("endpoint");

var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
                        .WithReference(endpoint);
Метод Переменная среды
WithReference(endpoint) MYAPP_ENDPOINT="https://localhost:9043"
services__myapp__endpoint__0="https://localhost:9043"

Параметр port — это порт, который прослушивается контейнером. Дополнительную информацию о контейнерных портах см. в Порты контейнеров. Дополнительные сведения об обнаружении служб см. в статье Aspire об обнаружении служб.

Формат переменной среды конечной точки службы

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

Если один ресурс зависит от другого ресурса, AppHost внедряет переменные среды в зависимый ресурс. Эти переменные среды настраивают зависимый ресурс для подключения к ресурсу, от которого он зависит. Aspire предоставляет два формата переменных среды для поддержки различных сценариев:

Упрощенный формат (polyglot-friendly)

Упрощенный формат использует шаблон {RESOURCENAME}_{ENDPOINTNAME} в верхнем регистре. Этот формат проще использовать из не.NET языков и рекомендуется для многоязычных сценариев.

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

APISERVICE_HTTP
APISERVICE_HTTPS

Предыдущие переменные среды выражают конечные точки HTTP и HTTPS для apiservice службы. Именованная конечная точка может быть выражена следующим образом:

APISERVICE_MYENDPOINT

В предыдущем примере служба apiservice имеет именованную конечную точку с именем myendpoint.

Заметка

Имя переменной среды основано на имени ресурса, а не на необязательном параметре имени подключения. Даже при использовании WithReference(resource, "customname") для указания имени настраиваемого подключения, созданные переменные среды по-прежнему используют имя ресурса (например, APISERVICE_HTTP), а не настраиваемое имя.

.NET Формат обнаружения служб

Формат обнаружения служб .NET используется конфигурационным обнаружением служб .NET. Имена переменных среды конечной точки службы префиксируются с помощью services__ (двойного подчеркивания), а затем имя службы, имя конечной точки и, наконец, индекс. Индекс поддерживает несколько конечных точек для одной службы, начиная с 0 для первой точки и увеличивая на один для каждой следующей точки.

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

services__apiservice__http__0
services__apiservice__https__0

Предыдущие переменные среды выражают первые конечные точки HTTP и HTTPS для apiservice службы. Именованная конечная точка может быть выражена следующим образом:

APISERVICE_MYENDPOINT

В предыдущем примере служба apiservice имеет именованную конечную точку с именем myendpoint.

Использование конкретной конечной точки с WithEnvironment

Чтобы указать имя пользовательской переменной среды для определенной конечной точки, используйте метод в сочетании WithEnvironment с GetEndpoint:

var projectA = builder.AddProject<Projects.ProjectA>("projecta");
var projectB = builder.AddProject<Projects.ProjectB>("projectb")
                      .WithEnvironment("PROJECTA_URL", projectA.GetEndpoint("https"));

Это создает одну переменную PROJECTA_URL среды с URL-адресом конечной projecta точки HTTPS службы.

Ссылка на существующие ресурсы

Некоторые ситуации предполагают, что вы ссылаетесь на существующий ресурс, возможно, тот, который развернут у облачного провайдера. Например, может потребоваться ссылаться на базу данных Azure. В этом случае вы будете полагаться на контекст выполнения , чтобы динамически определить, работает ли AppHost в режиме запуска или в режиме публикации. Если вы работаете локально и хотите использовать облачный ресурс, можно использовать свойство IsRunMode для условного добавления ссылки. Вместо этого можно создать ресурс в режиме публикации. Некоторые интеграции хостинга поддерживают предоставление строки подключения непосредственно, которую можно использовать для обращения к существующему ресурсу.

Аналогичным образом, могут быть случаи, когда вы хотите интегрировать Aspire в существующее решение. Одним из распространенных подходов является добавление Aspire проекта AppHost в существующее решение. В AppHost вы выражаете зависимости, добавляя ссылки на проекты в AppHost и создавая модель приложения. Например, один проект может зависеть от другого. Эти зависимости выражаются с помощью метода WithReference. Дополнительные сведения см. в статье Добавление Aspire в существующее приложение .NET.

Контекст выполнения

Предоставляет IDistributedApplicationBuilder контекст выполнения (DistributedApplicationExecutionContext), предоставляющий сведения о текущем выполнении AppHost. Этот контекст можно использовать для оценки того, выполняется ли AppHost как режим выполнения или как часть операции публикации. Рассмотрим следующие свойства:

  • IsRunMode: возвращает true, если выполняется текущая операция.
  • IsPublishMode: возвращает true, если текущая операция — публикация.

Эти сведения могут быть полезны, если вы хотите условно выполнить код на основе текущей операции. Рассмотрим следующий пример, демонстрирующий использование свойства IsRunMode. В этом случае метод расширения используется для создания стабильного имени узла для RabbitMQ для локальных запусков разработки.

private static IResourceBuilder<RabbitMQServerResource> RunWithStableNodeName(
    this IResourceBuilder<RabbitMQServerResource> builder)
{
    if (builder.ApplicationBuilder.ExecutionContext.IsRunMode)
    {
        builder.WithEnvironment(context =>
        {
            // Set a stable node name so queue storage is consistent between sessions
            var nodeName = $"{builder.Resource.Name}@localhost";
            context.EnvironmentVariables["RABBITMQ_NODENAME"] = nodeName;
        });
    }

    return builder;
}

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

var builder = DistributedApplication.CreateBuilder(args);

var redis = builder.ExecutionContext.IsRunMode
    ? builder.AddRedis("redis")
    : builder.AddConnectionString("redis");

builder.AddProject<Projects.WebApplication>("api")
       .WithReference(redis);

builder.Build().Run();

В приведенном выше коде:

  • Если AppHost находится в режиме запуска, Redis добавляется ресурс контейнера.
  • Если AppHost находится в режиме публикации, добавляется строка подключения.

Эта логика может быть легко перевернута для подключения к существующему ресурсу Redis при локальном запуске и создании нового ресурса Redis при публикации.

Важный

Aspire предоставляет общие API для управления модальность конструкторов ресурсов, что позволяет ресурсам вести себя по-разному в зависимости от режима выполнения. Интерфейсы API fluent имеют префикс RunAs* и PublishAs*. API RunAs* влияют на поведение локальной разработки (или режима выполнения), а API PublishAs* влияют на публикацию ресурса. Дополнительные сведения о том, как ресурсы Azure используют эти API, см. в статье Использование существующих ресурсов Azure.

См. также