Общий код между сервисами: shared kernel, NuGet-пакеты, базовые образы
↑ 8.3 Микросервисы и распределённые системы · ← Предыдущая · → Следующая
Зачем это на собесе
Как делиться кодом между сервисами и не создать «распределённый монолит через библиотеки».
Объяснение
| Что делиться | Как | Риск |
|---|---|---|
| Контракты (DTO, события, proto) | пакеты Company.Orders.Contracts, генерация из proto/OpenAPI | версионирование, обратная совместимость |
| Технические кросс-каттинг (логирование, OTel, resilience, auth) | внутренние NuGet-пакеты «платформы» | принудительные обновления |
| Утилиты | пакеты с узкой ответственностью | «Common» превращается в свалку |
| Доменная модель | обычно не делится | связанность, единый релиз |
| Базовые Docker-образы | общий core-образ (сертификаты, шрифты, инструменты) | единая точка обновления |
| Шаблоны проектов/пайплайнов | dotnet new шаблон, шаблоны CI | дрейф от шаблона |
Shared Kernel (DDD) — небольшая общая часть модели, за которую совместно отвечают команды; осознанный компромисс, а не по умолчанию.
Правила пакетов:
- Семантическое версионирование; ломающие изменения — major.
- Приватный NuGet-фид (GitLab/GitHub Packages, Azure Artifacts).
- Центральное управление версиями:
Directory.Packages.props. - Контрактные пакеты содержат только типы, без логики.
- Сервисы обновляют пакеты независимо; поддерживайте совместимость нескольких версий.
<!-- Directory.Packages.props -->
<Project>
<PropertyGroup><ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally></PropertyGroup>
<ItemGroup>
<PackageVersion Include="Company.Platform.Observability" Version="2.3.1" />
</ItemGroup>
</Project>Нюансы и подводные камни
- Общий доменный код заставляет деплоить сервисы синхронно.
- «Common»/«Shared» проект без владельца быстро растёт и связывает всех.
- Разные версии пакетов в сервисах: конфликты сериализации, различие в поведении.
- Лучше немного дублирования, чем сильная связанность через общий код.
- Общий образ: не перегружайте лишними инструментами (безопасность, размер).
Практика
- Вынесите наблюдаемость и resilience в платформенный пакет.
- Настройте приватный NuGet-фид и CI публикации пакетов.
- Сравните генерацию клиентов из OpenAPI и общий контрактный пакет.
Вопросы с ответами
Что можно делить между сервисами?
Контракты и техническую платформу; доменную модель обычно нет.
Что такое Shared Kernel?
Общее подмножество доменной модели, совместно владеемое несколькими командами.