{
  "schemaVersion": "1.0",
  "item": {
    "slug": "microservice-patterns",
    "name": "Microservice Patterns",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/wpank/microservice-patterns",
    "canonicalUrl": "https://clawhub.ai/wpank/microservice-patterns",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/microservice-patterns",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=microservice-patterns",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "README.md",
      "SKILL.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/microservice-patterns"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/microservice-patterns",
    "agentPageUrl": "https://openagent3.xyz/skills/microservice-patterns/agent",
    "manifestUrl": "https://openagent3.xyz/skills/microservice-patterns/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/microservice-patterns/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "WHAT",
        "body": "Patterns for building distributed systems: service decomposition, inter-service communication, data management, and resilience. Helps you avoid the \"distributed monolith\" anti-pattern."
      },
      {
        "title": "WHEN",
        "body": "Decomposing a monolith into microservices\nDesigning service boundaries and contracts\nImplementing inter-service communication\nManaging distributed transactions\nBuilding resilient distributed systems"
      },
      {
        "title": "KEYWORDS",
        "body": "microservices, service mesh, event-driven, saga, circuit breaker, API gateway, service discovery, distributed transactions, eventual consistency, CQRS"
      },
      {
        "title": "Decision Framework: When to Use Microservices",
        "body": "If you have...Then...Small team (<5 devs), simple domainStart with monolithNeed independent deployment/scalingConsider microservicesMultiple teams, clear domain boundariesMicroservices work wellTight deadlines, unknown requirementsMonolith first, extract later\n\nRule of thumb: If you can't define clear service boundaries, you're not ready for microservices."
      },
      {
        "title": "Pattern 1: By Business Capability",
        "body": "Organize services around business functions, not technical layers.\n\nE-commerce Example:\n├── order-service       # Order lifecycle\n├── payment-service     # Payment processing\n├── inventory-service   # Stock management\n├── shipping-service    # Fulfillment\n└── notification-service # Emails, SMS"
      },
      {
        "title": "Pattern 2: Strangler Fig (Monolith Migration)",
        "body": "Gradually extract from monolith without big-bang rewrites.\n\n1. Identify bounded context to extract\n2. Create new microservice\n3. Route new traffic to microservice\n4. Gradually migrate existing functionality\n5. Remove from monolith when complete\n\n# API Gateway routing during migration\nasync def route_orders(request):\n    if request.path.startswith(\"/api/orders/v2\"):\n        return await new_order_service.forward(request)\n    else:\n        return await legacy_monolith.forward(request)"
      },
      {
        "title": "Pattern 1: Synchronous (REST/gRPC)",
        "body": "Use for: Queries, when you need immediate response.\n\nimport httpx\nfrom tenacity import retry, stop_after_attempt, wait_exponential\n\nclass ServiceClient:\n    def __init__(self, base_url: str):\n        self.base_url = base_url\n        self.client = httpx.AsyncClient(timeout=5.0)\n    \n    @retry(stop=stop_after_attempt(3), wait=wait_exponential(min=1, max=10))\n    async def get(self, path: str):\n        \"\"\"GET with automatic retries.\"\"\"\n        response = await self.client.get(f\"{self.base_url}{path}\")\n        response.raise_for_status()\n        return response.json()\n\n# Usage\npayment_client = ServiceClient(\"http://payment-service:8001\")\nresult = await payment_client.get(f\"/payments/{payment_id}\")"
      },
      {
        "title": "Pattern 2: Asynchronous (Events)",
        "body": "Use for: Commands, when eventual consistency is acceptable.\n\nfrom aiokafka import AIOKafkaProducer\nimport json\n\n@dataclass\nclass DomainEvent:\n    event_id: str\n    event_type: str\n    aggregate_id: str\n    occurred_at: datetime\n    data: dict\n\nclass EventBus:\n    def __init__(self, bootstrap_servers: List[str]):\n        self.producer = AIOKafkaProducer(\n            bootstrap_servers=bootstrap_servers,\n            value_serializer=lambda v: json.dumps(v).encode()\n        )\n    \n    async def publish(self, event: DomainEvent):\n        await self.producer.send_and_wait(\n            event.event_type,  # Topic = event type\n            value=asdict(event),\n            key=event.aggregate_id.encode()\n        )\n\n# Order service publishes\nawait event_bus.publish(DomainEvent(\n    event_id=str(uuid.uuid4()),\n    event_type=\"OrderCreated\",\n    aggregate_id=order.id,\n    occurred_at=datetime.now(),\n    data={\"order_id\": order.id, \"customer_id\": order.customer_id}\n))\n\n# Inventory service subscribes and reacts\nasync def handle_order_created(event_data: dict):\n    order_id = event_data[\"data\"][\"order_id\"]\n    items = event_data[\"data\"][\"items\"]\n    await reserve_inventory(order_id, items)"
      },
      {
        "title": "When to Use Each",
        "body": "SynchronousAsynchronousNeed immediate responseFire-and-forgetSimple query/responseLong-running operationsLow latency requiredDecoupling is priorityTight coupling acceptableEventual consistency OK"
      },
      {
        "title": "Database Per Service",
        "body": "Each service owns its data. No shared databases.\n\norder-service     → orders_db (PostgreSQL)\npayment-service   → payments_db (PostgreSQL)\nproduct-service   → products_db (MongoDB)\nanalytics-service → analytics_db (ClickHouse)"
      },
      {
        "title": "Saga Pattern (Distributed Transactions)",
        "body": "For operations spanning multiple services that need rollback capability.\n\nclass SagaStep:\n    def __init__(self, name: str, action: Callable, compensation: Callable):\n        self.name = name\n        self.action = action\n        self.compensation = compensation\n\nclass OrderFulfillmentSaga:\n    def __init__(self):\n        self.steps = [\n            SagaStep(\"create_order\", self.create_order, self.cancel_order),\n            SagaStep(\"reserve_inventory\", self.reserve_inventory, self.release_inventory),\n            SagaStep(\"process_payment\", self.process_payment, self.refund_payment),\n            SagaStep(\"confirm_order\", self.confirm_order, self.cancel_confirmation),\n        ]\n    \n    async def execute(self, order_data: dict) -> SagaResult:\n        completed_steps = []\n        context = {\"order_data\": order_data}\n        \n        for step in self.steps:\n            try:\n                result = await step.action(context)\n                if not result.success:\n                    await self.compensate(completed_steps, context)\n                    return SagaResult(status=\"failed\", error=result.error)\n                completed_steps.append(step)\n                context.update(result.data)\n            except Exception as e:\n                await self.compensate(completed_steps, context)\n                return SagaResult(status=\"failed\", error=str(e))\n        \n        return SagaResult(status=\"completed\", data=context)\n    \n    async def compensate(self, completed_steps: List[SagaStep], context: dict):\n        \"\"\"Execute compensating actions in reverse order.\"\"\"\n        for step in reversed(completed_steps):\n            try:\n                await step.compensation(context)\n            except Exception as e:\n                # Log but continue compensating\n                logger.error(f\"Compensation failed for {step.name}: {e}\")"
      },
      {
        "title": "Circuit Breaker",
        "body": "Fail fast when a service is down. Prevents cascade failures.\n\nfrom enum import Enum\nfrom datetime import datetime, timedelta\n\nclass CircuitState(Enum):\n    CLOSED = \"closed\"      # Normal operation\n    OPEN = \"open\"          # Failing, reject requests\n    HALF_OPEN = \"half_open\" # Testing recovery\n\nclass CircuitBreaker:\n    def __init__(\n        self,\n        failure_threshold: int = 5,\n        recovery_timeout: int = 30,\n        success_threshold: int = 2\n    ):\n        self.failure_threshold = failure_threshold\n        self.recovery_timeout = recovery_timeout\n        self.success_threshold = success_threshold\n        self.failure_count = 0\n        self.success_count = 0\n        self.state = CircuitState.CLOSED\n        self.opened_at = None\n    \n    async def call(self, func: Callable, *args, **kwargs):\n        if self.state == CircuitState.OPEN:\n            if self._should_attempt_reset():\n                self.state = CircuitState.HALF_OPEN\n            else:\n                raise CircuitBreakerOpen(\"Service unavailable\")\n        \n        try:\n            result = await func(*args, **kwargs)\n            self._on_success()\n            return result\n        except Exception as e:\n            self._on_failure()\n            raise\n    \n    def _on_success(self):\n        self.failure_count = 0\n        if self.state == CircuitState.HALF_OPEN:\n            self.success_count += 1\n            if self.success_count >= self.success_threshold:\n                self.state = CircuitState.CLOSED\n                self.success_count = 0\n    \n    def _on_failure(self):\n        self.failure_count += 1\n        if self.failure_count >= self.failure_threshold:\n            self.state = CircuitState.OPEN\n            self.opened_at = datetime.now()\n    \n    def _should_attempt_reset(self) -> bool:\n        return datetime.now() - self.opened_at > timedelta(seconds=self.recovery_timeout)\n\n# Usage\nbreaker = CircuitBreaker(failure_threshold=5, recovery_timeout=30)\n\nasync def call_payment_service(data: dict):\n    return await breaker.call(payment_client.post, \"/payments\", json=data)"
      },
      {
        "title": "Retry with Exponential Backoff",
        "body": "For transient failures.\n\nfrom tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type\n\n@retry(\n    stop=stop_after_attempt(3),\n    wait=wait_exponential(multiplier=1, min=2, max=10),\n    retry=retry_if_exception_type((httpx.TimeoutException, httpx.HTTPStatusError))\n)\nasync def fetch_user(user_id: str):\n    response = await client.get(f\"/users/{user_id}\")\n    response.raise_for_status()\n    return response.json()"
      },
      {
        "title": "Bulkhead",
        "body": "Isolate resources to limit impact of failures.\n\nimport asyncio\n\nclass Bulkhead:\n    def __init__(self, max_concurrent: int):\n        self.semaphore = asyncio.Semaphore(max_concurrent)\n    \n    async def call(self, func: Callable, *args, **kwargs):\n        async with self.semaphore:\n            return await func(*args, **kwargs)\n\n# Limit concurrent calls to each service\npayment_bulkhead = Bulkhead(max_concurrent=10)\ninventory_bulkhead = Bulkhead(max_concurrent=20)\n\nresult = await payment_bulkhead.call(payment_service.charge, amount)"
      },
      {
        "title": "API Gateway Pattern",
        "body": "Single entry point for all clients.\n\nfrom fastapi import FastAPI, Depends, HTTPException\nfrom circuitbreaker import circuit\n\napp = FastAPI()\n\nclass APIGateway:\n    def __init__(self):\n        self.clients = {\n            \"orders\": httpx.AsyncClient(base_url=\"http://order-service:8000\"),\n            \"payments\": httpx.AsyncClient(base_url=\"http://payment-service:8001\"),\n            \"inventory\": httpx.AsyncClient(base_url=\"http://inventory-service:8002\"),\n        }\n    \n    @circuit(failure_threshold=5, recovery_timeout=30)\n    async def forward(self, service: str, path: str, **kwargs):\n        client = self.clients[service]\n        response = await client.request(**kwargs, url=path)\n        response.raise_for_status()\n        return response.json()\n    \n    async def aggregate(self, order_id: str) -> dict:\n        \"\"\"Aggregate data from multiple services.\"\"\"\n        results = await asyncio.gather(\n            self.forward(\"orders\", f\"/orders/{order_id}\", method=\"GET\"),\n            self.forward(\"payments\", f\"/payments/order/{order_id}\", method=\"GET\"),\n            self.forward(\"inventory\", f\"/reservations/order/{order_id}\", method=\"GET\"),\n            return_exceptions=True\n        )\n        \n        return {\n            \"order\": results[0] if not isinstance(results[0], Exception) else None,\n            \"payment\": results[1] if not isinstance(results[1], Exception) else None,\n            \"inventory\": results[2] if not isinstance(results[2], Exception) else None,\n        }\n\ngateway = APIGateway()\n\n@app.get(\"/api/orders/{order_id}\")\nasync def get_order_aggregate(order_id: str):\n    return await gateway.aggregate(order_id)"
      },
      {
        "title": "Health Checks",
        "body": "Every service needs liveness and readiness probes.\n\n@app.get(\"/health/live\")\nasync def liveness():\n    \"\"\"Is the process running?\"\"\"\n    return {\"status\": \"alive\"}\n\n@app.get(\"/health/ready\")\nasync def readiness():\n    \"\"\"Can we serve traffic?\"\"\"\n    checks = {\n        \"database\": await check_database(),\n        \"cache\": await check_redis(),\n    }\n    \n    all_healthy = all(checks.values())\n    status = \"ready\" if all_healthy else \"not_ready\"\n    \n    return {\"status\": status, \"checks\": checks}"
      },
      {
        "title": "NEVER",
        "body": "Shared Databases: Creates tight coupling, defeats the purpose\nSynchronous Chains: A → B → C → D = fragile, slow\nNo Circuit Breakers: One service down takes everything down\nDistributed Monolith: Services that must deploy together\nIgnoring Network Failures: Assume the network WILL fail\nNo Compensation Logic: Can't undo failed distributed transactions\nStarting with Microservices: Always start with a well-structured monolith\nChatty Services: Too many inter-service calls = latency death"
      }
    ],
    "body": "Microservices Patterns\nWHAT\n\nPatterns for building distributed systems: service decomposition, inter-service communication, data management, and resilience. Helps you avoid the \"distributed monolith\" anti-pattern.\n\nWHEN\nDecomposing a monolith into microservices\nDesigning service boundaries and contracts\nImplementing inter-service communication\nManaging distributed transactions\nBuilding resilient distributed systems\nKEYWORDS\n\nmicroservices, service mesh, event-driven, saga, circuit breaker, API gateway, service discovery, distributed transactions, eventual consistency, CQRS\n\nDecision Framework: When to Use Microservices\nIf you have...\tThen...\nSmall team (<5 devs), simple domain\tStart with monolith\nNeed independent deployment/scaling\tConsider microservices\nMultiple teams, clear domain boundaries\tMicroservices work well\nTight deadlines, unknown requirements\tMonolith first, extract later\n\nRule of thumb: If you can't define clear service boundaries, you're not ready for microservices.\n\nService Decomposition Patterns\nPattern 1: By Business Capability\n\nOrganize services around business functions, not technical layers.\n\nE-commerce Example:\n├── order-service       # Order lifecycle\n├── payment-service     # Payment processing\n├── inventory-service   # Stock management\n├── shipping-service    # Fulfillment\n└── notification-service # Emails, SMS\n\nPattern 2: Strangler Fig (Monolith Migration)\n\nGradually extract from monolith without big-bang rewrites.\n\n1. Identify bounded context to extract\n2. Create new microservice\n3. Route new traffic to microservice\n4. Gradually migrate existing functionality\n5. Remove from monolith when complete\n\n# API Gateway routing during migration\nasync def route_orders(request):\n    if request.path.startswith(\"/api/orders/v2\"):\n        return await new_order_service.forward(request)\n    else:\n        return await legacy_monolith.forward(request)\n\nCommunication Patterns\nPattern 1: Synchronous (REST/gRPC)\n\nUse for: Queries, when you need immediate response.\n\nimport httpx\nfrom tenacity import retry, stop_after_attempt, wait_exponential\n\nclass ServiceClient:\n    def __init__(self, base_url: str):\n        self.base_url = base_url\n        self.client = httpx.AsyncClient(timeout=5.0)\n    \n    @retry(stop=stop_after_attempt(3), wait=wait_exponential(min=1, max=10))\n    async def get(self, path: str):\n        \"\"\"GET with automatic retries.\"\"\"\n        response = await self.client.get(f\"{self.base_url}{path}\")\n        response.raise_for_status()\n        return response.json()\n\n# Usage\npayment_client = ServiceClient(\"http://payment-service:8001\")\nresult = await payment_client.get(f\"/payments/{payment_id}\")\n\nPattern 2: Asynchronous (Events)\n\nUse for: Commands, when eventual consistency is acceptable.\n\nfrom aiokafka import AIOKafkaProducer\nimport json\n\n@dataclass\nclass DomainEvent:\n    event_id: str\n    event_type: str\n    aggregate_id: str\n    occurred_at: datetime\n    data: dict\n\nclass EventBus:\n    def __init__(self, bootstrap_servers: List[str]):\n        self.producer = AIOKafkaProducer(\n            bootstrap_servers=bootstrap_servers,\n            value_serializer=lambda v: json.dumps(v).encode()\n        )\n    \n    async def publish(self, event: DomainEvent):\n        await self.producer.send_and_wait(\n            event.event_type,  # Topic = event type\n            value=asdict(event),\n            key=event.aggregate_id.encode()\n        )\n\n# Order service publishes\nawait event_bus.publish(DomainEvent(\n    event_id=str(uuid.uuid4()),\n    event_type=\"OrderCreated\",\n    aggregate_id=order.id,\n    occurred_at=datetime.now(),\n    data={\"order_id\": order.id, \"customer_id\": order.customer_id}\n))\n\n# Inventory service subscribes and reacts\nasync def handle_order_created(event_data: dict):\n    order_id = event_data[\"data\"][\"order_id\"]\n    items = event_data[\"data\"][\"items\"]\n    await reserve_inventory(order_id, items)\n\nWhen to Use Each\nSynchronous\tAsynchronous\nNeed immediate response\tFire-and-forget\nSimple query/response\tLong-running operations\nLow latency required\tDecoupling is priority\nTight coupling acceptable\tEventual consistency OK\nData Patterns\nDatabase Per Service\n\nEach service owns its data. No shared databases.\n\norder-service     → orders_db (PostgreSQL)\npayment-service   → payments_db (PostgreSQL)\nproduct-service   → products_db (MongoDB)\nanalytics-service → analytics_db (ClickHouse)\n\nSaga Pattern (Distributed Transactions)\n\nFor operations spanning multiple services that need rollback capability.\n\nclass SagaStep:\n    def __init__(self, name: str, action: Callable, compensation: Callable):\n        self.name = name\n        self.action = action\n        self.compensation = compensation\n\nclass OrderFulfillmentSaga:\n    def __init__(self):\n        self.steps = [\n            SagaStep(\"create_order\", self.create_order, self.cancel_order),\n            SagaStep(\"reserve_inventory\", self.reserve_inventory, self.release_inventory),\n            SagaStep(\"process_payment\", self.process_payment, self.refund_payment),\n            SagaStep(\"confirm_order\", self.confirm_order, self.cancel_confirmation),\n        ]\n    \n    async def execute(self, order_data: dict) -> SagaResult:\n        completed_steps = []\n        context = {\"order_data\": order_data}\n        \n        for step in self.steps:\n            try:\n                result = await step.action(context)\n                if not result.success:\n                    await self.compensate(completed_steps, context)\n                    return SagaResult(status=\"failed\", error=result.error)\n                completed_steps.append(step)\n                context.update(result.data)\n            except Exception as e:\n                await self.compensate(completed_steps, context)\n                return SagaResult(status=\"failed\", error=str(e))\n        \n        return SagaResult(status=\"completed\", data=context)\n    \n    async def compensate(self, completed_steps: List[SagaStep], context: dict):\n        \"\"\"Execute compensating actions in reverse order.\"\"\"\n        for step in reversed(completed_steps):\n            try:\n                await step.compensation(context)\n            except Exception as e:\n                # Log but continue compensating\n                logger.error(f\"Compensation failed for {step.name}: {e}\")\n\nResilience Patterns\nCircuit Breaker\n\nFail fast when a service is down. Prevents cascade failures.\n\nfrom enum import Enum\nfrom datetime import datetime, timedelta\n\nclass CircuitState(Enum):\n    CLOSED = \"closed\"      # Normal operation\n    OPEN = \"open\"          # Failing, reject requests\n    HALF_OPEN = \"half_open\" # Testing recovery\n\nclass CircuitBreaker:\n    def __init__(\n        self,\n        failure_threshold: int = 5,\n        recovery_timeout: int = 30,\n        success_threshold: int = 2\n    ):\n        self.failure_threshold = failure_threshold\n        self.recovery_timeout = recovery_timeout\n        self.success_threshold = success_threshold\n        self.failure_count = 0\n        self.success_count = 0\n        self.state = CircuitState.CLOSED\n        self.opened_at = None\n    \n    async def call(self, func: Callable, *args, **kwargs):\n        if self.state == CircuitState.OPEN:\n            if self._should_attempt_reset():\n                self.state = CircuitState.HALF_OPEN\n            else:\n                raise CircuitBreakerOpen(\"Service unavailable\")\n        \n        try:\n            result = await func(*args, **kwargs)\n            self._on_success()\n            return result\n        except Exception as e:\n            self._on_failure()\n            raise\n    \n    def _on_success(self):\n        self.failure_count = 0\n        if self.state == CircuitState.HALF_OPEN:\n            self.success_count += 1\n            if self.success_count >= self.success_threshold:\n                self.state = CircuitState.CLOSED\n                self.success_count = 0\n    \n    def _on_failure(self):\n        self.failure_count += 1\n        if self.failure_count >= self.failure_threshold:\n            self.state = CircuitState.OPEN\n            self.opened_at = datetime.now()\n    \n    def _should_attempt_reset(self) -> bool:\n        return datetime.now() - self.opened_at > timedelta(seconds=self.recovery_timeout)\n\n# Usage\nbreaker = CircuitBreaker(failure_threshold=5, recovery_timeout=30)\n\nasync def call_payment_service(data: dict):\n    return await breaker.call(payment_client.post, \"/payments\", json=data)\n\nRetry with Exponential Backoff\n\nFor transient failures.\n\nfrom tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type\n\n@retry(\n    stop=stop_after_attempt(3),\n    wait=wait_exponential(multiplier=1, min=2, max=10),\n    retry=retry_if_exception_type((httpx.TimeoutException, httpx.HTTPStatusError))\n)\nasync def fetch_user(user_id: str):\n    response = await client.get(f\"/users/{user_id}\")\n    response.raise_for_status()\n    return response.json()\n\nBulkhead\n\nIsolate resources to limit impact of failures.\n\nimport asyncio\n\nclass Bulkhead:\n    def __init__(self, max_concurrent: int):\n        self.semaphore = asyncio.Semaphore(max_concurrent)\n    \n    async def call(self, func: Callable, *args, **kwargs):\n        async with self.semaphore:\n            return await func(*args, **kwargs)\n\n# Limit concurrent calls to each service\npayment_bulkhead = Bulkhead(max_concurrent=10)\ninventory_bulkhead = Bulkhead(max_concurrent=20)\n\nresult = await payment_bulkhead.call(payment_service.charge, amount)\n\nAPI Gateway Pattern\n\nSingle entry point for all clients.\n\nfrom fastapi import FastAPI, Depends, HTTPException\nfrom circuitbreaker import circuit\n\napp = FastAPI()\n\nclass APIGateway:\n    def __init__(self):\n        self.clients = {\n            \"orders\": httpx.AsyncClient(base_url=\"http://order-service:8000\"),\n            \"payments\": httpx.AsyncClient(base_url=\"http://payment-service:8001\"),\n            \"inventory\": httpx.AsyncClient(base_url=\"http://inventory-service:8002\"),\n        }\n    \n    @circuit(failure_threshold=5, recovery_timeout=30)\n    async def forward(self, service: str, path: str, **kwargs):\n        client = self.clients[service]\n        response = await client.request(**kwargs, url=path)\n        response.raise_for_status()\n        return response.json()\n    \n    async def aggregate(self, order_id: str) -> dict:\n        \"\"\"Aggregate data from multiple services.\"\"\"\n        results = await asyncio.gather(\n            self.forward(\"orders\", f\"/orders/{order_id}\", method=\"GET\"),\n            self.forward(\"payments\", f\"/payments/order/{order_id}\", method=\"GET\"),\n            self.forward(\"inventory\", f\"/reservations/order/{order_id}\", method=\"GET\"),\n            return_exceptions=True\n        )\n        \n        return {\n            \"order\": results[0] if not isinstance(results[0], Exception) else None,\n            \"payment\": results[1] if not isinstance(results[1], Exception) else None,\n            \"inventory\": results[2] if not isinstance(results[2], Exception) else None,\n        }\n\ngateway = APIGateway()\n\n@app.get(\"/api/orders/{order_id}\")\nasync def get_order_aggregate(order_id: str):\n    return await gateway.aggregate(order_id)\n\nHealth Checks\n\nEvery service needs liveness and readiness probes.\n\n@app.get(\"/health/live\")\nasync def liveness():\n    \"\"\"Is the process running?\"\"\"\n    return {\"status\": \"alive\"}\n\n@app.get(\"/health/ready\")\nasync def readiness():\n    \"\"\"Can we serve traffic?\"\"\"\n    checks = {\n        \"database\": await check_database(),\n        \"cache\": await check_redis(),\n    }\n    \n    all_healthy = all(checks.values())\n    status = \"ready\" if all_healthy else \"not_ready\"\n    \n    return {\"status\": status, \"checks\": checks}\n\nNEVER\nShared Databases: Creates tight coupling, defeats the purpose\nSynchronous Chains: A → B → C → D = fragile, slow\nNo Circuit Breakers: One service down takes everything down\nDistributed Monolith: Services that must deploy together\nIgnoring Network Failures: Assume the network WILL fail\nNo Compensation Logic: Can't undo failed distributed transactions\nStarting with Microservices: Always start with a well-structured monolith\nChatty Services: Too many inter-service calls = latency death"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/wpank/microservice-patterns",
    "publisherUrl": "https://clawhub.ai/wpank/microservice-patterns",
    "owner": "wpank",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/microservice-patterns",
    "downloadUrl": "https://openagent3.xyz/downloads/microservice-patterns",
    "agentUrl": "https://openagent3.xyz/skills/microservice-patterns/agent",
    "manifestUrl": "https://openagent3.xyz/skills/microservice-patterns/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/microservice-patterns/agent.md"
  }
}