четверг, 30 июля 2026 г.

Dapr, Start Project, Aspire, AppHost

Dapr, Start Project, Aspire, AppHost

https://chat.deepseek.com/a/chat/s/7687913a-329e-41d3-8e09-fd83eb9e9de1

Описанная ситуация — вы запускаете не AppHost, а проект ApiService.
В логах видны адреса https://localhost:7539 и http://localhost:5452 — это порты ApiService, а не оркестратора. Панель управления Aspire (Dashboard) запускается только при старте AppHost.

🔍 Что происходит

  • В решении несколько проектов, и по умолчанию (или случайно) активным выбран AspireApp1.ApiService.

  • Вы нажимаете F5 / Ctrl+F5 → запускается только API-сервис, в консоли отображаются его логи.

  • Сам AppHost не стартует → Dashboard не появляется, другие ресурсы (WebFrontend) не поднимаются.

  • Именно поэтому «висит» — API-сервис запущен, но веб-интерфейса нет, а AppHost некому запустить.

✅ Решение

  1. Сделайте проект AspireApp1.AppHost стартовым:

    • В Solution Explorer правый клик на AspireApp1.AppHostSet as Startup Project.

    • Убедитесь, что файл AppHost.cs открыт или в списке проектов выделен AppHost.

  2. Запустите решение (F5 или Ctrl+F5).
    Теперь в консоли вы увидите:

    text
    info: Aspire.Hosting.DistributedApplication[0]
          Now listening on: https://localhost:17008

    и браузер автоматически откроет Aspire Dashboard по этому адресу.

📝 Пояснения

  • Dashboard (веб-панель Aspire) — это встроенный UI, показывающий состояние всех ресурсов, логи, трассировку. Он запускается внутри процесса AppHost.

  • Проект AppHost (AspireApp1.AppHost.csproj) — консольное приложение, которое поднимает Dashboard и управляет остальными сервисами.

  • Проекты ApiService и Web не могут самостоятельно запустить Dashboard.

🧹 Что ещё можно проверить (если после смены стартового проекта не заработает)

  • В AppHost.cs полностью удалён закомментированный вызов Dapr – текущий код корректен.

  • В launchSettings.json AppHost должно быть "launchBrowser": true (уже есть).

  • Убедитесь, что Redis не конфликтует портом – используется 6380, это нормально.

  • Dashboard может не открыться, если в системе не хватает сертификатов для HTTPS — тогда временно переключитесь на профиль http в launchSettings AppHost (там порт 15141).
    Для этого в Visual Studio в выпадающем списке рядом с кнопкой запуска выберите http вместо https.

---------------------------------------------------------------------------------------------------------

🟢 Работа с Dapr в PowerShell: что нужно знать

Ваш стартовый набор правильный — dapr init выполняется один раз для подготовки локального окружения. Дальше всё зависит от того, как вы запускаете приложения.

1. Первый запуск: инициализация

powershell
dapr init
  • Устанавливает контейнеры Docker: dapr_redis (state store/pubsub), dapr_zipkin (трассировка), dapr_placement (сервис actor).

  • После этого dapr готов к работе.

Если Docker не нужен, можно использовать облегчённый режим:
dapr init --slim — без контейнеров, только бинарники sidecar.

2. Проверка статуса

powershell
dapr status

Показывает, запущены ли placement, Redis, Zipkin и общее состояние среды.

3. Запуск приложений (без Aspire)

Если вы запускаете приложение вручную:

powershell
dapr run --app-id myapp --app-port 5000 --dapr-http-port 3500 -- dotnet run

Но в вашем Aspire-проекте это не требуется — сайдкары запускаются и останавливаются автоматически через .WithDaprSidecar().

4. Сборка и остановка

  • Остановка сайдкаров вручную (если запускали через dapr run):
    dapr stop <app-id>

  • Остановка всей среды Dapr (удаление контейнеров, если вы инициализировали через dapr init):
    dapr uninstall
    после этого нужно будет снова сделать dapr init, если Dapr ещё нужен.

  • При работе с Aspire достаточно закрыть AppHost (Ctrl+C) — все сайдкары завершатся автоматически.

5. Просмотр логов сайдкара

powershell
dapr logs <app-id>

Удобно, если нужно проверить, как обрабатываются pub/sub или state-запросы.

6. Панель мониторинга (Dashboard)

  • Раньше была dapr dashboard, сейчас рекомендуется использовать Zipkin для трейсинга (он запускается при dapr init). Zipkin доступен по умолчанию на http://localhost:9411.

  • В Aspire вы получаете полную приборную панель, поэтому отдельная Dapr Dashboard не нужна.

7. Ручное тестирование Pub/Sub

Можно публиковать события прямо из консоли, не запуская приложение-отправитель:

powershell
dapr publish --pubsub pubsub --topic forecast-generated --data '{"ForecastCount":5, "AverageTempC":10}'

8. Компоненты (компоненты Dapr)

  • Файлы конфигурации (state store, pubsub, bindings) по умолчанию лежат в %USERPROFILE%\.dapr\components.

  • При использовании Aspire с интеграцией Dapr можно размещать компоненты рядом с проектом, а в AppHost указывать через .WithDaprSidecar("apiservice", dapr => dapr.WithResourcesPath("../components")) — это удобнее.

9. Важный нюанс для вашего проекта

Вы используете CommunityToolkit.Aspire.Hosting.Dapr. Когда раскомментируете builder.AddDapr() и .WithDaprSidecar(), ни в коем случае не запускайте дополнительно dapr run — Aspire сам поднимет и настроит сайдкары для каждого сервиса. Двойной запуск приведёт к конфликтам портов.

10. Чего точно не надо делать каждый раз

  • Повторно выполнять dapr init — только если вы удаляли окружение (dapr uninstall).

  • Вручную поднимать dapr run для проектов, которыми управляет Aspire.

Если всё работает через AppHost — вы на правильном пути. Dapr CLI вам понадобится в основном для dapr status, просмотра логов и отладки.

Start, AppHost

Start, AppHost

https://chat.deepseek.com/share/ytqllzdymhe27olnt4

🟢 Работа с Dapr в PowerShell: что нужно знать

Ваш стартовый набор правильный — dapr init выполняется один раз для подготовки локального окружения. Дальше всё зависит от того, как вы запускаете приложения.

1. Первый запуск: инициализация

powershell
dapr init
  • Устанавливает контейнеры Docker: dapr_redis (state store/pubsub), dapr_zipkin (трассировка), dapr_placement (сервис actor).

  • После этого dapr готов к работе.

Если Docker не нужен, можно использовать облегчённый режим:
dapr init --slim — без контейнеров, только бинарники sidecar.

2. Проверка статуса

powershell
dapr status

Показывает, запущены ли placement, Redis, Zipkin и общее состояние среды.

3. Запуск приложений (без Aspire)

Если вы запускаете приложение вручную:

powershell
dapr run --app-id myapp --app-port 5000 --dapr-http-port 3500 -- dotnet run

Но в вашем Aspire-проекте это не требуется — сайдкары запускаются и останавливаются автоматически через .WithDaprSidecar().

4. Сборка и остановка

  • Остановка сайдкаров вручную (если запускали через dapr run):
    dapr stop <app-id>

  • Остановка всей среды Dapr (удаление контейнеров, если вы инициализировали через dapr init):
    dapr uninstall
    после этого нужно будет снова сделать dapr init, если Dapr ещё нужен.

  • При работе с Aspire достаточно закрыть AppHost (Ctrl+C) — все сайдкары завершатся автоматически.

5. Просмотр логов сайдкара

powershell
dapr logs <app-id>

Удобно, если нужно проверить, как обрабатываются pub/sub или state-запросы.

6. Панель мониторинга (Dashboard)

  • Раньше была dapr dashboard, сейчас рекомендуется использовать Zipkin для трейсинга (он запускается при dapr init). Zipkin доступен по умолчанию на http://localhost:9411.

  • В Aspire вы получаете полную приборную панель, поэтому отдельная Dapr Dashboard не нужна.

7. Ручное тестирование Pub/Sub

Можно публиковать события прямо из консоли, не запуская приложение-отправитель:

powershell
dapr publish --pubsub pubsub --topic forecast-generated --data '{"ForecastCount":5, "AverageTempC":10}'

8. Компоненты (компоненты Dapr)

  • Файлы конфигурации (state store, pubsub, bindings) по умолчанию лежат в %USERPROFILE%\.dapr\components.

  • При использовании Aspire с интеграцией Dapr можно размещать компоненты рядом с проектом, а в AppHost указывать через .WithDaprSidecar("apiservice", dapr => dapr.WithResourcesPath("../components")) — это удобнее.

9. Важный нюанс для вашего проекта

Вы используете CommunityToolkit.Aspire.Hosting.Dapr. Когда раскомментируете builder.AddDapr() и .WithDaprSidecar(), ни в коем случае не запускайте дополнительно dapr run — Aspire сам поднимет и настроит сайдкары для каждого сервиса. Двойной запуск приведёт к конфликтам портов.

10. Чего точно не надо делать каждый раз

  • Повторно выполнять dapr init — только если вы удаляли окружение (dapr uninstall).

  • Вручную поднимать dapr run для проектов, которыми управляет Aspire.

Если всё работает через AppHost — вы на правильном пути. Dapr CLI вам понадобится в основном для dapr status, просмотра логов и отладки.


среда, 29 июля 2026 г.

Install, DAPR

Install, DAPR

PowerShell 7.6.4

PS C:\Users\Administrator> winget install Dapr.CLI

Found Dapr CLI [Dapr.CLI] Version 1.18.0

This application is licensed to you by its owner.

Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.

Downloading https://github.com/dapr/cli/releases/download/v1.18.0/dapr.msi

  ██████████████████████████████  54.1 MB / 54.1 MB

Successfully verified installer hash

Starting package install...

Successfully installed

-------------------------------------

После установки инициализируйте Dapr:

PS C:\Users\Administrator> pwsh

PowerShell 7.6.4

PS C:\Users\Administrator> dapr init

Making the jump to hyperspace...

Container images will be pulled from Docker Hub

Installing runtime version 1.18.2

Downloading binaries and setting up components...

Temporarily shutting down WSL to free ports for scheduler installation...

docker: request returned 500 Internal Server Error for API route and version http://%!F(MISSING)%!F(MISSING).%!F(MISSING)pipe%!F(MISSING)dockerDesktopLinuxEngine/v1.55/containers/create?name=dapr_zipkin, check if the server supports the requested API version

Run 'docker run --help' for more information

PS C:\Users\Administrator>

-----------------------------------------------------

Dapr, Sidecar

🚀 Dapr и Sidecar — что это и когда используется

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

🎯 Сначала про паттерн Sidecar

Sidecar (сайдкар, "коляска") — это архитектурный паттерн, где рядом с основным сервисом запускается вспомогательный процесс, который берёт на себя "инфраструктурные" задачи.
Зачем это нужно?
  • Ваш код не знает про инфраструктуру (брокер сообщений, БД, секреты)
  • Sidecar предоставляет стандартизированный API (например, HTTP localhost:3500)
  • Можно менять инфраструктуру без изменения кода

🧩 Что такое Dapr?

Dapr (Distributed Application Runtime) — это open-source проект от Microsoft, который реализует паттерн Sidecar для микросервисов.

Dapr предоставляет готовые "строительные блоки":

Building Block
Что делает
🔌 Service-to-Service
Вызовы между сервисами с mTLS и retry
🗂️ State Management
Хранение состояния (Redis, Cosmos DB, SQL)
📨 Pub/Sub
Очереди сообщений (RabbitMQ, Kafka, Azure Service Bus)
🔐 Secrets
Работа с секретами (Vault, Azure Key Vault)
🔗 Bindings
Интеграция с внешними системами (AWS S3, SMTP)
👥 Actors
Паттерн Virtual Actors (как в Orleans)
🔄 Workflows
Оркестрация долгоживущих процессов

⚖️ Aspire vs Dapr — сравнение

Характеристика
Aspire
Dapr
Когда работает
Разработка и развёртывание
Runtime (продакшн)
Где живёт
AppHost (оркестратор)
Sidecar рядом с каждым сервисом
Что решает
"Как запустить все сервисы вместе?"
"Как сервисы общаются?"
Service Discovery
✅ Есть
✅ Есть (другой механизм)
State Management
❌ Нет
✅ Есть
Pub/Sub
❌ Нет
✅ Есть
Secrets
⚠️ Базовый
✅ Продвинутый
Observability
✅ OpenTelemetry
✅ OpenTelemetry
Облачная привязка
Azure-ориентированный
Cloud-agnostic

💡 Главное различие:

  • Aspire = инструмент разработчика для создания cloud-native приложений
  • Dapr = runtime-библиотека, которая работает в продакшене рядом с вашими сервисами

🤝 Можно ли использовать Aspire + Dapr вместе?

ДА! Они отлично дополняют друг друга. Начиная с .NET 8, у Aspire есть официальная поддержка Dapr.
var builder = DistributedApplication.CreateBuilder(args); // Добавляем Dapr sidecar к каждому сервису var apiService = builder.AddProject<Projects.AspireApp1_ApiService>("apiservice") .WithDaprSidecar("apiservice"); // 👈 Запустится Dapr sidecar var web = builder.AddProject<Projects.AspireApp1_Web>("webfrontend") .WithDaprSidecar("webfrontend") // 👈 И здесь тоже .WithReference(apiService); // Dapr components (Pub/Sub брокер, State Store) builder.AddDaprComponent("statestore", "state.redis", new Dictionary<string, string> { ["redisHost"] = "localhost:6379" }); builder.AddDaprComponent("pubsub", "pubsub.rabbitmq", new Dictionary<string, string> { ["host"] = "amqp://localhost:5672" });
Тогда при запуске у вас будет в 2 раза больше процессов:
apiservice (ваш .NET код) └─ apiservice-dapr (Dapr sidecar) webfrontend (ваш Blazor) └─ webfrontend-dapr (Dapr sidecar) Redis (кэш и state store) RabbitMQ (брокер сообщений)

🎯 Когда использовать Dapr?

✅ Случаи, когда Dapr — правильный выбор:

  1. Много микросервисов на разных языках (.NET + Python + Node.js + Go)
    • Dapr даёт одинаковый API для всех
  2. Частая смена инфраструктуры
    • Сегодня RabbitMQ, завтра Kafka — код не меняется
    • Сегодня Redis, завтра Cosmos DB — код не меняется
  3. Нужны готовые паттерны распределённых систем
    • Pub/Sub с гарантированной доставкой
    • Actor model (Virtual Actors)
    • Workflows с компенсирующими транзакциями (Saga)
  4. Мульти-облачные развёртывания
    • Один код → Azure, AWS, GCP, on-premise

❌ Случаи, когда Dapr — избыточен:

  1. Монолит или 2-3 сервиса (как ваш проект сейчас)
    • Aspire + HttpClient достаточно
  2. Вся команда на .NET
    • Встроенные средства .NET (gRPC, MassTransit) проще
  3. Простые сценарии без очередей/акторов
    • Лишняя сложность

🔍 Реальный сценарий на базе вашего проекта

Представим, что ваш проект вырос:
Сегодня (Aspire only): ┌──────────┐ HTTP ┌────────────┐ │ Web │────────────│ ApiService │ └──────────┘ └────────────┘ │ └── Генерирует случайные данные Завтра (Aspire + Dapr): ┌──────────┐ ┌────────────┐ ┌──────────────┐ │ Web │◄─ Pub/Sub ──►│ ApiService │◄─ Pub/Sub ──►│ Notification │ │ (Blazor) │ │ │ │ Service │ └──────────┘ └────────────┘ └──────────────┘ │ │ │ └── State Store ───► [ Redis ] ◄── State Store ────────┘
Что изменилось: ApiService публикует событие weather-forecast-generated в Pub/Sub Notification Service подписывается на событие и отправляет email/пуш Web сохраняет последнюю порцию прогнозов в State Store Если ApiService упадёт — Notification Service всё равно получит событие (брокер буферизует) Весь этот сценарий не требует изменения бизнес-логики сервисов — только настройки Dapr-компонентов. 📊 Сводная таблица решений Ваш проект Что использовать Простой Blazor + API (как сейчас) ✅ Только Aspire Добавляем кэш, БД, очередь ⚠️ Aspire + библиотеки (StackExchange.Redis, MassTransit) 10+ микросервисов на разных языках 🎯 Aspire + Dapr Нужны Virtual Actors, Workflows 🎯 Dapr (или Orleans) Мульти-облако, частая смена инфраструктуры 🎯 Dapr 💡 Итог Sidecar — это архитектурный паттерн (разделение кода и инфраструктуры) Dapr — это реализация этого паттерна с готовыми building blocks Aspire — это инструмент разработки для оркестрации всего этого В вашем текущем проекте Dapr не нужен — Aspire отлично справляется. Но когда проект вырастет до настоящих микросервисов с очередями, акторами и мульти-облачной архитектурой — Dapr станет очень кстати. 🚀 Хотите попробовать? Могу показать: 🔧 Как добавить Dapr в ваш проект прямо сейчас (пошагово) 📨 Как реализовать Pub/Sub (ApiService публикует прогноз → Web получает через очередь) 💾 Как использовать Dapr State Management вместо прямого Redis 🎭 Dapr Actors для реализации "умного" прогнозирования с памятью
🚀 Добавляем Dapr в ваш Aspire проект Отлично! Давайте интегрируем Dapr в ваш проект. Это превратит его из простого демо в полноценное микросервисное приложение с sidecar-паттерном. 📋 Предварительные требования Сначала установите Dapr CLI: Windows:
winget install Dapr.CLI
dapr init
Шаг 1: Обновляем AppHost.csproj Добавьте пакет Dapr в AspireApp1.AppHost.csproj:
<ItemGroup> <PackageReference Include="Aspire.Hosting.Dapr" Version="13.4.6" /> <PackageReference Include="Aspire.Hosting.Redis" Version="13.4.6" /> </ItemGroup>
Шаг 2: Обновляем AppHost.cs Замените содержимое AppHost.cs на это:
var builder = DistributedApplication.CreateBuilder(args); // Redis для кэширования и state management var cache = builder.AddRedis("cache"); // Dapr components (опционально, но полезно) var stateStore = builder.AddDaprComponent("statestore", "state.redis", new Dictionary<string, string> { ["redisHost"] = "localhost:6379", ["redisPassword"] = "" }); // ApiService с Dapr sidecar var apiService = builder.AddProject<Projects.AspireApp1_ApiService>("apiservice") .WithHttpHealthCheck("/health") .WithDaprSidecar("apiservice"); // 👈 Dapr sidecar запускается рядом // Web с Dapr sidecar builder.AddProject<Projects.AspireApp1_Web>("webfrontend") .WithExternalHttpEndpoints() .WithHttpHealthCheck("/health") .WithDaprSidecar("webfrontend") // 👈 И здесь тоже .WithReference(cache) .WaitFor(cache) .WithReference(apiService) .WaitFor(apiService); builder.Build().Run();
Что изменилось:
  • .WithDaprSidecar("apiservice") — запускает Dapr sidecar рядом с ApiService
  • .WithDaprSidecar("webfrontend") — запускает Dapr sidecar рядом с Web
  • Добавлен Dapr component для state management (использует Redis)

🔧 Шаг 3: Обновляем ApiService/Program.cs

Теперь ApiService будет использовать Dapr для вызовов:
var builder = WebApplication.CreateBuilder(args); // Add service defaults & Aspire client integrations. builder.AddServiceDefaults(); // Add services to the container. builder.Services.AddProblemDetails(); builder.Services.AddOpenApi(); var app = builder.Build(); app.UseExceptionHandler(); if (app.Environment.IsDevelopment()) { app.MapOpenApi(); } string[] summaries = ["Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"]; app.MapGet("/", () => "API service is running. Navigate to /weatherforecast to see sample data."); app.MapGet("/weatherforecast", () => { var forecast = Enumerable.Range(1, 5).Select(index => new WeatherForecast ( DateOnly.FromDateTime(DateTime.Now.AddDays(index)), Random.Shared.Next(-20, 55), summaries[Random.Shared.Next(summaries.Length)] )) .ToArray(); // Логируем через Dapr (видимо в Aspire Dashboard) app.Logger.LogInformation("Generated weather forecast for {Count} days", forecast.Length);
return forecast; }) .WithName("GetWeatherForecast"); app.MapDefaultEndpoints(); app.Run(); record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) { public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); }
 Шаг 4: Обновляем Web/WeatherApiClient.cs Теперь Web будет вызывать ApiService через Dapr sidecar:
namespace AspireApp1.Web;

public class WeatherApiClient(HttpClient httpClient, ILogger<WeatherApiClient> logger)
{
    public async Task<WeatherForecast[]> GetWeatherAsync(int maxItems = 10, CancellationToken cancellationToken = default)
    {
        // ВАЖНО: Dapr sidecar слушает на localhost:3500
        // Но Aspire автоматически настраивает правильный порт
        // Мы используем специальный формат: http://localhost:<dapr-port>/v1.0/invoke/<app-id>/method/<endpoint>
        
        logger.LogInformation("Requesting weather forecast via Dapr");
        
        List<WeatherForecast>? forecasts = null;
        
        // Aspire + Dapr: используем стандартный service discovery
        // Dapr sidecar автоматически проксирует запросы
        await foreach (var forecast in httpClient.GetFromJsonAsAsyncEnumerable<WeatherForecast>("/weatherforecast", cancellationToken))
        {
            if (forecasts?.Count >= maxItems)
            {
                break;
            }
            if (forecast is not null)
            {
                forecasts ??= [];
                forecasts.Add(forecast);
            }
        }
        
        logger.LogInformation("Received {Count} forecasts", forecasts?.Count ?? 0);
        return forecasts?.ToArray() ?? [];
    }
}

public record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
Шаг 5: Добавляем Dapr State Management (бонус!) Давайте используем Dapr для сохранения последней порции прогнозов. Обновите ApiService/Program.cs:
var builder = WebApplication.CreateBuilder(args); builder.AddServiceDefaults(); builder.Services.AddProblemDetails(); builder.Services.AddOpenApi(); // Добавляем Dapr SDK для работы с sidecar builder.Services.AddDaprClient(); var app = builder.Build(); app.UseExceptionHandler(); if (app.Environment.IsDevelopment()) { app.MapOpenApi(); } string[] summaries = ["Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"]; app.MapGet("/", () => "API service is running. Navigate to /weatherforecast to see sample data."); app.MapGet("/weatherforecast", async (Dapr.Client.DaprClient daprClient, ILogger<Program> logger) => { var forecast = Enumerable.Range(1, 5).Select(index => new WeatherForecast ( DateOnly.FromDateTime(DateTime.Now.AddDays(index)), Random.Shared.Next(-20, 55), summaries[Random.Shared.Next(summaries.Length)] )) .ToArray(); // Сохраняем в Dapr State Store (использует Redis под капотом) await daprClient.SaveStateAsync("statestore", "latest-forecast", forecast); logger.LogInformation("Generated and saved weather forecast"); return forecast; }) .WithName("GetWeatherForecast"); // Новый эндпоинт: получить последнюю сохранённую порцию app.MapGet("/weatherforecast/latest", async (Dapr.Client.DaprClient daprClient) => { var forecast = await daprClient.GetStateAsync<WeatherForecast[]>("statestore", "latest-forecast"); return forecast ?? []; }) .WithName("GetLatestWeatherForecast"); app.MapDefaultEndpoints(); app.Run(); record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) { public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); }
Добавьте пакет в AspireApp1.ApiService.csproj:
<ItemGroup> <PackageReference Include="Dapr.AspNetCore" Version="1.14.0" /> </ItemGroup>
🎯 Шаг 6: Запускаем проект Откройте Docker Desktop В Visual Studio установите AspireApp1.AppHost как Startup Project Нажмите F5 Что вы увидите: В Docker Desktop:
redis (кэш и state store) aspire-dashboard
В процессах (не в Docker):
apiservice (ваш .NET код) apiservice-daprd (Dapr sidecar) webfrontend (ваш Blazor) webfrontend-daprd (Dapr sidecar)
В Aspire Dashboard (https://localhost:17008): Traces: увидите запросы через Dapr sidecar Logs: логи от обоих сервисов Metrics: метрики Dapr и вашего кода 🔍 Как проверить, что Dapr работает? 1. Откройте терминал и выполните:
  APP ID HTTP PORT APP PORT AGE CREATED DAPRD PID CLI PID apiservice 3500 5452 1m 2024-01-15 10:30:15 12345 12340 webfrontend 3501 7539 1m 2024-01-15 10:30:15 12346 12341
2. Прямой вызов через Dapr:
curl http://localhost:3500/v1.0/invoke/apiservice/method/weatherforecast
Что изменилось в архитектуре? Было (только Aspire):
Web ──HTTP──> ApiService ──> Генерация данных
Стало (Aspire + Dapr):
Web ──HTTP──> Web Dapr Sidecar ──mTLS──> ApiService Dapr Sidecar ──HTTP──> ApiService ↓ Dapr State Store (Redis)
Преимущества:
  • ✅ mTLS между сервисами (безопасность из коробки)
  • ✅ Retry и circuit breaker (через Dapr)
  • ✅ State management без привязки к Redis
  • ✅ Observability (все вызовы видны в трейсах)
  • ✅ Готовность к Pub/Sub, Actors, Workflows

🎓 Что можно добавить дальше?

  1. Pub/Sub: ApiService публикурует событие forecast-generated, Web подписывается
  2. Actors: Реализовать "умный" прогноз с памятью
  3. Resiliency: Настроить retry-политики в Dapr
  4. Secrets: Использовать Dapr Secrets API вместо appsettings
Хотите, чтобы я показал, как реализовать Pub/Sub (событийная архитектура) или Actors (умное прогнозирование)? 🚀
Копировать
Спроси Qwen
Объяснить
Перевести(ru-RU)