Mỗi service là một ứng dụng ĐỘC LẬP: riêng database, riêng deployment, riêng team. Phức tạp nhất nhưng scale tốt nhất.
Tổng Quan
Khi Nào Dùng / Không Dùng
| ✅ Dùng khi | ❌ Không dùng khi |
|---|---|
| Team > 15 devs, nhiều squads | Team < 10, single squad |
| Services cần scale ĐỘC LẬP (order vs search) | Mọi thứ scale cùng mức |
| Cần deploy RIÊNG BIỆT (hotfix 1 service) | Deploy cycle chung OK |
| Technology diversity cần thiết | Toàn bộ dùng .NET |
| Đã có DevOps/SRE team | Không có infra automation |
Dự án hay dùng: Large-scale eCommerce (Shopee, Lazada), Banking core, Ride-hailing, Streaming platforms.
Project Structure (Per Service)
order-service/
├── src/
│ ├── OrderService.Domain/
│ ├── OrderService.Application/
│ ├── OrderService.Infrastructure/
│ └── OrderService.API/
│ ├── Program.cs
│ ├── Dockerfile
│ └── appsettings.json
├── tests/
│ ├── OrderService.UnitTests/
│ └── OrderService.IntegrationTests/
├── order-service.sln
└── .github/workflows/
└── ci-cd.yml ← Riêng pipeline cho service này
solution-root/ ← Tổng thể (optional monorepo)
├── services/
│ ├── order-service/
│ ├── inventory-service/
│ ├── payment-service/
│ └── notification-service/
├── shared/
│ └── Contracts/ ← Shared NuGet package (Integration Events)
├── infra/
│ ├── docker-compose.yml
│ ├── k8s/
│ └── bicep/
└── gateway/
└── ApiGateway/
Communication Patterns
| Pattern | When | Tech |
|---|---|---|
| REST | Public API, CRUD | ASP.NET Minimal API |
| gRPC | Internal service-to-service, high throughput | Grpc.AspNetCore |
| Events (async) | Fire-and-forget, eventual consistency OK | MassTransit + Azure Service Bus |
| Request/Reply (async) | Needs response but can wait | MassTransit Request Client |
NuGet Essentials (Per Service)
xml<!-- Communication -->
<PackageReference Include="MassTransit.Azure.ServiceBus.Core" Version="8.*" />
<PackageReference Include="Grpc.AspNetCore" Version="2.*" />
<!-- Resilience -->
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="9.*" />
<!-- Observability -->
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.*" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.*" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.*" />
<!-- Infrastructure -->
<PackageReference Include="Azure.Identity" Version="1.*" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.*" />
<!-- Containerization -->
<PackageReference Include="Microsoft.NET.Build.Containers" Version="9.*" />
Docker & Deployment
dockerfile# Multi-stage build FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build WORKDIR /src COPY ["OrderService.API/OrderService.API.csproj", "OrderService.API/"] RUN dotnet restore COPY . . RUN dotnet publish -c Release -o /app FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS runtime WORKDIR /app COPY --from=build /app . EXPOSE 8080 ENTRYPOINT ["dotnet", "OrderService.API.dll"]
yaml# docker-compose.yml (Local Development)
services:
order-service:
build: ./services/order-service
ports: ["5001:8080"]
environment:
- ConnectionStrings__Default=Server=sqlserver;Database=Orders;...
inventory-service:
build: ./services/inventory-service
ports: ["5002:8080"]
sqlserver:
image: mcr.microsoft.com/mssql/server:2022-latest
redis:
image: redis:7-alpine
rabbitmq:
image: rabbitmq:3-management
ports: ["15672:15672"]