mcpField
M
microservices-patterns

microservices-patterns

github.com/secondsky开发240392 次安装5 周前更新
代码仓库

关于 microservices-patterns

面向微服务与分布式系统设计者的技能,涵盖服务拆分、通信、数据管理和韧性模式,并提供示例与常见问题指引。

主要功能

  1. 01服务拆分策略
  2. 02同步与异步通信模式
  3. 03服务独立数据与 Saga 事务
  4. 04熔断、重试与舱壁模式
  5. 05最佳实践与常见问题

适用场景

  1. 01将单体应用拆分为服务
  2. 02定义服务边界与契约
  3. 03选择通信和数据模式
  4. 04规划服务故障处理

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/secondsky/claude-skills --skill microservices-patterns

安装后在 Claude Code 中输入/microservices-patterns确认已加载。

详细介绍

微服务模式

掌握微服务架构模式,包括服务边界、服务间通信、数据管理和弹性模式,以构建分布式系统。

何时使用此技能

  • 将单体应用拆分为微服务
  • 设计服务边界和契约
  • 实现服务间通信
  • 管理分布式数据和事务
  • 构建弹性分布式系统
  • 实现服务发现和负载均衡
  • 设计事件驱动架构

核心概念

1. 服务拆分策略

按业务能力拆分

  • 围绕业务功能组织服务
  • 每个服务负责自己的领域
  • 示例:OrderService、PaymentService、InventoryService

按子域拆分(DDD)

  • 核心域、支撑子域
  • 限界上下文映射到服务
  • 明确所有权和职责

绞杀者无花果模式

  • 逐步从单体应用中拆分
  • 将新功能构建为微服务
  • 通过代理将请求路由到新旧系统
2. 通信模式

同步(请求/响应)

  • REST API
  • gRPC
  • GraphQL

异步(事件/消息)

  • 事件流(Kafka)
  • 消息队列(RabbitMQ、SQS)
  • 发布/订阅模式
3. 数据管理

每个服务独立数据库

  • 每个服务管理自己的数据
  • 不共享数据库
  • 松耦合

Saga 模式

  • 分布式事务
  • 补偿操作
  • 最终一致性
4. 弹性模式

断路器

  • 多次出错时快速失败
  • 防止故障级联

带退避的重试

  • 处理暂时性故障
  • 指数退避

舱壁

  • 隔离资源
  • 限制故障影响

服务拆分模式

模式 1:按业务能力拆分
# Order Service
class OrderService:
    async def create_order(self, order_data: dict) -> Order:
        order = Order.create(order_data)
        await self.event_bus.publish(
            OrderCreatedEvent(order_id=order.id, customer_id=order.customer_id)
        )
        return order

# Payment Service (separate service)
class PaymentService:
    async def process_payment(self, payment_request: PaymentRequest) -> PaymentResult:
        result = await self.payment_gateway.charge(
            amount=payment_request.amount,
            customer=payment_request.customer_id
        )
        if result.success:
            await self.event_bus.publish(
                PaymentCompletedEvent(order_id=payment_request.order_id)
            )
        return result

# Inventory Service (separate service)
class InventoryService:
    async def reserve_items(self, order_id: str, items: List[OrderItem]) -> ReservationResult:
        for item in items:
            available = await self.inventory_repo.get_available(item.product_id)
            if available < item.quantity:
                return ReservationResult(success=False, error=f"Insufficient inventory")

        reservation = await self.create_reservation(order_id, items)
        await self.event_bus.publish(InventoryReservedEvent(order_id=order_id))
        return ReservationResult(success=True, reservation=reservation)
模式 2:API 网关
from fastapi import FastAPI
import httpx

class APIGateway:
    """Central entry point for all client requests."""

    def __init__(self):
        self.order_service_url = "http://order-service:8000"
        self.payment_service_url = "http://payment-service:8001"
        self.http_client = httpx.AsyncClient(timeout=5.0)

    @circuit(failure_threshold=5, recovery_timeout=30)
    async def call_order_service(self, path: str, method: str = "GET", **kwargs):
        """Call order service with circuit breaker."""
        response = await self.http_client.request(
            method, f"{self.order_service_url}{path}", **kwargs
        )
        response.raise_for_status()
        return response.json()

    async def create_order_aggregate(self, order_id: str) -> dict:
        """Aggregate data from multiple services."""
        order, payment, inventory = await asyncio.gather(
            self.call_order_service(f"/orders/{order_id}"),
            self.call_payment_service(f"/payments/order/{order_id}"),
            self.call_inventory_service(f"/reservations/order/{order_id}"),
            return_exceptions=True
        )

        result = {"order": order}
        if not isinstance(payment, Exception):
            result["payment"] = payment
        if not isinstance(inventory, Exception):
            result["inventory"] = inventory
        return result

通信模式

模式 1:同步 REST 通信
import httpx
from tenacity import retry, stop_after_attempt, wait_exponential

class ServiceClient:
    """HTTP client with retries and timeout."""

    def __init__(self, base_url: str):
        self.base_url = base_url
        self.client = httpx.AsyncClient(timeout=httpx.Timeout(5.0, connect=2.0))

    @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10))
    async def get(self, path: str, **kwargs):
        """GET with automatic retries."""
        response = await self.client.get(f"{self.base_url}{path}", **kwargs)
        response.raise_for_status()
        return response.json()

payment_client = ServiceClient("http://payment-service:8001")
result = await payment_client.get("/payments/123")
模式 2:异步事件驱动
from aiokafka import AIOKafkaProducer, AIOKafkaConsumer
import json

class EventBus:
    """Event publishing and subscription."""

    async def publish(self, event: DomainEvent):
        """Publish event to Kafka topic."""
        await self.producer.send_and_wait(
            event.event_type,
            value=asdict(event),
            key=event.aggregate_id.encode()
        )

    async def subscribe(self, topic: str, handler: callable):
        """Subscribe to events."""
        consumer = AIOKafkaConsumer(topic, bootstrap_servers=self.bootstrap_servers)
        await consumer.start()
        async for message in consumer:
            await handler(message.value)

# Order Service publishes
await event_bus.publish(OrderCreatedEvent(order_id=order.id))

# Inventory Service subscribes
async def handle_order_created(event_data: dict):
    await reserve_inventory(event_data["order_id"], event_data["items"])
模式 3:Saga 模式(分布式事务)
class OrderFulfillmentSaga:
    """Orchestrated saga for order fulfillment."""

    def __init__(self):
        self.steps = [
            SagaStep("create_order", self.create_order, self.cancel_order),
            SagaStep("reserve_inventory", self.reserve_inventory, self.release_inventory),
            SagaStep("process_payment", self.process_payment, self.refund_payment),
            SagaStep("confirm_order", self.confirm_order, self.cancel_order_confirmation)
        ]

    async def execute(self, order_data: dict) -> SagaResult:
        completed_steps = []
        context = {"order_data": order_data}

        try:
            for step in self.steps:
                result = await step.action(context)
                if not result.success:
                    await self.compensate(completed_steps, context)
                    return SagaResult(status=SagaStatus.FAILED, error=result.error)

                completed_steps.append(step)
                context.update(result.data)

            return SagaResult(status=SagaStatus.COMPLETED, data=context)
        except Exception as e:
            await self.compensate(completed_steps, context)
            return SagaResult(status=SagaStatus.FAILED, error=str(e))

    async def compensate(self, completed_steps: List[SagaStep], context: dict):
        """Execute compensating actions in reverse order."""
        for step in reversed(completed_steps):
            await step.compensation(context)

弹性模式

断路器模式
from enum import Enum
from datetime import datetime, timedelta

class CircuitState(Enum):
    CLOSED = "closed"   # Normal operation
    OPEN = "open"       # Failing, reject requests
    HALF_OPEN = "half_open"  # Testing recovery

class CircuitBreaker:
    def __init__(self, failure_threshold: int = 5, recovery_timeout: int = 30):
        self.failure_threshold = failure_threshold
        self.recovery_timeout = recovery_timeout
        self.failure_count = 0
        self.state = CircuitState.CLOSED
        self.opened_at = None

    async def call(self, func, *args, **kwargs):
        if self.state == CircuitState.OPEN:
            if self._should_attempt_reset():
                self.state = CircuitState.HALF_OPEN
            else:
                raise CircuitBreakerOpenError("Circuit breaker is open")

        try:
            result = await func(*args, **kwargs)
            self._on_success()
            return result
        except Exception as e:
            self._on_failure()
            raise

    def _on_success(self):
        self.failure_count = 0
        if self.state == CircuitState.HALF_OPEN:
            self.state = CircuitState.CLOSED

    def _on_failure(self):
        self.failure_count += 1
        if self.failure_count >= self.failure_threshold:
            self.state = CircuitState.OPEN
            self.opened_at = datetime.now()

breaker = CircuitBreaker(failure_threshold=5, recovery_timeout=30)
result = await breaker.call(payment_client.process_payment, payment_data)

最佳实践

  1. 服务边界:与业务能力保持一致
  2. 每个服务独立数据库:不共享数据库
  3. API 契约:版本化并保持向后兼容
  4. 尽可能采用异步通信:优先使用事件,而非直接调用
  5. 断路器:服务故障时快速失败
  6. 分布式追踪:跨服务跟踪请求
  7. 服务注册表:动态发现服务
  8. 健康检查:存活和就绪探针

常见陷阱

  • 分布式单体:服务之间紧密耦合
  • 多话服务:服务间调用过多
  • 共享数据库:通过数据造成紧密耦合
  • 没有断路器:导致故障级联
  • 所有操作都采用同步方式:耦合紧密,弹性差
  • 过早采用微服务:一开始就采用微服务
  • 忽视网络故障:假设网络始终可靠
  • 没有补偿逻辑:无法撤销失败的事务

评论

支持 Markdown