メインコンテンツへスキップ
ブログ一覧に戻る
Web制作・運用

マイクロサービス入門:分割する利益と、分散によって増える責任

2024年9月1日
最終更新: 2026年10月8日
11分で読めます

この記事でわかること

マイクロサービスの価値は、サービスを小さくすることより、独立して変更・運用できることにあります。注文処理を例に、データ所有、部分障害、再試行、段階移行の判断を整理します。

2026年10月8日にMicrosoft Azure Architecture CenterのMicroservices architecture style本文を再確認した。マイクロサービスはbounded context内の業務能力を持つ小さな自律サービスの集合で、独立デプロイやスケールを狙える一方、ネットワーク障害、データ整合性、観測、認証認可、契約、バージョン、運用の責任を増やす。分割前に業務境界・データ所有・障害時の振る舞いを定義し、サービス数ではなく変更単位と運用能力で判断する。

30秒で要点

マイクロサービスは、業務のまとまりごとにサービスを分け、独立して変更・配備・運用できるようにする設計です。ファイルやコンテナを細かく分けるだけでは、その利益は得られません。

  • 同時に変更し続ける機能は、境界を分けるほど調整が増える場合があります。
  • 通信先の遅延、結果不明、重複、データの反映待ちを通常の状態として設計します。
  • モノリス内の整理で解決できる課題なら、分散を増やさず改善する選択肢もあります。

分割の理由を「将来大きくなるから」で終わらせず、今どの変更や障害対応が詰まっているのかから考えます。

独立して変えたいものが、分割の候補になる

一つのアプリでも、注文、在庫、請求の内部構造を整理できます。このように境界を明確にしつつ配備単位を一つに保つ構成を、モジュラーモノリスと呼びます。ネットワーク越しの連携を増やさず、責任を整理する方法です。

マイクロサービスでは、その境界を実行・配備・データ管理にも広げます。たとえば在庫計算だけ負荷が高い、請求の変更を別の周期で配備したい、といった事情が候補になります。Microsoftのアーキテクチャ解説も、独立性の利点と、通信・整合性・運用の複雑さを併記しています。

表が収まらない場合は、横にスクロールできます

判断すること一つの配備単位が合いやすい場合分割を検討する理由になる場合
変更のまとまり多くの変更が複数機能を同時に触る一つの業務だけ独立して変更できる
データの整合同時に確定すべき更新が多い反映待ちを含む業務状態を扱える
負荷全体を同じ規模で動かして問題ない一部だけ大きく伸ばす必要がある
運用体制少数の担当が全体を支えるサービスの監視・当番・更新責任を持てる
契約の管理同時更新で互換性を揃えられる新旧版が混在するAPIやイベントを維持できる

これは採用点数表ではありません。請求のように強い整合性が必要な部分を一つに保ち、通知だけを分ける構成もあります。システム全体を一つの方式に統一する必要はありません。

境界は、技術の種類より業務の責任から決める

「画面サービス」「SQLサービス」のように技術の層だけで分けると、一つの業務変更で全サービスの更新が必要になる場合があります。先に、誰がどの判断とデータを所有するかを定義します。

架空の受注システムなら、次の分担が考えられます。

表が収まらない場合は、横にスクロールできます

所有者自分で確定すること外へ伝えること
注文サービス注文内容と受付状態注文を受け付けた事実
在庫サービス商品ごとの引当可否と予約在庫を確保できたか
請求サービス請求・支払いの状態請求処理の結果

他サービスのDBを直接更新すると、テーブル変更と権限、障害が相手の内部実装へ結び付きます。APIやイベントを通すだけで独立性が完成するわけではありませんが、契約として扱う入口を作れます。

同じDB製品を使うことは可能です。ただし所有範囲とアクセス権を分け、バックアップや障害の単位が共有される影響も確認します。異なる製品を増やすほど、担当者の技能や復旧手順も必要になります。

境界の妥当性は変更履歴から見直せます。たとえば「直近の業務変更のうち、複数サービスの同時配備を要した件数/全業務変更件数」を調べます。同時変更が多いなら、契約や境界を見直す手がかりになります。一定の割合を超えれば失敗、という普遍的な基準はありません。

同期通信と非同期通信では、待ち方が変わる

同期APIは、呼び出し元が返答を待って次へ進む方式です。確認結果をその場で必要とする処理に向きますが、依存先が遅いと待ち時間が重なります。サービスの場所を探す仕組みやAPI Gatewayを導入しても、依存先の遅さは消えません。

非同期のイベント連携では、受け付けた事実を送って後続処理へ渡します。画面へ先に「受付済み」と返せる一方、処理がまだ終わっていない状態を保存し、利用者へ説明する必要があります。「受付済み」と「在庫確保済み」を同じ成功表示にしないことが重要です。

どちらでも、入力形式、必須項目、エラー、認証と認可、版の互換性を契約に含めます。項目を追加しただけで古い受信側が停止しないか、逆に未知項目を無視して意味を取り違えないかを確かめます。通信が内部ネットワークにあることだけでは、操作権限の確認を省略できません。

タイムアウトは「相手が何もしなかった」証拠ではない

在庫を確保するAPIへ送信した後、返答が届く前に接続が切れたとします。在庫側では確保済みかもしれません。呼び出し元が同じ注文を別の操作として再送すれば、二重引当になる可能性があります。

このため、再試行の前に同じ業務操作を識別する方法と、結果を問い合わせる経路を決めます。冪等性は、同じ操作が繰り返されても意図した副作用を重ねない性質です。キーを送るだけで成立するものではなく、保存期間、同時要求、内容が異なる再送の扱いまで契約にします。

表が収まらない場合は、横にスクロールできます

対策減らしたい問題それだけでは解決しないこと
タイムアウト待ち続けて資源を占有する相手が処理したかどうか
上限付き再試行一時的な通信・過負荷の失敗永続的な入力不正、重複した副作用
サーキットブレーカー障害先へ呼び出しを送り続けるデータの修復やサービス自体の回復
同時実行数の制限一つの依存先が処理枠を使い切る容量を超えた要求の業務上の扱い
代替応答一部停止時に全部を待たせる古い在庫や価格を使ってよいかの判断
Retryパターンは、再試行による重複と負荷、複数層での再試行を注意点に挙げています。間隔を延ばし、必要に応じてばらつきを加え、合計の待ち時間と回数を制限します。入力不正や権限不足を同じ内容で繰り返しても回復しません。 サーキットブレーカーは、失敗が続く間は呼び出しを止め、少量の試行で回復を確かめる仕組みです。失敗時に何を利用者へ返すかと一緒に設計します。単に「サービスを分けたので障害は広がらない」とは言えません。

DB更新とイベント送信の間には、失敗する隙間がある

注文をDBへ保存した直後にプロセスが止まると、在庫側へ通知できない場合があります。順序を逆にして通知から送ると、今度はDBの保存に失敗した注文を在庫側が処理してしまいます。

Outboxパターンでは、注文の保存と「送る予定のイベント」の記録を同じDBトランザクションに入れます。別の配送処理が、確定した送信予定を読み出して送ります。AWSのTransactional outbox解説

注文DBへの保存と直接通知を別々に行うと途中停止で通知が欠ける。Outboxでは注文と送信予定を同じトランザクションで確定し、別処理で配送するが、受信側の重複対策と滞留監視は残る
図1:Outboxが埋めるのは、業務更新と送信予定の記録の間の隙間。受信側で一度だけ業務効果を出す設計や、届かないイベントの調査まで自動で完成するわけではない。

配送後、送信済みの記録を付ける前に配送処理が落ちると、同じイベントが再送されます。受信側ではイベントIDと業務更新を整合して保存し、同じIDの再配信で副作用を重ねないようにします。メモリ内の一覧だけでは、再起動や複数台の同時処理に耐えられません。

順序にも注意が必要です。「注文を取り消した」の後に遅れて「注文を受け付けた」が届いたとき、古い状態へ戻してよいかを決めます。業務IDごとの版や状態遷移の規則を持ち、過去イベントの扱いを明確にします。全イベントの厳密な全体順序が必要かは、業務ごとに検討します。

ローカルな確定と、業務全体の確定は別

サービスを分けても、各DBの中でACIDトランザクションを使えます。分散したから全処理が結果整合性だけになるわけではありません。一方、複数サービスへまたがる注文全体をどう確定するかは、別の設計が必要です。

Sagaでは、在庫予約、請求などのローカルな処理を組み合わせ、途中で失敗したら予約解除などの補償を行います。補償は過去のDB更新をなかったことにする操作ではありません。発送済みの商品や送信済みの通知は、単純には取り消せません。返金が失敗する場合も含め、状態の記録、再処理、担当者による照合が必要です。Sagaの仕組みと制約

分割前に、失敗した注文を机上で追ってみる

次の表は架空の注文処理に対する検証計画です。実サービスに障害を注入した測定結果ではありません。各状態を、どの記録から、誰が、いつ判断するかまで答えられるかを確認します。

表が収まらない場合は、横にスクロールできます

想定する失敗期待する扱い調べる記録
注文DBのcommit前に停止未確定の通知を出さない注文行とOutbox行の確定状態
commit後、配送前に停止未配送分を後で回収できるOutboxの未配送件数と最古の滞留時間
配送後、記録前に停止重複配送で二重引当しないイベントIDと受信側の確定結果
在庫APIの返答だけ消失再送前に同じ操作の結果を照合業務操作IDと問い合わせ結果
取り消しが先に届く遅れた通知で状態を巻き戻さない業務IDごとの版と状態遷移
補償処理も失敗未解決として担当者へ渡す補償の状態、期限、対応履歴

机上で説明できたら、隔離した検証環境で実装を確かめます。サービス単体のテストだけでなく、新旧APIの契約、DBを含む連携、業務全体の結果を分けて確認します。ログには共通の業務IDや追跡IDを使い、秘密や個人情報を無条件に含めないようにします。

一つずつ移し、戻せる期間を明確にする

移行は、依存が少なく業務境界が明確な機能から始めます。入口の振り分けを用意し、一部だけ新サービスへ移すStrangler Figパターンは選択肢です。ただし入口が単一障害点にならないか、新旧データの整合と二重運用の費用も確認します。段階移行の考慮事項

戻し方は、単に振り分け先を旧サービスへ戻すだけとは限りません。新サービスだけが受け取った更新をどう扱うか、旧形式で読めないデータがないかが問題になります。旧DBや変換処理を削除する前に、戻せる条件を明文化します。

成果は、独立して配備できた変更の割合、業務完了までの時間、期限を超えた未解決件数、当番対応の負担で比較できます。再試行を含むHTTP成功率だけでは、同じ注文の重複や未完了を見落とします。分母を重複除去した注文件数にした業務成功率も別に見ます。

運用の費用には実行基盤だけでなく、通信、ログ、監視、契約テスト、当番、DBの復旧手順を含めます。必要な担当を置けないなら、内部の境界を整えて配備単位を保つ判断にも合理性があります。

実行環境の分離はコンテナ技術入門、配備と公開の条件はCI/CD入門で扱います。再送の契約を詰める場合は冪等性キーの考え方、運用全体は運用保守ガイドを参照してください。

よくある質問(FAQ)