microservices-design について
マイクロサービスを設計する開発者向けのパターン集です。サービス境界、イベント通信、Saga、ゲートウェイ、ヘルスチェックに加え、アンチパターンと実装チェックリストを扱います。
主な機能
- 01ビジネス能力に基づくサービス境界
- 02イベント通信と冪等性
- 03Sagaのオーケストレーションと補償
- 04APIゲートウェイとヘルスチェック
- 05アンチパターンと実装チェックリスト
活用シーン
- 01サービスの責務とデータストアの計画
- 02信頼性の高い非同期ワークフローの設計
- 03ゲートウェイ、ヘルス、耐障害性の確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ rohitg00/ awesome-claude-code-toolkit --skill microservices-designインストール後、Claude Code で/microservices-designを入力して読み込まれたか確認します。
詳細
マイクロサービス設計
サービス境界
技術レイヤーではなく、ビジネス能力を中心にサービスを定義します。各サービスは自身のデータストアを所有し、明確な API 契約を公開します。
order-service/ -> owns orders table, publishes OrderCreated events
inventory-service/ -> owns inventory table, subscribes to OrderCreated
payment-service/ -> owns payments table, handles payment processing
notification-service -> stateless, subscribes to events, sends emails/SMS
イベント駆動型の通信
interface DomainEvent {
eventId: string;
eventType: string;
aggregateId: string;
timestamp: string;
version: number;
payload: Record<string, unknown>;
}
const orderCreatedEvent: DomainEvent = {
eventId: crypto.randomUUID(),
eventType: "order.created",
aggregateId: orderId,
timestamp: new Date().toISOString(),
version: 1,
payload: { customerId, items, totalAmount },
};
await broker.publish("orders", orderCreatedEvent);
async function handleOrderCreated(event: DomainEvent) {
const { items } = event.payload as OrderPayload;
for (const item of items) {
await db.inventory.update({
where: { productId: item.productId },
data: { quantity: { decrement: item.quantity } },
});
}
await markEventProcessed(event.eventId);
}
重複配信を安全に処理するため、冪等性キー(eventId)を使用します。
サーガパターン(オーケストレーション)
class OrderSaga {
private steps: SagaStep[] = [
{
name: "reserveInventory",
execute: (ctx) => inventoryService.reserve(ctx.items),
compensate: (ctx) => inventoryService.release(ctx.items),
},
{
name: "processPayment",
execute: (ctx) => paymentService.charge(ctx.customerId, ctx.amount),
compensate: (ctx) => paymentService.refund(ctx.paymentId),
},
{
name: "confirmOrder",
execute: (ctx) => orderService.confirm(ctx.orderId),
compensate: (ctx) => orderService.cancel(ctx.orderId),
},
];
async run(context: SagaContext): Promise<void> {
const completed: SagaStep[] = [];
for (const step of this.steps) {
try {
const result = await step.execute(context);
Object.assign(context, result);
completed.push(step);
} catch (error) {
for (const s of completed.reverse()) {
await s.compensate(context);
}
throw new SagaFailedError(step.name, error);
}
}
}
}
API ゲートウェイパターン
# Kong or similar gateway config
services:
- name: orders
url: http://order-service:3000
routes:
- paths: ["/api/v1/orders"]
methods: [GET, POST]
plugins:
- name: rate-limiting
config:
minute: 100
- name: jwt
- name: correlation-id
- name: users
url: http://user-service:3000
routes:
- paths: ["/api/v1/users"]
plugins:
- name: rate-limiting
config:
minute: 200
ヘルスチェックパターン
app.get("/health", async (req, res) => {
const checks = {
database: await checkDatabase(),
cache: await checkRedis(),
broker: await checkMessageBroker(),
};
const healthy = Object.values(checks).every(c => c.status === "up");
res.status(healthy ? 200 : 503).json({
status: healthy ? "healthy" : "degraded",
checks,
version: process.env.APP_VERSION,
uptime: process.uptime(),
});
});
アンチパターン
- サービス間でデータベースを共有する(密結合)
- 複数のサービスにまたがる同期 HTTP チェーン(連鎖的な障害)
- 分散モノリスを構築する(サービスを独立してデプロイできない)
- サービス間呼び出しにサーキットブレーカーがない
- イベントハンドラーに冪等性を実装しない
- サーガではなく分散トランザクションを使用する
チェックリスト
- 各サービスが独自のデータストアを所有している
- 非同期ワークフローでは、サービスがイベントを介して通信している
- 補償処理を伴う複数サービス間のトランザクションにサーガパターンを使用している
- サーキットブレーカーが連鎖的な障害を防いでいる
- API ゲートウェイがルーティング、レート制限、認証を処理している
- ヘルスチェックエンドポイントが依存先の状態を報告している
- イベントハンドラーが冪等である(重複を安全に処理できる)
- サービスを独立してデプロイおよびスケーリングできる
コメント
Markdown 対応