#Architektura mikroserwisów: praktyczny przewodnik
Mikroserwisy to nie srebrna kula — to narzędzie architektoniczne, które ma sens w odpowiednim kontekście. Po latach budowania systemów rozproszonych dla naszych klientów, wypracowaliśmy zestaw zasad, które pomagają uniknąć najczęstszych błędów.
##Kiedy mikroserwisy mają sens
Zanim rozbijemy monolit, warto odpowiedzieć na kilka pytań:
- Czy zespół jest wystarczająco duży (>8 deweloperów)?
- Czy różne części systemu mają różne wymagania skalowania?
- Czy potrzebujemy niezależnych cykli wdrożeniowych?
- Czy jesteśmy gotowi na złożoność operacyjną?
""Jeśli nie potrafisz zbudować dobrze zorganizowanego monolitu, mikroserwisy tylko pomnożą Twoje problemy."
##Podział na domeny
Stosujemy Domain-Driven Design (DDD) jako podstawę do wydzielania granic serwisów. Każdy mikroserwis odpowiada za jedną, dobrze zdefiniowaną domenę biznesową.
1// Przykład: granice kontekstów w systemie e-commerce2const boundedContexts = {3 catalog: {4 entities: ["Product", "Category", "PriceRule"],5 commands: ["CreateProduct", "UpdatePrice", "SetDiscount"],6 events: ["ProductCreated", "PriceChanged"],7 },8 orders: {9 entities: ["Order", "OrderItem", "Shipment"],10 commands: ["PlaceOrder", "CancelOrder", "UpdateShipment"],11 events: ["OrderPlaced", "OrderShipped", "OrderDelivered"],12 },13 payments: {14 entities: ["Payment", "Refund", "Invoice"],15 commands: ["ProcessPayment", "IssueRefund"],16 events: ["PaymentCompleted", "RefundIssued"],17 },18 users: {19 entities: ["User", "Address", "Preferences"],20 commands: ["RegisterUser", "UpdateProfile"],21 events: ["UserRegistered", "ProfileUpdated"],22 },23}
##Komunikacja między serwisami
Wybór odpowiedniego wzorca komunikacji jest kluczowy:
| Wzorzec | Zastosowanie | Zalety | Wady |
|---|---|---|---|
| REST/HTTP | Zapytania synchroniczne | Prostota, szeroka adopcja | Coupling, kaskadowe błędy |
| gRPC | Komunikacja wewnętrzna | Wydajność, typowanie | Złożoność debugowania |
| Event-driven (Kafka) | Asynchroniczne procesy | Luźne powiązanie, skalowalność | Eventual consistency |
| CQRS | Oddzielenie odczytu/zapisu | Optymalizacja per-use-case | Złożoność implementacji |
###Event-driven w praktyce
W większości naszych projektów stosujemy podejście event-driven jako fundament komunikacji:
1// Definicja zdarzeń domenowych2interface DomainEvent {3 id: string4 type: string5 aggregateId: string6 timestamp: Date7 payload: Record<string, unknown>8 metadata: {9 correlationId: string10 causationId: string11 version: number12 }13}1415// Publikacja zdarzenia po złożeniu zamówienia16async function placeOrder(command: PlaceOrderCommand): Promise<void> {17 const order = Order.create(command)18 await orderRepository.save(order)1920 await eventBus.publish({21 id: crypto.randomUUID(),22 type: "order.placed",23 aggregateId: order.id,24 timestamp: new Date(),25 payload: {26 customerId: command.customerId,27 items: command.items,28 totalAmount: order.calculateTotal(),29 },30 metadata: {31 correlationId: command.correlationId,32 causationId: command.id,33 version: 1,34 },35 })36}
##Infrastruktura i orkiestracja
Każdy serwis jest konteneryzowany i zarządzany przez Kubernetes:
1# Przykład konfiguracji deployment w Kubernetes2apiVersion: apps/v13kind: Deployment4metadata:5 name: orders-service6 labels:7 app: orders8 team: backend9spec:10 replicas: 311 strategy:12 type: RollingUpdate13 rollingUpdate:14 maxSurge: 115 maxUnavailable: 016 selector:17 matchLabels:18 app: orders19 template:20 spec:21 containers:22 - name: orders23 image: registry.cyberwolf.studio/orders:v2.1.024 resources:25 requests:26 memory: "256Mi"27 cpu: "250m"28 limits:29 memory: "512Mi"30 cpu: "500m"31 livenessProbe:32 httpGet:33 path: /health34 port: 808035 initialDelaySeconds: 1036 periodSeconds: 1537 readinessProbe:38 httpGet:39 path: /ready40 port: 808041 initialDelaySeconds: 542 periodSeconds: 10
##Obserwabilność
W systemie rozproszonym obserwabilność to nie luksus — to konieczność. Stosujemy trzy filary:
- Logi — strukturalne logowanie JSON, centralna agregacja (ELK/Loki)
- Metryki — Prometheus + Grafana, RED metrics per serwis
- Trace'y — OpenTelemetry z distributed tracing przez cały pipeline
###Kluczowe dashboardy
- Service Health — latencja, error rate, throughput per serwis
- Business Metrics — zamówienia/min, konwersja, wartość koszyka
- Infrastructure — CPU, pamięć, sieć, pod autoscaling
- Dependencies — health check zewnętrznych integracji
##Podsumowanie
Mikroserwisy dają ogromną elastyczność, ale wymagają dojrzałości operacyjnej. Zacznij od dobrze zaprojektowanego monolitu, identyfikuj naturalne granice domen i wydzielaj serwisy tam, gdzie przynoszą realną wartość.
Potrzebujesz pomocy z architekturą systemu? Porozmawiajmy o Twoim projekcie.