AgentSkillsCN

microservices

基于 Sam Newman 的《构建微服务》,涵盖服务分解、服务间通信、数据管理,以及运营模式——微服务架构模式与实践。 适用场景:微服务分解、服务间通信、服务网格、API 网关、Saga 模式、服务发现、分布式数据管理。 切勿用于:单体架构(使用单体架构)、事件溯源细节(使用事件驱动)、领域建模(使用领域驱动设计)。

SKILL.md
--- frontmatter
name: microservices
description: |
    Microservice architecture patterns and practices based on Sam Newman's "Building Microservices" -- covering service decomposition, inter-service communication, data management, and operational patterns.
    USE FOR: microservice decomposition, inter-service communication, service mesh, API gateway, saga pattern, service discovery, distributed data management
    DO NOT USE FOR: monolithic architecture (use monoliths), event sourcing details (use event-driven), domain modeling (use domain-driven-design)
license: MIT
metadata:
  displayName: "Microservices"
  author: "Tyler-R-Kendrick"
compatibility: claude, copilot, cursor

Microservices Architecture

Overview

Microservices architecture structures an application as a collection of loosely coupled, independently deployable services, each organized around a business capability. Each service owns its data, runs in its own process, and communicates over the network.

The canonical reference is Sam Newman's Building Microservices (O'Reilly, 2nd edition 2021), supplemented by Monolith to Microservices (Newman, 2019) for migration strategies.

The First Rule of Microservices: Don't start with microservices. Start with a monolith, understand your domain, and decompose when you have evidence that the benefits outweigh the operational costs. (See dev/architecture/monoliths for the monolith-first approach.)

Service Decomposition

By Business Capability

Align services to what the business does (e.g., Order Management, Inventory, Payments). This creates stable boundaries because business capabilities change less frequently than technical layers.

By Subdomain (DDD-Aligned)

Use Domain-Driven Design bounded contexts as service boundaries (see dev/architecture/domain-driven-design):

  • Core subdomains -- Your competitive advantage; build custom services.
  • Supporting subdomains -- Necessary but not differentiating; simpler services or libraries.
  • Generic subdomains -- Commodity; buy or use off-the-shelf (auth, email, payments).

Decomposition Heuristics

HeuristicDescription
Single ResponsibilityEach service does one thing well
Data ownershipEach service owns its data; no shared databases
Independent deployabilityChanging one service does not require deploying another
Team alignmentOne team can own and operate the service end-to-end
Bounded context boundaryService boundaries align with DDD bounded contexts

Inter-Service Communication

Synchronous Communication

PatternProtocolWhen to Use
Request/Response (REST)HTTP/JSONSimple CRUD, external APIs, broad tooling support
Request/Response (gRPC)HTTP/2 + ProtobufInternal service-to-service; high throughput, strong typing, streaming
GraphQLHTTP/JSONClient-driven queries; aggregating multiple services for a frontend

Asynchronous Communication

PatternMechanismWhen to Use
Event NotificationMessage broker (topic/pub-sub)Decoupled notification; consumers decide what to do
Event-Carried State TransferMessage broker with payloadReduce synchronous callbacks; consumer has needed data
Command MessageMessage broker (queue)Tell a specific service to do something
Async Request/ResponseCorrelation ID + reply queueNeed a response but don't want to block

Rule of thumb: Prefer asynchronous communication for inter-service calls. Use synchronous only when a real-time response is required (e.g., user-facing request/response).

Communication Anti-Patterns

  • Distributed monolith -- Services are "microservices" in name only; they deploy together, share databases, or cannot function independently.
  • Chatty interfaces -- Excessive synchronous calls between services creating latency chains.
  • Shared database -- Multiple services reading/writing the same tables destroys independent deployability.

API Gateway

An API gateway sits between external clients and internal services, providing:

  • Request routing -- Routes client requests to the appropriate microservice
  • Protocol translation -- External REST to internal gRPC, for example
  • Authentication/Authorization -- Centralized security enforcement
  • Rate limiting and throttling -- Protect services from traffic spikes
  • Response aggregation -- Combine responses from multiple services for a single client call

Common implementations: Kong, AWS API Gateway, Azure API Management, Envoy, NGINX, Ocelot (.NET).

Service Mesh

A service mesh handles service-to-service networking concerns transparently via sidecar proxies:

code
┌──────────────────────┐    ┌──────────────────────┐
│  Service A           │    │  Service B           │
│  ┌────────────────┐  │    │  ┌────────────────┐  │
│  │ App Container  │  │    │  │ App Container  │  │
│  └───────┬────────┘  │    │  └───────▲────────┘  │
│          │           │    │          │           │
│  ┌───────▼────────┐  │    │  ┌───────┴────────┐  │
│  │ Sidecar Proxy  │──┼────┼─▶│ Sidecar Proxy  │  │
│  │ (Envoy)        │  │    │  │ (Envoy)        │  │
│  └────────────────┘  │    │  └────────────────┘  │
└──────────────────────┘    └──────────────────────┘
         Control Plane (Istio / Linkerd)

Capabilities: Mutual TLS, traffic management, retries, circuit breaking, observability (distributed tracing, metrics), canary deployments.

Implementations: Istio, Linkerd, Consul Connect, AWS App Mesh.

Saga Pattern -- Distributed Transactions

Since each microservice owns its data, distributed transactions (2PC) are impractical. The saga pattern manages data consistency across services through a sequence of local transactions with compensating actions.

Choreography (Event-Driven)

Each service publishes events that trigger the next step. No central coordinator.

code
Order Service ──(OrderCreated)──▶ Payment Service
Payment Service ──(PaymentProcessed)──▶ Inventory Service
Inventory Service ──(InventoryReserved)──▶ Shipping Service

On failure:
Inventory Service ──(ReservationFailed)──▶ Payment Service (refund)
Payment Service ──(RefundProcessed)──▶ Order Service (cancel)

Pros: Simple, decoupled, no single point of failure. Cons: Hard to understand the overall flow; debugging is difficult; risk of cyclic dependencies.

Orchestration (Central Coordinator)

A saga orchestrator (process manager) coordinates the steps explicitly.

code
┌─────────────────┐
│ Saga Orchestrator│
│ (Order Saga)     │
└────┬───┬───┬────┘
     │   │   │
     ▼   ▼   ▼
  Payment  Inventory  Shipping
  Service  Service    Service

Pros: Clear flow, easier to understand and debug, centralized compensation logic. Cons: Orchestrator is a coupling point; risk of becoming a "god service."

Guidance: Use choreography for simple sagas (2-3 steps). Use orchestration for complex flows (4+ steps or complex compensation).

Distributed Data Management

PatternDescription
Database per ServiceEach service has its own database; no shared access
API CompositionQuery multiple services and aggregate results
CQRSSeparate read and write models for different optimization (see dev/architecture/event-driven)
Event SourcingStore state changes as events; derive current state (see dev/architecture/event-driven)
SagaManage distributed transactions through compensating actions
Outbox PatternReliably publish events by writing to a local outbox table within the same transaction

Service Discovery

Services need to find each other in a dynamic environment where instances come and go.

ApproachExamplesMechanism
Client-side discoveryNetflix Eureka, ConsulClient queries registry, picks instance
Server-side discoveryAWS ALB, Kubernetes ServicesLoad balancer/proxy routes to available instance
DNS-basedConsul DNS, Kubernetes CoreDNSResolve service name to IP(s) via DNS

In Kubernetes environments, server-side discovery via Services and DNS is the default and usually sufficient.

Resilience Patterns

PatternPurpose
Circuit BreakerStop calling a failing service; fail fast and allow recovery
Retry with BackoffRetry transient failures with exponential backoff and jitter
BulkheadIsolate failures to prevent cascading (separate thread pools / connections)
TimeoutSet explicit timeouts on all remote calls; never wait forever
FallbackProvide degraded but functional response when a service is unavailable
Health CheckExpose liveness and readiness endpoints for orchestrators

When NOT to Use Microservices

Microservices introduce significant operational complexity. Do not use them when:

  • Your team is small (< 8-10 developers) -- The overhead exceeds the benefit.
  • Your domain is not well understood -- You will draw the wrong boundaries and create a distributed monolith.
  • You lack operational maturity -- You need CI/CD, monitoring, distributed tracing, container orchestration, and on-call practices before microservices are viable.
  • Latency is critical -- Every network hop adds latency; monoliths have zero network overhead for internal calls.
  • Strong consistency is required everywhere -- Microservices embrace eventual consistency; if your domain requires ACID transactions across multiple entities, a monolith may be simpler.
  • You are building an MVP or prototype -- Speed of iteration matters more than scalability at this stage.

Tradeoffs Summary

BenefitCost
Independent deployabilityOperational complexity (CI/CD per service, monitoring, tracing)
Technology heterogeneityPolyglot overhead; harder to maintain standards
Team autonomyCoordination overhead; contract management
Scalability per serviceNetwork latency; serialization/deserialization cost
Fault isolationDistributed failure modes (partial failures, network partitions)
Organizational alignmentRequires mature DevOps culture

Best Practices

  • Design for failure from day one: circuit breakers, retries, timeouts, bulkheads.
  • Own your data: one database per service, no shared database access.
  • Make inter-service communication observable: distributed tracing (OpenTelemetry), centralized logging, metrics.
  • Use consumer-driven contract testing (Pact, Spring Cloud Contract) to prevent breaking changes.
  • Prefer asynchronous communication; use synchronous calls only when necessary.
  • Keep services small enough to be owned by a single team, but large enough to justify the operational overhead.
  • Deploy independently, test independently, fail independently.