Aspire - artemovsergey/ASP GitHub Wiki
.NET Aspire был разработан для упрощения тестирования взаимодействующих микрослужб на машинах разработчиков.
В разделе «Запуск микрослужб на Kubernetes» главы 8 «Практическая организация микрослужб с помощью Kubernetes» мы перечислили два метода тестирования, которые можно использовать на наших машинах разработчиков:
- Тестирование взаимодействующих микрослужб с помощью
minikube
при отладке каждой отдельной микрослужбы с помощью метода моста - Использование встроенной поддержки Visual Studio для Docker для отладки и тестирования наших микрослужб при их взаимодействии через виртуальную сеть Docker
Хотя метод minikube
является более полным и реалистичным, он требует много времени, поэтому большая часть
тестирования/отладки выполняется с помощью виртуальных сетей Docker.
.NET Aspire предоставляет более простую альтернативу прямому использованию сетей Docker. Кроме того, он предлагает простой способ настройки взаимодействия между микрослужбами, а также между каждой микрослужбой и другими ресурсами. Наконец, проекты .NET Aspire можно скомпилировать для создания инструкций по развертыванию всех микрослужб в Azure Container Apps и созданию некоторых ресурсов, которые они используют в Azure. Однако его основное применение — в средах разработки и тестирования, и его не следует использовать для автоматической настройки реальных производственных сред, поскольку он не поддерживает все варианты развертывания.
В этой главе мы опишем основы .NET Aspire вместе со всеми услугами и возможностями, которые он предлагает. В частности, в этой главе рассматриваются следующие темы:
- Функции и услуги .NET Aspire
- Настройка микрослужб и ресурсов
- Использование .NET Aspire на практике
- Развертывание проекта .NET Aspire
.NET Aspire обеспечивает взаимодействие микросервисов и предлагает следующие дополнительные сервисы:
- Очень простое управление взаимодействием с ресурсами среды, такими как базы данных и брокеры сообщений. Вам не нужно указывать строку подключения, которая может измениться при развертывании микросервиса; достаточно объявить взаимодействие между микросервисом и ресурсом вместе с некоторыми общими настройками.
- Это осуществляется с помощью функции .NET, называемой обнаружением локальных сервисов, которая будет подробно рассмотрена в подразделе «Обнаружение сервисов и его роль в .NET Aspire».
- Он предлагает симуляторы облачных сервисов, а также общие дисковые и встроенные в память базы данных и посредников сообщений.
- Взаимодействие между микрослужбами и другими ресурсами настраивается декларативно в специальном проекте .NET, что позволяет избежать использования виртуальных адресов и строк подключения внутри кода микрослужб.
- После запуска проекта .NET Aspire запускаются все микрослужбы и ресурсы, а взаимодействие между микрослужбами и ресурсами обрабатывается автоматически.
- Во время работы микрослужб в среде разработки собираются как журналы, так и статистические данные.
- Как только запускается проект .NET Aspire, в браузере появляется интеллектуальная консоль, которая отображает всю собранную статистику и журналы, а также ссылки для доступа ко всем конечным точкам микросервисов.
Взаимодействия между микросервисами, а также между микросервисами и другими ресурсами объявляются в проекте особого типа, называемом App Host. Проект App Host и все другие шаблоны Aspire можно найти, введя Aspire в поле поиска Visual Studio, как показано на следующем рисунке:

Еще один тип проекта, специфичный для Aspire, — это проект .NET Aspire Service Defaults, который предоставляет методы расширения для настройки различных сервисов. Чтобы обеспечить одинаковую настройку некоторых базовых сервисов во всех микросервисах, мы определяем их в этом проекте, а затем вызываем их методы расширения в конфигурации Program.cs всех проектов микросервисов. Соответственно, все микросервисы должны добавить ссылку на этот проект.
По умолчанию все шаблоны Aspire настраивают следующие параметры сервиса по умолчанию:
- Обнаружение сервиса HttpClient: в конфигурации App Host микросервисам и ресурсам присваиваются имена, и благодаря этой конфигурации HttpClient может использовать виртуальные URL-адреса на основе этих имен вместо фактических URL-адресов ресурсов, которые могут зависеть от того, где ресурсы развернуты в различных средах (разработка, тестирование, производство и т. д.).
- Отказоустойчивость HttpClient: каждый вызов HttpClient автоматически применяется ко всем политикам, как описано в подразделе «Отказоустойчивое выполнение задач» главы 2 «Развенчание мифов о микросервисных приложениях». В частности, стратегии повторных попыток, прерывания цепи, таймаута и ограничения скорости (изоляция переборки) применяются автоматически и могут быть настроены один раз и навсегда в проекте .NET Aspire Service Defaults.
- OpenTelemetry, который будет обсуждаться в отдельном подразделе.
- Общедоступные конечные точки, отображающие состояние микросервисов. Проверки работоспособности используются как оркестратором App Host, так и оркестраторами стадии подготовки и производства, такими как Kubernetes (см. подраздел «Проверки готовности, работоспособности и запуска» в главе 8 «Практическая организация микросервисов с Kubernetes»). Предоставляются две конечные точки по умолчанию: /health, которая возвращает код HTTP 200 и тестовый ответ «healthy», если микрослужба находится в рабочем состоянии, и конечная точка /alive, которая возвращает код HTTP 200 и тестовый ответ «healthy», если микрослужба работает и не вышла из строя.
- По умолчанию обе конечные точки доступны только во время разработки из соображений безопасности. Однако, если микросервис недоступен для внешних пользователей, его также можно безопасно открыть в производственной среде. Для этого нужно просто удалить условие для среды в расширении MapDefaultEndpoints(), определенном в проекте .NET Aspire Service Defaults.
- Если же микросервис является фронтендом, эти конечные точки могут быть открыты только в том случае, если они защищены как аутентификацией, так и стратегией ограничения, которая предотвращает атаки типа «отказ в сервисе». Вам не нужно вручную добавлять все эти конфигурации, так как они добавляются автоматически при создании проекта. В большинстве случаев вам нужно будет изменить только некоторые параметры, такие как параметры различных стратегий отказоустойчивости.
Каждому микросервису необходимо просто вызвать builder.AddServiceDefaults() и app. MapDefaultEndpoints(), чтобы применить все настроенные значения по умолчанию, как показано здесь:
var builder = WebApplication.CreateBuilder(args);
// Add service defaults & Aspire client integrations.
builder.AddServiceDefaults();
// Add application specific services
builder.Services…..
…
// Build application host
var app = builder.Build();
//Configure application
app….
…
//Add default endpoints
app.MapDefaultEndpoints();
app.Run();
Также имеются специфичные для Aspire тестовые проекты на основе xUnit, NUnit и MSTest. Они содержат все необходимые ссылки для создания хоста приложения, запуска приложения и связи с микросервисами через URL-адреса на основе их имен (обнаружение сервисов). Как только вы добавляете тестовый проект, он содержит начальный пример теста со всем кодом для создания хоста приложения и отправки вызова микрослужбе. Этот код закомментирован, поэтому вам нужно просто добавить ссылку на ваш проект хоста приложения, чтобы раскомментировать код, и заменить поддельное имя проекта хоста приложения и имя микрослужбы на имя вашего проекта хоста приложения и имя микрослужбы:
// Arrange
// var appHost = await DistributedApplicationTestingBuilder
.CreateAsync<Projects.MyAspireApp_AppHost>();
// appHost.Services.ConfigureHttpClientDefaults(clientBuilder =>
// {
// clientBuilder.AddStandardResilienceHandler();
// }); //
// await using var app = await appHost.BuildAsync();
// var resourceNotificationService = app.Services.
// GetRequiredService<ResourceNotificationService>();
// await app.StartAsync();
// // Act
// var httpClient = app.CreateHttpClient("webfrontend");
// await resourceNotificationService
// .WaitForResourceAsync("webfrontend",
// KnownResourceStates.Running).WaitAsync(TimeSpan.
FromSeconds(30));
// var response = await httpClient.GetAsync("/");
В предыдущем коде выделены поддельные имена, которые необходимо заменить. Также доступен шаблон под названием .NET Aspire Empty App, который создает проекты App Host и Service Defaults, а также шаблон .NET Aspire Starter App, который добавляет несколько примеров микросервисов и ресурсов вместе с их конфигурациями App Host. Шаблон .NET Aspire Starter App имеет большую дидактическую ценность, поскольку сразу показывает базовые конфигурации, а также то, как настроить и использовать HttpClient с обнаружением сервисов. Кроме того, это хороший способ изучить консоль, которая появляется в браузере при запуске приложения, с ее статистикой и журналами, а также ссылками для доступа ко всем конечным точкам микросервисов. Мы рекомендуем вам создать, изучить и запустить этот проект. Обнаружение сервисов не является специфической функцией Aspire, а является общей функцией .NET. Оно опирается на различных поставщиков для сопоставления имен сервисов с фактическими URL-адресами. Мы обсудим это более подробно в следующем подразделе.
Обнаружение сервисов — это функция HttpClient, предоставляемая через методы расширения, определенные в пакете NuGet Microsoft.Extensions.ServiceDiscovery. Имена сервисов сопоставляются с фактическими URL-адресами с помощью карт, определенных поставщиками. По умолчанию в список поставщиков добавляется только поставщик конфигурации .NET.
Этот провайдер пытается прочитать эти карты из раздела «Сервисы» конфигурации проекта, где они должны быть определены следующим образом:
"Services": {
"myservice": {
"https": [
"10.46.24.91:80"
],
"http": [
"10.46.24.91:443"
]
}
}
Когда сервис вызывается с http://myservice, выбирается конечная точка, указанная в подразделе http ; в противном случае, если он вызывается с https://myservice, выбирается конечная точка в подразделе https. Провайдер на основе конфигурации добавляется следующим образом:
builder.Services.AddServiceDiscovery();
Предыдущий код также добавляет провайдер pass-through, который просто разрешает каждое имя сервиса в само имя сервиса. Другими словами, провайдер pass-through ничего не делает! Он должен быть использован при развертывании в Kubernetes, так как в Kubernetes имена разрешаются сервисами. Поэтому при развертывании в Kubernetes каждый микросервис должен иметь связанный сервис, имя которого идентично имени микросервиса. Например, если у нас есть микросервис под названием routes_planning, который развернут в Kubernetes routes_planning Deployment, то коммуникации с routes_planning должны проходить через сервис Kubernetes под названием routes-planning. Если имя сервиса не разрешается поставщиком на основе конфигурации, оно передается следующему поставщику, который является поставщиком пропуска. Предположим, что мы хотим развернуть на Kubernetes, но сначала нам нужно протестировать наше приложение с помощью .NET Aspire. Нужны ли нам две разные настройки обнаружения сервисов для этих двух сред? Ответ — нет! На самом деле, .NET Aspire не использует файл конфигурации для определения карт сервисов. Вместо этого, когда проект App Host запускает микрослужбу, он вставляет все необходимые правила разрешения сервисов в переменные среды, которые затем объединяются со всей другой конфигурационной информацией микрослужбы.
Когда приложение публикуется в кластере Kubernetes, хост приложения отсутствует, поэтому в конфигурацию не вставляются карты разрешения сервисов, а все разрешения передаются провайдеру пропуска. Можно также использовать AddServiceDiscoveryCore(), который не добавляет провайдер по умолчанию вместо AddServiceDiscovery(). В этом случае провайдеры должны быть добавлены вручную с помощью вы Можно также использовать AddServiceDiscoveryCore(), который не добавляет никаких провайдеров по умолчанию вместо AddServiceDiscovery(). В этом случае провайдеры должны быть добавлены вручную путем вызова AddPassThroughServiceEndpointProvider() и AddConfigurationServiceEndpointProvi der(). Например, если мы хотим добавить только провайдера на основе конфигурации, мы можем просто написать следующее:
builder.Services.AddServiceDiscovery()
.AddConfigurationServiceEndpointProvider();
Обнаружение сервисов также можно настроить, установив свойства объекта опций ConfigurationServic eEndPointResolverOptions. Например, следующий код изменяет имя раздела Services, в котором размещаются все карты имен сервисов:
builder.Services.Configure<ConfigurationServiceEndPointResolverOptions>(
static options =>
{
options.SectionName = "MyCustomResolverSection"
})
После добавления и настройки обнаружения сервисов необходимо указать HTTP-клиенты, которые должны его использовать. Следующий код применяет обнаружение сервисов ко всем HTTP-клиентам:
builder.Services.ConfigureHttpClientDefaults(http =>
{
http.AddServiceDiscovery();
});
ConfigureHttpClientDefaults также можно использовать для добавления и настройки различных политик отказоустойчивости для всех HTTP-клиентов:
builder.Services.ConfigureHttpClientDefaults(http =>
{
http.AddStandardResilienceHandler();
http.AddServiceDiscovery();
});
Предыдущий код представляет собой конфигурацию HttpClient по умолчанию, добавляемую во все проекты .NET Aspire Service Defaults.
Обнаружение сервиса также можно добавить к конкретному HttpClient, как показано здесь:
builder.Services.AddHttpClient("myclient", static client =>
{
client.BaseAddress = new("https://routes_planning");
})
.AddServiceDiscovery();
Когда обнаружение сервисов налажено, мы также можем писать URI, такие как «https+http://routes_ planning» или «http+https://routes_planning». В этом случае обнаружение сервисов попытается разрешить URI с помощью первого протокола (https или http) и перейдет ко второму протоколу в случае неудачи. Это полезно, когда мы используем http во время разработки и https на стадии подготовки и производства. Для этой цели достаточно определить только http-конечные точки в настройках запуска всех микросервисных проектов. Фактически, App Host использует настройки запуска каждого микросервиса для создания карт обнаружения сервисов, которые он вставляет в переменные среды. Поэтому во время разработки будут генерироваться только http-карты, поэтому разрешение https завершится неудачей. После развертывания, вместо этого, будет работать только провайдер pass-through, поэтому разрешение https будет успешным. До этого момента мы предполагали, что каждый микросервис имеет только одну конечную точку, но иногда некоторые сервисы могут иметь несколько конечных точек, каждая из которых находится на отдельном порте. Когда микросервис имеет несколько конечных точек, мы должны дать имена всем конечным точкам, кроме одной (конечной точки по умолчанию). Имена конечных точек задаются в определении и конфигурации сервиса, которые находятся в App Host. Ниже приведено определение микросервиса с конечной точкой по умолчанию и конечной точкой с именем «aux»:
var routesPlanning = builder.AddProject<Projects.
RoutesPlanningService>("routes_planning ")
.WithHttpsEndpoint(hostPort: 9999, name: "aux");
В этом случае сгенерированная карта конфигурации будет связывать два URL-адреса с именем сервиса, один для конечной точки по умолчанию, а другой для именованной конечной точки, как показано здесь:
"Services": {
"routes_planning": {
"https": ["https://localhost:8080"],
"aux": ["https://localhost:8090"]
}
}
По умолчанию конечная точка доступна по адресу «https://routes_planning», а для конечной точки с именем необходимо добавить к URI также имя конечной точки, как показано здесь:
При использовании Aspire App Host предыдущая конфигурация автоматически создается и вставляется во все сервисы, которым она нужна, поэтому нам не нужно об этом беспокоиться. Однако, если мы развертываем на Kubernetes, мы должны определить сервис Kubernetes, который правильно разрешает как «https://routes_planning», так и «https://_aux.routes_planning». Этого результата легко достичь с помощью именованных портов, как показано здесь:
apiVersion: v1
kind: Service
metadata:
name: routes_planning
spec:
selector:
name: routes_planning
ports:
- name: default
port: 8080
- name: aux
port: 8090
Порту, связанному с конечной точкой по умолчанию, должно быть присвоено имя по умолчанию, в то время как всем портам, связанным с именованными конечными точками, должно быть присвоено то же имя, что и конечной точке. Теперь, когда мы понимаем магию, стоящую за обнаружением фактического URL-адреса сервиса, давайте перейдем к магии, стоящей за интеграцией ресурсов и автоматической обработкой строк подключения.
Ресурсы, необходимые для различных проектов микросервисов, могут быть смоделированы при запуске решения. Достаточно добавить соответствующие пакеты Aspire NuGet, а также объявить и настроить ресурс в App Host. Существуют методы расширения для объявления основных баз данных, Redis,
и основные брокеры сообщений, такие как RabbitMQ, Kafka и даже симулятор Azure Service Bus. Полный список всех ресурсов, которые можно добавить в проект Aspire и настроить в его App Host, см. в официальной документации по интеграции на сайте https://learn.microsoft. com/en-us/dotnet/aspire/fundamentals/integrations-overview. За кулисами все эти ресурсы реализованы с помощью образов Docker, поэтому большинство методов расширения также позволяют выбрать конкретный образ Docker и конкретную версию. Кроме того, поскольку App Host поддерживает общие образы Docker, можно реализовать методы расширения для пользовательского ресурса, который еще не поддерживается. Однако список поддерживаемых ресурсов быстро растет, поэтому вы должны найти все необходимые ресурсы, которые уже реализованы. В разделе «Использование .NET Aspire на практике» этой главы вы подробно узнаете, как интегрировать и настроить SQL Server и RabbitMQ, а в разделе «Настройка микрослужб и ресурсов» мы объясним, как объявить и настроить как микрослужбы, так и ресурсы в App Host. При настройке ресурса вы даете ему имя, и если ресурс поддерживает строку подключения, то это имя считается именем строки подключения. Соответственно, когда App Host создает ресурс, он вычисляет его строку подключения и передает ее в раздел ConnectionStrings конфигурации всех микрослужб, которые используют этот ресурс. Это делается путем размещения строки конфигурации в переменной среды под названием ConnectionStrings__, где — это имя, которое мы дали ресурсу.
Например, предположим, что нашему приложению требуется экземпляр SQL Server, содержащий базу данных с именем «mydatabase». В App Host мы можем объявить эти ресурсы следующим образом:
var builder = DistributedApplication.CreateBuilder(args);
var sql = builder.AddSqlServer("sql");
var db = sql.AddDatabase("mydatabase ");
Теперь, если микрослужба, определённая в проекте MyExampleProject, должна использовать базу данных «mydatabase», она должна объявить её следующим образом:
builder.AddProject<Projects.MyExampleProject>().WithReference(db);
Вызов WithReference(db) приводит к тому, что строка подключения для доступа к «mydatabase» в экземпляре SQL Server вставляется в переменную среды ConnectionStrings__mydatabase микрослужбы MyExampleProject. Очевидно, что при настройке ресурса мы также можем указать учетные данные для доступа к нему вместо использования учетных данных по умолчанию, созданных методом расширения.
Более подробная информация о настройке ресурсов и микрослужб в App Host будет представлена в следующем разделе. Обычно вместе со строкой подключения App Host передает целый раздел конфигурации, содержащий более подробную информацию о ресурсах, такую как имя пользователя и пароль. Формат этих вспомогательных данных зависит от конкретного типа ресурса. В разделе «Использование .NET Aspire на практике» этой главы мы рассмотрим формат вспомогательной информации RabbitMQ. Формат вспомогательной информации всех поддерживаемых ресурсов доступен в официальной документации. Если мы хотим использовать уже существующий ресурс, нам не нужно объявлять его в App Host, но нам необходимо объявить его строку подключения с помощью builder.AddConnectionString, чтобы App Host мог внедрить ее во все микросервисы, которые в ней нуждаются. Например, если база данных SQL Server из предыдущего примера уже существует как в среде разработки, так и в среде развертывания, код необходимо изменить следующим образом:
var builder = DistributedApplication.CreateBuilder(args);
var db = builder.AddConnectionString("parameterName", "database");
Здесь parameterName — это имя параметра, содержащего строку подключения в файле конфигурации App Host в разделе «Parameters», как показано здесь:
{
"Parameters": {
" parameterName ": " SERVER=XXX.XXX.X.XX;DATABASE=DATABASENAME ……"
}
}
Разумеется, мы можем использовать среды .NET для предоставления различных конфигураций в разных средах. Остальная часть кода остается без изменений:
builder.AddProject<Projects.MyExampleProject>()
.WithReference(db);
Что происходит со всеми строками подключения и вспомогательными данными ресурсов при развертывании приложения в производственной или промежуточной среде?
Если развертывание выполняется вручную, та же переменная среды, вставленная хостом приложения, должна быть определена в конфигурации целевого оркестратора. Так, например, если целевым оркестратором является Kubernetes, она должна быть определена в разделе env развертывания. Как мы увидим более подробно в разделе «Развертывание проекта .NET Aspire», при использовании автоматических инструментов для настройки целевого оркестратора существует две возможности:
- Если автоматический инструмент способен предоставить необходимые ресурсы, он также автоматически настроит все переменные среды, взяв всю необходимую информацию из созданных ресурсов
- Если автоматический инструмент не генерирует необходимые ресурсы, а только генерирует код для настройки всех микрослужб, он запросит у пользователя значения переменных среды В следующем подразделе подробно описано, как обрабатывать телеметрию во время разработки и при развертывании приложения.
Телеметрия позволяет отслеживать микросервисное приложение в целом, связывая между собой связанные между собой события, происходящие в разных микросервисах. В частности, она собирает следующие данные:
- Логирование: индивидуальные логи всех микросервисов и ресурсов собираются и классифицируются в соответствии с временем их создания и источником.
- Трассировка: трассировки соотносят события журнала, которые являются частью одной и той же логической активности (например, обработка одного запроса), даже если они распределены по нескольким машинам или процессам. Трассировка является отправной точкой для диагностики и отладки неисправностей.
- Метрики: различные метрики микросервисов собираются каждым выполняющимся микросервисом и отправляются в точку сбора. Когда приложение запускается в среде разработки и использует App Host в качестве оркестратора, телеметрия каждого микросервиса включается вызовом ConfigureOpenTelemetry(), настроенным в проекте .NET Aspire Service Defaults. Этот вызов включает сбор метрик и передачу этих метрик вместе с журналами микросервисов в конечную точку OpenTelemetry, которая реализует протокол OpenTelemetry (OTLP). Во время разработки консоль Aspire, которая открывается при запуске решения, работает как конечная точка OpenTelemetry, а данные для подключения к этой конечной точке вводятся в качестве переменной среды во все микросервисы App Host. Таким образом, все данные, которые мы видим в этой консоли, происходят из телеметрии.
При развертывании приложения те же переменные среды должны содержать данные конечной точки OpenTelemetry, доступной в среде развертывания. Azure поддерживает OTLP, поэтому, если, например, приложение развернуто в Azure Kubernetes, мы должны передать данные конечной точки телеметрии, которая создается вместе с кластером Azure Kubernetes. Также можно передать данные OpenTelemetry в такие инструменты, как Grafana, что было описано в подразделе «Административные инструменты Kubernetes» главы 9 «Упрощение контейнеров и Kubernetes: Azure Container Apps и другие инструменты». Переменные среды, автоматически вставляемые в каждый микросервис хостом приложения, которые мы должны вставлять вручную в среду развертывания, следующие:
- OTEL_EXPORTER_OTLP_ENDPOINT, которая содержит URL конечной точки OTLP.
- OTEL_SERVICE_NAME, которая содержит имя сервиса, которое микросервис должен добавлять к отправляемым данным. Вы должны использовать то же имя, которое было присвоено микросервису в конфигурации приложения Host.
- OTEL_RESOURCE_ATTRIBUTES, который содержит уникальный идентификатор, однозначно идентифицирующий каждый экземпляр сервиса. Он также должен быть добавлен ко всем данным и иметь следующий формат: service.instance.id=<уникальное имя>. Обычно в качестве уникальных имен сервисов используются GUID. После того, как вы выяснили все сервисы, предлагаемые Aspire, вам нужно узнать, как настроить App Host.
App Host обрабатывает сервисы следующим образом:
- Проекты .NET: их можно настроить с помощью var myService = builder. AddProject<Projects.MyProjectName>(«myservicename»);
- Контейнеры, хранящиеся в каком-либо реестре: их можно настроить с помощью var myService = builder.AddContainer(«myservicename», «ContainerNameOrUri»);
- Исполняемые файлы: их можно настроить с помощью var myService = builder. AddExecutable(«myservicename», «», "");
- Dockerfiles для сборки: их можно настроить с помощью var myService = builder. AddDockerfile( «myservicename », «relative/context/path»); где «relative/context/path» — это папка, содержащая Dockerfile и все файлы, необходимые для сборки Dockerfile. Этот путь должен быть относительным по отношению к каталогу, содержащему файл проекта App Host.
За каждой из предыдущих команд может следовать несколько параметров конфигурации, передаваемых с помощью плавного интерфейса, как показано в этом примере:
var cache = builder.AddProject<Projects……
var apiService = builder.AddProject<Projects……
builder.AddProject<Projects.MyAspireProject>("webfrontend")
.WithReference(cache)
.WaitFor(cache)
.WithReference(apiService)
.WaitFor(apiServ
WithReference объявляет, что сервис взаимодействует с ресурсом или сервисом, переданным в качестве аргумента. Это приводит к вставке всех переменных среды, содержащих данные, необходимые для обнаружения сервиса, строк подключения или другой вспомогательной информации о ресурсе. WaitFor объявляет, что микросервис должен быть запущен после того, как сервис или ресурс, переданный в качестве аргумента, запущен. WithReplicas(int n) — еще один важный метод конфигурации интерфейса fluent. Он объявляет, что микрослужба должна быть реплицирована n раз. Это важно, если мы планируем использовать автоматический инструмент для компиляции конфигурации App Host в код конфигурации Kubernetes или Azure Container Apps.
К сожалению, часто в режиме разработки ограниченная мощность нашей машины для разработки не позволяет использовать то же количество реплик, которое нам нужно в производственной среде. Поэтому в таких случаях мы должны выполнять другие инструкции по конфигурации. Конфигурация App Host выполняется как при запуске приложения на машине разработчика, так и при использовании конфигурации App Host для генерации кода для других платформ. Во втором случае мы говорим, что находимся в режиме публикации, а не в режиме запуска. К счастью, объект builder содержит информацию о среде выполнения в свойстве builder.ExecutionContext. В частности, мы можем использовать свойства builder.ExecutionContext.IsPublishMode и builder. ExecutionContext.IsRunMode, чтобы различать конфигурацию в режиме выполнения и в режиме публикации. Как уже упоминалось в подразделе «Обнаружение сервиса и его роль в .NET Aspire», мы также можем использовать метод интерфейса WithEndpoint для объявления вспомогательных конечных точек, доступных на других портах:
var routesPlanning = builder.AddProject<Projects.
RoutesPlanningService>("routes_planning ")
.WithEndpoint(hostPort: 9999, name: "aux");
WithEndpoint можно заменить на WithHttpsEndpoint и WithHttpEndpoint для объявления, соответственно, только HTTPS- и только HTTP-конечных точек. Метод плавного интерфейса WithExternalHttpEndpoints() объявляет, что конечная точка микрослужбы должна быть доступна вне приложения для клиентов приложения. Эти конечные точки будут раскрыты с помощью сервисов Ingress или LoadBalancer при публикации приложения в Kubernetes и с помощью внешних входов при публикации приложения в Azure Container Apps. Ресурсы, используемые микрослужбами, могут быть объявлены и настроены с помощью того же плавного интерфейса. Каждый тип ресурса требует специального пакета NuGet, который предоставляет необходимые методы расширения для интерфейса Fluent. Все эти методы расширения построены на основе метода builder.AddContainer, поскольку они используют образы Docker для реализации ресурсов. Поэтому, если нужный нам ресурс еще не доступен, мы можем сами написать необходимые методы расширения. Однако, как уже упоминалось, существуют ресурсы для всех основных баз данных, Redis, всех основных брокеров сообщений и большинства сервисов Azure. Некоторые конфигураторы ресурсов Azure предоставляют и используют фактические ресурсы Azure, а другие используют локальные симуляторы. Существуют симуляторы для Azure Storage и Azure Service Bus. Список всех доступных интеграций ресурсов см. в официальной документации: https://learn. microsoft.com/en-us/dotnet/aspire/fundamentals/integrations-overview. По умолчанию при завершении работы App Host все данные базы данных теряются, поскольку все образы Docker используют временное хранилище. Однако мы можем использовать метод плавного интерфейса WithDataVolume(), чтобы принудительно использовать постоянное хранилище тома Docker:
var sql = builder.AddSqlServer("sql")
.WithDataVolume();
var db = sql.AddDatabase("database");
При вызове этого метода создается том Docker с автоматически сгенерированным именем. Для более точного контроля над именем тома и каталогом внутри контейнера, в который он монтируется, можно использовать WithBindMount:
var sql = builder.AddSqlServer("sql")
.WithBindMount("MyVolumeName", "/var/opt/mssql");
var db = sql.AddDatabase("database");
Большинство ресурсов используют имя пользователя по умолчанию, например sa, и автоматически сгенерированный пароль. Обе учетные записи доступны через ссылку «Информация о ресурсах» в консоли браузера App Host. Однако, если данные не сохраняются в томе, этот пароль может меняться при каждом запуске.
К счастью, все ресурсы предоставляют возможность указать некоторые параметры, и имя пользователя и пароль всегда входят в их число. Разумеется, параметры не вставляются непосредственно в код по понятным причинам. Они взяты из раздела «Параметры» конфигурации App Host. Таким образом, их можно вставлять в файл конфигурации App Host, поэтому мы также можем предоставить разные значения для каждой среды, используя обычное переопределение файла конфигурации на основе среды .NET. Первым шагом является определение объекта параметра с именем свойства «Parameters», которое содержит фактическое значение:
var password = builder.AddParameter("sqlpassword", secret: true);
Установив секретность в значение true, мы включаем генерацию подсказки для хранения параметра в безопасном месте при запуске Aspire в режиме публикации. Затем параметр помещается в нужное место метода расширения ресурса, которое зависит от конкретного ресурса:
var sql = builder.AddSqlServer("sql", password)
.WithBindMount("MyVolumeName", "/var/opt/mssql");
var db = sql.AddDatabase("database");
Фактическое значение должно быть указано в файле конфигурации проекта App Host, как показано здесь:
{
"Parameters": {
"sqlpassword": "my_password_value",
…
},
…
}
В этом разделе мы адаптируем пример Kubernetes из главы 8 «Практическая организация микрослужб с помощью Kubernetes» для работы с Aspire. В качестве первого шага скопируем всю папку решения в другую папку в другом месте, чтобы мы могли изменять ее, не уничтожая предыдущую версию. Затем выполним следующие шаги, чтобы подготовить общее решение:
- Добавьте в решение новый проект App Host и назовите его CarSharingAppHost.
- Добавьте в решение новый проект .NET Aspire Service Defaults и назовите его CarSharingServiceDefaults.
- Добавьте ссылку на проекты FakeSource, FakeDestination и RoutesPlanning в проект CarSharingAppHost.
- Добавьте ссылку на проект CarSharingServiceDefaults в проекты FakeSource, FakeDestination и RoutesPlanning.
- Щелкните правой кнопкой мыши проект CarSharingAppHost и в появившемся меню выберите Set as Startup Project. Предыдущие шаги подготавливают решение для .NET Aspire. Теперь приступим к изменению кода. В первую очередь необходимо добавить настройки по умолчанию для всех микросервисов. Для этого добавим builder. AddServiceDefaults(); в файл program.cs проектов FakeSource, FakeDestination и RoutesPlanning. Затем мы должны добавить app.MapDefaultEndpoints(), который добавляет конечные точки работоспособности только в файл program.cs проекта RoutesPlanning, поскольку это единственный веб-проект среди наших микрослужб. Он должен быть размещен, как показано здесь:
var app = builder.Build();
app.MapDefaultEndpoints();
Теперь давайте вспомним, что мы добавили все параметры микрослужб в качестве переменных среды в их файл Properties/launcheSettings.json. Мы поместили их в настройки запуска Docker. Теперь, поскольку эти проекты больше не будут использовать Docker при запуске в Aspire, мы должны скопировать все эти определения в другой профиль настроек запуска.
Это код настроек запуска проекта RoutesPlanning после этого изменения:
{
"profiles": {
"http": {
"commandName": "Project",
"environmentVariables": {
//place here your environment variables
"ConnectionStrings__DefaultConnection": "Server=localhost;
Database=RoutesPlanning;User Id=sa;Password=Passw0rd_;
Trust Server Certificate=True;MultipleActiveResultSets=true",
"ConnectionStrings__RabbitMQConnection": "host=localhost:5672;
username=guest;password=_myguest;
publisherConfirms=true;timeout=10”,
"Messages__SubscriptionIdPrefix": "routesPlanning",
"Topology__MaxDistanceKm": "50",
"Topology__MaxMatches": "5",
"Timing__HousekeepingIntervalHours": "48",
"Timing__HousekeepingDelayDays": "10",
"Timing__OutputEmptyDelayMS": "500",
"Timing__OutputBatchCount": "10",
"Timing__OutputRequeueDelayMin": "5",
"Timing__OutputCircuitBreakMin": "4"
},
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:5212"
},
"Container (Dockerfile)": {
…
…
Мы заменили host.docker.internal на localhost во всех строках подключения, так как при запуске в Aspire наши микросервисы не будут обращаться к базе данных SQL и брокеру сообщений RabbitMQ изнутри образа контейнера Docker, а будут обращаться напрямую с машины разработчика.
Аналогично, настройки запуска FakeSource становятся следующими:
{
"profiles": {
"FakeSource": {
"commandName": "Project",
"environmentVariables": {
"DOTNET_ENVIRONMENT": "Development",
"ConnectionStrings__RabbitMQConnection":
"host=localhost:5672;username=guest;
password=_myguest;publisherConfirms=true;timeout=10"
},
"dotnetRunMessages": true
},
"Container (Dockerfile)": {
"commandName": "Docker",
"environmentVariables": {
"ConnectionStrings__RabbitMQConnection":
“host=host.docker.internal:5672;
username=guest;password=_myguest;
publisherConfirms=true;timeout=10”
}
}
},
"$schema": "https://json.schemastore.org/launchsettings.json"
}
В результате настройки запуска FakeDestination становятся следующими:
{
"profiles": {
"FakeDestination": {
"commandName": "Project",
"environmentVariables": {
"DOTNET_ENVIRONMENT": "Development",
"ConnectionStrings__RabbitMQConnection":
"host=localhost:5672;username=guest;
password=_myguest;publisherConfirms=true;timeout=10"
},
"dotnetRunMessages": true
},
"Container (Dockerfile)": {
"commandName": "Docker",
"environmentVariables": {
"ConnectionStrings__RabbitMQConnection":
“host=host.docker.internal:5672;
username=guest;password=_myguest;
publisherConfirms=true;timeout=10"
}
}
},
"$schema": "https://json.schemastore.org/launchsettings.json"
}
Содержимое строк подключения RabbitMQ и SQL Server показывает, что мы решили использовать существующие экземпляры RabbitMQ и SQL, которые работают вне Aspire. Это был самый простой вариант для данного решения, поскольку весь код уже был организован для работы таким образом. Однако часто это лучший выбор, когда мы начинаем решение с нуля, поскольку экземпляры, которые работают, когда App Host не запущен, проще обрабатывать во время разработки. Фактически, мы можем передавать миграции базы данных в базу данных без необходимости запускать App Host во время работы с миграциями. Аналогично, мы можем проверять RabbitMQ из его консоли браузера, когда App Host не работает. Другим альтернативным вариантом было бы разделить весь код конфигурации App Host на две зоны кода. Первая зона кода содержит базы данных и брокеры сообщений, с которыми нам нужно работать, когда приложение не запущено, а вторая зона кода содержит все остальные ресурсы и конфигурацию микросервисов. Когда нам нужно работать с ресурсами, определенными в первой зоне кода, мы закомментируем весь код второй зоны и запустим App Host. После завершения работы с миграциями и проверки очереди RabbitMQ мы снимаем комментарий со второй зоны кода, которая определяет и настраивает все остальные ресурсы и микрослужбы, и запускаем все приложение. Предыдущую методологию можно усовершенствовать, определив булеву переменную среды хоста приложения, которая выбирает вторую зону конфигурации с помощью оператора if. После этого мы можем написать наш код конфигурации в файле program.cs хоста приложения.
Поскольку в нашем случае каждый микросервис имеет несколько профилей настроек запуска, мы должны указать правильный профиль для использования с каждым микросервисом в методе AddProject fluent interface. Кроме того, поскольку FakeSource отправляет данные в микросервис RoutesPlanning, а микросервис RoutesPlanning отправляет данные в сервис FakeDestination, мы должны убедиться, что RoutesPlanning запускается после запуска FakeDestination, а FakeSource запускается только после запуске RoutesPlanning. Нам не нужен WithReference, поскольку не все микросервисы общаются напрямую, а общаются через экземпляр RabbitMQ, а WithReference необходим только для вставки информации для прямой связи с ресурсом. Нам также не нужно объявлять ссылку на RabbitMQ, поскольку мы используем внешний экземпляр RabbitMQ, который работает вне App Host, поэтому у нас уже есть его строка подключения. Все ограничения легко выполнить с помощью следующего кода конфигурации:
var builder = DistributedApplication.CreateBuilder(args);
var fakeDestination=builder.AddProject<Projects.
FakeDestination>("fakedestination",
"FakeDestination");
var routesPlanning = builder.AddProject<Projects.
RoutesPlanning>("routesplanning", "http")
.WaitFor(fakeDestination);
builder.AddProject<Projects.FakeSource>("fakesource", "FakeSource")
.WaitFor(routesPlanning);
builder.Build().Run();
Здесь вторым аргументом каждого вызова AddProject является имя профиля запуска, который будет использоваться для каждого микросервиса. Убедимся, что внешние контейнеры Docker RabbitMQ и SQL Server работают, а затем запустим наше решение. Если все работает правильно, в консоли браузера Aspire вы должны увидеть что-то похожее на следующий рисунок:

Щелкните значок «Консоль» в левом меню, чтобы просмотреть все журналы микрослужб. Выберите fakedestination; вы должны увидеть что-то похожее на следующий рисунок:

Логи должны содержать информацию о подключении к RabbitMQ через EasyNetQ и о запуске сервиса-рабочего. В конце концов, вы должны увидеть два сообщения от микросервиса RoutesPlanning, которые сообщают, что было найдено два совпадения. Поскольку все микросервисы используют одну и ту же строку подключения RabbitMQ, мы можем улучшить организацию всего кода, удалив ее из настроек запуска каждого микросервиса и вынеся ее в конфигурацию хоста приложения с помощью AddConnectionString, как показано здесь:
builder.AddConnectionString("RabbitMQParameterName",
"RabbitMQConnection");
Здесь RabbitMQParameterName — это имя параметра конфигурации хоста приложения, который содержит фактическую строку подключения:
{
"Parameters": {
"RabbitMQParameterName": "host=localhost:5672;username=guest;
password=_myguest;
publisherConfirms=true;timeout=10"
}
}
В следующем подразделе мы опишем, как изменить код, чтобы запустить RabbitMQ внутри App Host.
RabbitMQ поддерживается интеграцией Aspire, поэтому мы можем запускать его также внутри App Host. Первый шаг для этого — добавление пакета NuGet Aspire.Hosting.RabbitMQ. Затем нам нужно настроить экземпляр RabbitMQ:
var username = builder.AddParameter("rabbitmqusername", secret: true);
var password = builder.AddParameter("rabbitmqpassword", secret: true);
var rabbitmq = builder.AddRabbitMQ("RabbitMQConnection", username,
password)
.WithManagementPlugin()
.WithDataVolume(isReadOnly: false);
Здесь мы добавили том для сохранения данных после завершения работы App Host и потребовали установку консоли управления браузером, чтобы мы могли просматривать все очереди, а также настраивать экземпляр. Фактическое имя пользователя и пароль должны быть указаны в разделе «Parameters» конфигурационного файла App Host:
{
"Parameters": {
"rabbitmqusername": "<username>",
"rabbitmqpassword": "<password>"
}
}
После этого мы должны объявить ссылку на этот экземпляр RabbitMQ во всех микрослужбах с помощью WithReference(rabbitmq). На этом этапе нам необходимо удалить строки подключения RabbitMQ из всех настроек запуска наших микрослужб, поскольку теперь одна и та же строка подключения будет вставляться App Host. К сожалению, вставленная строка подключения не соответствует формату, требуемому EasyNetQ, а имеет следующий формат:
amqp://username:password@<host url>:5672.
Самый простой способ решить эту проблему — написать метод манипулирования строками, который преобразует эту строку и добавляет всю остальную вспомогательную информацию. Мы можем определить этот метод в проекте Service Defaults, чтобы он был доступен для всех микросервисов.
Нам нужно только извлечь URL, имя пользователя и пароль, а затем мы можем использовать их для создания строки подключения в формате, необходимом для EasyNetQ. Это можно сделать, разделив строку на //, затем на @ и, наконец, на :, чтобы получить имя пользователя и пароль. В последнем разделе мы опишем, как получить конфигурацию, необходимую для нашего целевого оркестратора для проекта Aspire.
.NET Aspire можно использовать для тестирования приложения или небольшой части сложного микросервисного приложения на машине разработчика, заменяя таким образом сети minikube и Docker.
Однако небольшие приложения можно полностью реализовать в Aspire, а затем код Aspire можно использовать для генерации конфигурации целевого оркестратора. Эта генерация может быть ручной или основанной на автоматических инструментах. Как ручное создание, так и автоматические инструменты опираются на манифест JSON, который может быть создан автоматически и описывает конфигурацию приложения. Манифест JSON может быть сгенерирован путем добавления следующего профиля запуска в файл launchSettings.json проекта App Host:
"profiles": {
"generate-manifest": {
"commandName": "Project",
"launchBrowser": false,
"dotnetRunMessages": true,
"commandLineArgs": "--publisher manifest --output-path aspire-
manifest.json"
}
…
После добавления в launchSettings.json этот профиль появляется в списке выбора профилей Visual Studio рядом с кнопкой «Выполнить». Достаточно выбрать профиль «generate-manifest» и запустить решение. При запуске решения приложение компилируется, но вместо запуска создает манифест JSON в папке проекта App Host. Вы можете вручную прочитать этот манифест и использовать содержащуюся в нем информацию для настройки оркестратора, либо воспользоваться автоматическими инструментами, которые генерируют манифест и используют его для автоматической настройки оркестратора.
Visual Studio изначально поддерживает развертывание приложений Azure Container Apps. Публикация в Azure Container Apps не представляет сложности. Достаточно щелкнуть правой кнопкой мыши проект App Host решения и выбрать «Публиковать». После этого можно выбрать цель публикации Azure Container Apps. Процедура подскажет вам, как подключиться к вашей подписке Azure и предоставить всю информацию, необходимую для публикации приложения. Мастер публикации опубликует все микрослужбы как приложения Azure Container Apps и подготовит все другие ресурсы, определенные в App Host в Azure, такие как базы данных и другие ресурсы Azure. Также доступен внешний инструмент под названием Aspir8 (https://prom3theu5.github.io/aspirational-manifests/ getting-started.html), который способен развертывать приложение на кластере Kubernetes. Однако в этом случае он создаст только развертывания и сервисы Kubernetes. После установки Aspir8 поддерживает следующие команды:
- aspirate init: инициализирует проект Aspir8 в текущем каталоге
- aspirate generate: генерирует манифесты Kubernetes на основе манифеста хоста приложения .NET Aspire
- aspirate apply: применяет сгенерированные манифесты Kubernetes к кластеру Kubernetes
- aspirate destroy: удаляет ресурсы, созданные командой apply
- aspirate destroy: удаляет ресурсы, созданные командой apply
Для простого приложения вы можете развернуть его непосредственно в кластере Kubernetes, а в случае более сложных приложений вы можете использовать манифест Kubernetes в качестве отправной точки для проектирования необходимой конфигурации Kubernetes.
Для команд apply и destroy требуется установка kubectl, и все операции выполняются с использованием текущего контекста kubectl. Определение контекста kubectl см. в разделе «Взаимодействие с Kubernetes: kubectl, minikube и AKS» главы 8 «Практическая организация микрослужб с помощью Kubernetes».
Если вы хотите вручную проверить манифест, сгенерированный App Host, обратитесь к официальной документации по формату на странице https://learn.microsoft.com/en-us/dotnet/aspire/ deployment/manifest-format.
В этой главе мы описали возможности и сервисы, предлагаемые .NET Aspire. Мы обсудили как настроить сложное приложение, состоящее из микросервисов и других ресурсов в проекте App Host, и подробно рассмотрели, как работает обнаружение сервисов в целом и в частности с .NET Aspire.
Мы описали, как переменные среды, содержащие всю информацию, необходимую для взаимодействия между микросервисами и ресурсами, автоматически вставляются во все микросервисы App Host.
Наконец, мы обсудили, как Aspire реализует наблюдаемость с помощью телеметрии и как конфигурация App Host может быть использована для генерации автоматической конфигурации для целевых оркестраторов.
Эта глава завершает наше удивительное путешествие по концепциям и технологиям современных распределенных вычислений. Мы надеемся, что вам понравилось читать эту книгу так же, как нам понравилось ее писать.
Вопросы
- Какие проекты .NET SDK специфичны для Aspire? .NET Aspire Starter Project, .NET Aspire Empty Project, .NET Aspire App Host, .NET Aspire Service Defaults, .and various NET Aspire Test projects.
- Является ли обнаружение сервисов особенностью Aspire? Нет, это общая особенность .NET.
- Сколько провайдеров обнаружения сервисов поставляется с настройками Aspire по умолчанию? Только два.
- Каков лучший способ обработки уже существующих ресурсов, которые не определены с помощью App Host, но используются несколькими микрослужбами? Использование AddConnectionString.
- Aspir8 также предоставляет ресурсы Azure? Нет, на данный момент он предоставляет только ресурсы Kubernetes.
- Для чего нужен метод WithReference fluent interface? Для объявления, что ресурс зависит от другого ресурса, то есть ему нужна информация такая как URL-адреса и строка подключения этого ресурса.
• Дэн Кларк, независимый разработчик и консультант, представляет курс по .NET Aspire. • Это четвёртый курс Дэна, предыдущие были посвящены Docker, Kubernetes и JetBrains Rider. • .NET Aspire меняет правила игры для разработчиков .NET, работающих с веб-приложениями и API.
• .NET Aspire включает хост приложения и настройки по умолчанию. • Настройки по умолчанию настраивают OpenTelemetry, проверки работоспособности, обнаружение сервисов и отказоустойчивость. • Хост приложения становится стартовым проектом, описывающим всё приложение: API, фронтенд, базу данных SQL Server и кеш Redis.
• При запуске приложения открывается панель управления Aspire, показывающая все сервисы, включая Docker и .NET-приложение. • Панель управления предоставляет детали сервисов, переменные среды, проверки работоспособности, журналы консоли, структурированные журналы, трассировки и метрики. • Доступны локальные визуализации и настройки OpenTelemetry.
• Добавление .NET Aspire в существующий проект занимает считанные минуты. • В курсе будут рассмотрены история развёртывания Aspire, обнаружение сервисов, проверки работоспособности и другие темы. • В следующем видео Дэн подробнее опишет, что будет изучаться в курсе.
• Обсуждение различных способов работы с ASP.NET в зависимости от IDE: Visual Studio, JetBrains Rider, VS Code и командная строка. • Фокус на JetBrains Rider как основной среде для демонстраций. • Упоминание о стандартных действиях, таких как добавление пакетов NuGet и ссылки на проекты.
• Демонстрация начала работы с новым проектом в Visual Studio. • Рекомендация не пропускать объяснение, даже если вы не используете Visual Studio. • Упоминание последней версии ASP.NET 9.2 и предварительного интерфейса ASP.NET CLI.
• Важность обращения к документации на сайте Microsoft.com. • Обзор инструментов: VS Code, Visual Studio, .NET CLI. • Необходимость установки Docker Desktop или Podman.
02:11 Установка компонентов
• Установка контейнерной среды выполнения и инструментов VS Code. • Создание нового проекта в Visual Studio с использованием шаблонов ASP.NET. • Создание хоста приложения ASP.NET и сервиса по умолчанию.
• Добавление поддержки ASP.NET в существующее приложение через контекстное меню. • Выбор версии ASP.NET и автоматическое изменение стартап-проекта.
• Обзор шаблонов проектов: стартовый пакет, пустое приложение ASP.NET, настройки сервиса по умолчанию, тестовые проекты. • Возможность ручного добавления проектов в существующее решение.
• Поиск и установка плагина ASP.NET в Rider. • Обзор шаблонов ASP.NET в Rider: хост приложения, настройки сервиса по умолчанию, пустое приложение, стартовое приложение, тестовые приложения.
• Управление службами и отладка в Rider: перезапуск, остановка, подключение отладчика. • Использование панели мониторинга для отслеживания состояния приложений.
• Установка расширения C# DevKit в VS Code. • Создание проекта ASP.NET через Ctrl + Shift + P или через «Новый проект». • Выбор шаблона ASP.NET и создание нового приложения.
• Microsoft улучшила формат файлов CS Proj, но файл SLN остался устаревшим. • Новый формат SLNX более чистый и не содержит идентификаторов GUID.
• В C# DevKit есть панель Solution Explorer для управления проектами. • Можно строить, отлаживать и просматривать зависимости проектов.
• Приложение запускается через панель управления ASP.NET. • Доступны данные о состоянии приложения.
• Используется проект Oh My Posh для настройки терминала. • Отображаются информация о Git, Docker, Kubernetes и оперативная память.
• Команда для установки последних шаблонов проектов ASP.NET. • Фильтрация шаблонов по ASP.NET.
• Создание нового ASP.NET Starter проекта. • Запуск проекта через командную строку с помощью dot net run. • Переход на панель мониторинга через Ctrl+Click.
• Анонс новой версии ASP.NET CLI 9.2. • Обещание рассказать об этом в следующем видео.
• Вышла новая версия Aspire 9.2. • Представлен новый интерфейс Aspire CLI. • Это предварительный просмотр, который может измениться.
• Документация содержит команду для установки. • Автор использует псевдоним для команды Aspire.
• Возможность создания нового проекта. • Добавление элементов интеграции. • Публикация результатов для развёртывания приложения.
• Запуск приложения с помощью команды aspire run
.
01:35 Управление ресурсами
• Таблица со статусом ресурсов. • Разные типы ресурсов, о которых будет рассказано позже.
• Переход на панель управления через ссылки. • Закрытие хостинга приложения с помощью Ctrl+C. • Обещание более подробного рассмотрения панели управления в следующем видео.
• Приборная панель создана с помощью Blazor и библиотеки Fluent UI. • Возможность выбора светлого или тёмного режима, а также изменения языка. • Функция удаления телеметрии для локальной разработки.
• Левая сторона панели содержит различные панели и ресурсы. • Окно консоли для просмотра необработанных логов. • Структурированные логи с возможностью просмотра подробной информации.
• Имя ресурса, статус, время запуска и исходная информация. • Кликабельные URL-адреса и действия для запуска и остановки ресурсов. • Просмотр деталей и копирование значений в буфер обмена.
• Возможность пометить ресурсы как постоянные для сохранения данных при перезапуске панели мониторинга. • Фильтры для выбора ресурсов по состоянию и проверке работоспособности.
03:30 Визуализация зависимостей
• График для визуализации иерархии ресурсов. • Пример зависимостей: база данных, сервер, миграция Entity Framework, API, интерфейсное приложение, рейтинговая служба, кэш Redis.
• Фильтры для журналов консоли, приостановка и удаление ресурсов. • Переключение временных меток UTC или местное время. • Глобальное удаление журналов для очистки данных.
• Горячие клавиши для быстрого перехода между страницами и изменения размера панелей.
• Возможность запуска автономной версии приборной панели в Docker. • Интеграция с OpenTelemetry для локальной разработки.
• Подведение итогов по приборной панели Aspire. • Анонс следующего модуля о преимуществах использования Aspire и создании приложения с помощью Aspiring.
7 Итак, зачем использовать Aspire
• Знакомство с кодовой базой приложения для подкастов. • Основные преимущества ASP.NET: поддержка OpenTelemetry из коробки и локальная панель мониторинга.
• Трассировки становятся привычкой вместо использования журналов. • Панель мониторинга в ASP.NET доступна из коробки, без необходимости ручной настройки.
• Возможность запуска приложения с запущенными контейнерами Docker. • Пример с новым разработчиком: клонирование репозитория и запуск приложения.
• Доступ к образцам ASP.NET на GitHub. • Примеры для Azure Functions, JavaScript, Node.js, Python.
• Запуск приложения через dot net run. • Ожидание запуска зависимостей, использование кэшированных версий образов Docker.
• Новые пакеты NuGet для интеграции технологий: SQL Server, PostgreSQL, Redis, RabbitMQ. • Упрощение подключения сервисов через ASP.NET Service Discovery.
• Обсуждение развёртывания в будущих версиях ASP.NET. • Текущая незрелость аспекта развёртывания. • Активное использование ASP.NET локально без развёртывания.
• Переход к рассмотрению кода приложения для подкастов. • Использование Docker Compose для расширения базы данных. • Одухотворение приложения по мере работы над модулем.
8 Представляем веб-приложение для перечисления подкастов
• База кода доступна на GitHub: https://github.com/dotnet-train/aspire. • Репозиторий пока частный, но станет публичным после выпуска курса.
• Структура папок может измениться перед выпуском, но будет похожа на текущую. • Для каждого модуля есть отдельный каталог, содержащий копию кодовой базы. • Функциональность будет расширяться по мере прохождения курса.
• Веб-API возвращает список подкастов с помощью Entity Framework. • Строка подключения к базе данных получена из конфигурации. • Используются имя пользователя и пароль для доступа к базе данных.
• Сущности Entity Framework: подкаст с идентификатором, названием и контекстом базы данных. • Интерфейс — проект Blazor с рендерингом на стороне сервера. • Главная страница отображает список подкастов.
• Файл Docker Compose определяет базу данных и запускает контейнер. • Локальный файл Docker ожидает готовности базы данных и запускает SQL-скрипт. • Скрипт создаёт таблицу «подкаст» и заполняет её данными.
• Запуск API и интерфейса с помощью Docker Compose и Rider. • Возможность многопользовательского запуска в Rider.
• Приложение отображает список подкастов после нажатия кнопки «Получить подкасты». • Планируется добавление Redis для рейтинга подкастов. • В следующем видео будет показано, как добавить ASP.NET в существующее приложение.