プレイブック
本番環境における DDD: 分散システムと最新化戦略 (Ddd 4)
運用環境で DDD を実装するにはどうすればよいですか? Event Storming、Saga、Transactional Outbox、Anti-Corrupting Layer、Strangler を使用したレガシー変換ガイド 図 1
DDD - ソフトウェアのビジネス言語
一部 4 の 4
The map for this chapter
This chapter is not a list of patterns to memorize. It follows how business truth inside a monolith can move safely while the system changes.
Monolith
↓
Event Storming
↓
Bounded Context
↓
Saga
↓
Outbox
↓
Strangler Fig
↓
Production
本番環境における本当の質問
DDD で境界線を引くことが始まりです。運用環境では、これらの境界が変化してもシステムとユーザーの信頼を維持することが実際のテストとなります。従来のモノリス内の注文フローを一晩で書き換えたくなるかもしれません。しかし、これは通常、最もリスクの高い選択肢です。```text Monolith → mevcut iş gerçeği Yeni bağlam → daha temiz model Kademeli geçiş → ölçülebilir güven
## 最初に説明した概念```text
📦 Event Storming
İş olaylarını, komutları ve riskleri birlikte görünür kılan keşif atölyesi.
📦 Saga
Dağıtık bir iş akışındaki yerel işlemleri ve başarısızlıktaki iş telafisini yöneten model.
📦 Transactional Outbox
Veri değişikliği ile yayınlanacak event'i aynı yerel transaction içinde kaydeden desen.
📦 Strangler Fig
Legacy sistemi tek seferde değiştirmek yerine yeni sınırlarla adım adım saran dönüşüm stratejisi.
```ドメイン イベントは、`SiparişOnaylandı` という過去形で書かれたビジネス上の事実です。コマンドは意図です: `SiparişiOnayla`。この区別は必要です。意図は拒否される可能性があるため、起こった事実は、他の文脈が自信を持って反応できる記録です。
## Event Storming を使用して、まず目に見えないストリームを見つけます
本番環境の変革は、コード インベントリではなく、ワークフローから始まります。製品、運用、エンジニアリングが同じ壁にあり、イベントが過去形でリストされています。コマンド、アクター、外部システム、レッド ホット スポットを追加します。```text
SiparişOnaylandı ← SiparişiOnayla ← Customer
↓
StokRezerveEdildi ← StokRezerveEt
↓
ÖdemeAlındı ← ÖdemeyiAl ← Payment Gateway
```流れも端から端まで読んでみてください。逆の物語。返金、一部支払い、タイムアウト、手動介入など、ハッピー パスに隠されていた決定を可視化します。境界コンテキストはテーブル名ではありません。決定は言語と所有権が変わる場所で見られます。
## 佐賀: ロールバックではなく、労働補償
支払い、在庫、配送が異なるコンテキストで行われる場合、単一の ACID トランザクションは存在しません。 2PC は強力な一貫性を約束できます。ただし、コーディネーターまたは参加者が失敗した場合、ロックの保持とアクセシビリティの料金が発生します。代わりに、Saga は各ローカル ステップの補償を定義します。```text
Reserve inventory → Capture payment → Create shipment
payment fails → Release inventory
````ReleaseInventory` も冪等である必要があります。同じイベントが 2 回発生した場合、ストックは 2 回増加しないはずです。短いローカルなストリームでは、振り付けで十分かもしれません。複数ステップの可視性が重要なプロセスのオーケストレーション。ステートマシンと単一の観察ポイントを提供します。
## 送信箱とトレーサビリティ: 移行を証明できるようにする
オーダーのコミット中にブローカーに到達できない場合、データベースとメッセージ パブリケーションの間に二重書き込みギャップが発生します。それが送信ボックスが存在する理由です。```text
Local transaction
→ Order'ı kaydet
→ OrderConfirmed'i Outbox'a yaz
→ Commit
Relay → Broker → Consumer → Projection
```消費者は、少なくとも 1 回の配信でメッセージが重複することを予期する必要があります。イベント ID、集計バージョン、ビジネスへの影響を確認する必要があります。相関 ID はエンドツーエンド フローの一部を示し、因果関係 ID はどの決定がイベントを生成したかを示します。これらはログフィールドではありません。 "どうしたの?"事件当時。そして「なぜそうなったのか?」があなたの質問に対する答えです。
## Strangler Fig によるレガシー変換
ビッグバン変革とは、ビジネス ルールが発見される前に古い動作が失われるリスクです。新しいコンテキストをレガシーの隣にインポートします。まずデータと行動の違いを測定し、次にトラフィックを促進します。```text
1. Replication only → yeni modele veri akıt
2. Shadow reads → eski ve yeni cevabı karşılaştır
3. Partial reads → küçük trafik yüzdesini yönlendir
4. Write migration → yeni sınırda yaz, geri uyumu koru
5. Full cutover → metriklerle doğrulanmış geçiş
6. Decommission → köprüleri ve eski kodu kaldır
```腐敗防止層は、ここでは新しいモデルのシールドです。従来のあいまいなフィールドをドメインに直接移動するのではなく、`LEGACY_ORDER_STATE=7` が新しいコンテキストで意味のある `FulfilmentStatus` になるように変換します。したがって、ダーティ モデルの影響は 1 つのアダプタに残ります。
## 受け入れ基準: 導入だけでなくロールバック機能
移行の成功は、新しいエンドポイントの応答性だけではありません。シャドウ読み取り差分率、P95 遅延差分、コンシューマ ラグ、DLQ 深度、ロールバック プランが表示されるはずです。再生コストはイベントの数に応じて O(n) です。スナップショットまたはセグメント化されたリプレイはこのコストを削減できますが、検証された履歴の代わりにはなりません。
観察できないシステムは管理できません。各イベント コントラクトには、所有者、リリース戦略、アラート、およびリプレイ Runbook が必要です。
## 誤った信頼を生み出す一致```text
❌ DDD = mikroservis dönüşümü
✓ DDD önce iş dilini ve karar sınırını korur; mikroservis bazen sonuçtur.
❌ Saga = teknik rollback
✓ Saga, geri alınamayan iş etkisini telafi eden iş akışıdır.
❌ Outbox = exactly-once teslimat
✓ Outbox event kaybını önler; consumer yine duplicate için idempotent olmalıdır.
❌ Shadow read = test tamamlandı
✓ Karşılaştırma, canlı trafikte davranış farkını ölçen uzun süreli kanıttır.
❌ ACL = gereksiz katman
✓ ACL, legacy dilinin yeni domain'i kirletmesini engeller.
制作準備チェックリスト
- イベント ストーミングではハッピー パス以外のホット スポットや外部システムが表示されますか?
- 冪等補償は、Saga ステップごとに定義されていますか?
- ブローカーに障害が発生した場合、Outbox はデータベース レコードとイベントの間のギャップを埋めますか?
- 相関 ID、因果関係 ID、消費者ラグ、DLQ の可観測性はありますか?
- 新しいコンテキストは ACL を使用してレガシー モデルを保護しますか?
- シャドウ読み取り、カスケード トラフィック、ロールバックに対して測定可能なしきい値が確立されていますか?
- 古い橋の日付と所有者は明らかですか?
変換の複雑さはサービスの数では測られません。独立した変更は、エラーの分離と返品の証明によって測定されます。
この記事で覚えておくべきこと
- 運用環境における DDD とは、モデルが変更されてもビジネス言語に忠実であり続けることを意味します。
- イベント ストーミングは、コードの前では目に見えない意思決定とリスクを発見します。
- Saga、Outbox、冪等性は分散障害を設計入力として受け入れます。
- Strangler Fig と ACL は、従来の変換を 1 つのジャンプではなく検証可能なステップに分割します。
近代化とは古いシステムを破壊することではありません。ビジネスの価値を失わずに、より安全な変化のリズムを確立することです。
FAQ
よくある質問
イベントストーミングとは何ですか?
ビジネスイベント、コマンド、リスクをまとめて可視化するディスカバリワークショップ。
佐賀って何?
分散ワークフローでのローカル操作と障害時のジョブ回復を管理するモデル。
「DDD=マイクロサービス化」は正しいでしょうか?
DDD では、まずビジネス言語と意思決定の境界を保持します。その結果としてマイクロサービスが生まれることもあります。
このセクションでは何を修正しますか?
目的は、より多くのサービスを生み出すことではありません。その目的は、ビジネスの言語が変わったときに、システムも安全に変更できるようにすることです。運用環境における DDD とは、モデルが変更されてもビジネス言語に忠実であり続けることを意味します。 DDD で境界線を引くことが始まりです。運用環境では、これらの境界が変化してもシステムとユーザーの信頼を維持することが実際のテストとなります。従来のモノリス内の注文フローを一晩で書き換えたくなるかもしれません。しかし、これは通常、最もリスクの高い選択肢です。
学んだエンジニアリング原則
- 実稼働 DDD では、イベントと境界がエラー下でもビジネスの意味を維持する必要があります。
- サーガ、アウトボックス、冪等性。分散配信は例外ではなく標準であることを認識しています。
- Strangler Fig を使用すると、ACL はレガシー変換の変更を小さく、測定可能かつ可逆的に保ちます。
続きを読む
続きを読む
シリーズの次のシリーズ
DDD は大規模システムでどのように動作しますか?
DDD は大規模システムでどのように拡張されますか?有界コンテキスト、コンテキスト マッピング、コンウェイの法則、モジュラー モノリス、マイクロサービス境界、トランザクション アウトボックスの決定…
同じシリーズ
DDD コード: エンティティ、値オブジェクト、および集計
DDD 戦術パターンはどのように機能しますか?値オブジェクト、エンティティ、集計、ドメイン サービス、アプリケーション サービス、リポジトリの境界と実際の注文例…
同じシリーズ
DDD - データベースのためではなく、ビジネスのためのソフトウェアを設計する
ドメイン駆動設計とは何ですか?データベース駆動設計の限界、共通言語の力、DDD が実際の投資となる場合についてのガイドです。