Qwen, Aspire, Gateway, Http
https://chat.qwen.ai/s/75eecb49-01e6-446f-8953-2f35f9d9d9b8?fev=0.2.91
https://chat.qwen.ai/s/75eecb49-01e6-446f-8953-2f35f9d9d9b8?fev=0.2.91
Ниже — честный черновик описания системы в формате обсуждения. Я заполняю только то, что реально подтверждается вашими диалогами и кодом из
Trading.txt. Там, где фактов нет, я прямо пишу: «пропускаю» или «нет данных».Важная оговорка: сейчас это не продакшен-система, а архитектурный прототип / каркас. Поэтому многие пункты про KPI, экономику, эксплуатацию и отзывы пользователей заполнить без выдумок нельзя.
Сводная таблица: «Как было / Как задумывалось / Что получили»
1. Контекст и отправная точка
Бизнес-проблема
В предоставленных материалах нет описания конкретной старой бизнес-системы, поэтому честно можно сказать так:
Исходная боль — не конкретный легаси-продукт, а архитектурная проблема построения взаимодействия между проектами внутри .NET Aspire без избыточного усложнения.
Основная боль, которую видно из диалогов:
- сервисов становится больше;
- прямые связи превращаются в спагетти
N × N; - разработчики начинают добавлять RabbitMQ / MassTransit / Kafka туда, где это пока не нужно;
- архитектура становится неявной;
- связи существуют не как закон, а как договоренность;
- сложно понять, кто кого вызывает, где падает запрос и почему система деградирует.
Если формулировать коротко:
Нужно было сделать взаимодействие между Aspire-проектами простым, наблюдаемым, управляемым и не превращающимся в хаос.
Существующее решение
Если считать «старым» типовой подход, который обсуждался, то он выглядел примерно так:
- каждый сервис может напрямую вызывать другой сервис;
- для асинхронности сразу добавляется RabbitMQ / Kafka / MassTransit;
- фронтенд может ходить в несколько backend-сервисов напрямую;
- топология существует в голове разработчиков или в устаревших схемах;
- наблюдаемость приходится отдельно склеивать логами, трейсами и метриками.
В текущем репозитории уже использованы:
.NET 10;Aspire.Hosting/Aspire.AppHost.Sdk 13.4.6;ASP.NET Core;YARP Reverse Proxy 2.3.0;Microsoft.Extensions.ServiceDiscovery.Yarp 10.0.0;OpenTelemetry;Blazor Web/ Interactive Server;Trading.ServiceDefaultsкак общий слой для здоровья, телеметрии и resilience.
Критические недостатки старого подхода
Из диалогов и архитектурного смысла следуют такие недостатки:
- Спагетти-связи
ServiceA -> ServiceB ServiceB -> ServiceC ServiceC -> ServiceA ServiceD -> ServiceB ...
При росте числа сервисов система становится непонятной.
- Избыточная инфраструктура Например:
csharp
только для того, чтобы два сервиса могли обмениваться простыми сообщениями.
- Неявная топология
Разработчик может написать прямой
HttpClient-вызов, и это не будет видно из манифеста архитектуры. - Отсутствие физического контроля связей В старой модели безопасность и границы контролируются договоренностями, код-ревью или внешними сетевыми политиками.
- Плохая наблюдаемость сквозных сценариев Если запрос идет через несколько сервисов, без единого трейса сложно понять, где именно проблема.
Ограничения среды
Конкретных данных нет:
- бюджет: пропускаю;
- регуляторные требования: пропускаю;
- требования к унаследованным данным: пропускаю;
- ограничения по команде и срокам: пропускаю.
Но можно указать качественное ограничение:
Система начиналась как локальный / экспериментальный Aspire-прототип, поэтому нужно было избежать тяжелых внешних зависимостей вроде RabbitMQ, Kafka, отдельного Service Mesh и сложной инфраструктуры.
2. Концепция и цели
Формулировка гипотезы
Главная гипотеза проекта:
Если ввести центральныйGatewayкак полноценный Aspire-проект и задать все связи черезAppHost, то архитектура станет управляемой, наблюдаемой и защищенной от случайного усложнения.
Более точная формулировка:
Если фронтенд будет обращаться только кGateway, аGatewayбудет единственным маршрутизатором к бизнес-сервисам, то система перейдет от хаотичной моделиN × Nк управляемой модели Hub-and-Spoke.
Или совсем коротко:
Архитектура должна быть не диаграммой в документации, а исполняемым законом среды.
Ключевые метрики успеха
Фактических производственных метрик пока нет, поэтому конкретные цифры по задержкам, памяти, нагрузке и конверсии я пропускаю.
Но уже можно зафиксировать структурные показатели, которые подтверждают архитектурный результат.
Например:
Для будущего обсуждения можно предложить такие KPI:
- время обнаружения причины сбоя по трейсу;
- количество прямых зависимостей между бизнес-сервисами;
- число вызовов фронтенда к внутренним сервисам в обход Gateway;
- средняя задержка запроса через Gateway;
- процент успешных запросов;
- количество ошибок 5xx на маршрутах;
- время онбординга нового разработчика до понимания топологии системы.
Но реальных цифр пока нет.
Нереализованные альтернативы
Из диалогов видно, что рассматривались разные варианты.
1. RabbitMQ / MassTransit
Почему отложили:
- избыточно для простых внутренних взаимодействий;
- добавляет инфраструктурную сложность;
- появляется очередь, обменники, дедупликация, идемпотентность;
- для сценария «сервис А вызывает сервис Б» это часто слишком много.
2. NATS
Почему рассматривался:
- легкий брокер;
- высокая скорость;
- хорошо подходит для Pub/Sub.
Почему пока не выбран:
- все равно появляется отдельный инфраструктурный компонент;
- на первом этапе проще проверить модель через HTTP.
3. SignalR для server-to-server
Почему рассматривался:
- удобен для push-доставки;
- хорош для клиентских обновлений.
Почему не подходит как основной транспорт между сервисами:
- нет гарантий доставки как у очереди;
- при падении получателя сообщения могут теряться;
- масштабирование сложнее;
- лучше подходит для связи
сервер -> клиент, а несервис -> сервис.
4. Распределенный MediatR
Почему рассматривался:
- знакомая модель;
- хорошо работает внутри процесса.
Почему не подходит напрямую между Aspire-проектами:
- разные процессы имеют разные медиатор-шины;
- для межпроцессного вызова нужен транспорт;
- приходится строить распределенный механизм поверх.
5. WolverineFx
Почему рассматривался:
- «умный» аналог MediatR;
- умеет локальный и распределенный вызов;
- имеет паттерн Outbox;
- хорошо подходит для надежной асинхронной доставки.
Почему пока не внедрен:
- это уже следующий уровень сложности;
- сначала нужно закрепить простой и понятный HTTP-каркас;
- пока нет реальной потребности в гарантированной асинхронной федерации.
6. Модульный монолит
Почему рассматривался:
- минимум сетевой сложности;
- максимальная скорость;
- простая отладка.
Почему не выбран как текущая основа:
- проект уже ориентирован на распределенные сервисы;
- интересна именно модель управляемой федерации сервисов под Aspire.
Границы проекта
На текущем этапе намеренно решили не делать:
- полноценную базу данных;
- аутентификацию и авторизацию;
- риск-менеджмент;
- реальный matching engine;
- стаканы ордеров;
- Outbox / транзакционную доставку;
- Wolverine;
- RabbitMQ / Kafka;
- SignalR;
- интеграционные тесты;
- CI/CD;
- production-деплой;
- идемпотентность команд;
- версионирование контрактов;
- общий проект контрактов;
- нагрузочное тестирование.
Это правильно, потому что проект находится на этапе проверки архитектурной идеи.
3. Инновационность и новизна
Относительно рынка
Сами технологии не являются уникальными:
- YARP существует;
- Aspire существует;
- OpenTelemetry существует;
- HTTP как транспорт существует давно;
- паттерн API Gateway известен;
- BFF известен;
- Hub-and-Spoke известен.
Новизна здесь не в одной технологии, а в их комбинации и архитектурной философии.
Ключевая новизна:
.NET Aspire AppHostиспользуется не просто как лаунчер, а как исполняемый конституционный закон топологии системы.
Или:
Архитектура становится не документацией, а средой исполнения, которая физически мешает сделать неправильную связь.
Комментариев нет:
Отправить комментарий