コード探偵ロックの事件簿:決済プロバイダのデプロイで10秒だけ止まった API が、全インスタンスの同時リトライで60秒の停止になった。リトライの間隔を指数的に延ばしてランダムにずらし、一時的なエラーだけをやり直す(Retry Pattern)。
コード探偵ロックの事件簿:3週間で3回、決済 API の障害で注文がすべて失敗した。リトライ回数とタイムアウトを増やすほど接続プールが埋まり、停止は長引く。失敗が続いたら呼び出しを止め、様子を見て戻す3つの状態を持たせる(Circuit Breaker)。
コード探偵ロックの事件簿:マイクロサービスに分けた後も、注文サービスが在庫・配送・請求の各サービスを順に直接呼んでいたため、請求サービスの障害で注文確定が45分止まった。メッセージブローカーを挟み、送る側と受ける側が互いを知らない形にする(Publish-Subscribe)。
コード探偵ロックの事件簿:在庫確保を DB にコミットした直後、メッセージキューが落ちていて決済サービスへの通知が消えた。DB の更新と送るイベントを同じトランザクションで Outbox テーブルに書き、別のプロセスが後から確実に送る(Outbox)。
コード探偵ロックの事件簿:在庫・決済・配送を1つのトランザクションとして扱っていたため、決済が応答しないと在庫と配送のコミットも止まり、300件の注文を週末に1件ずつ手で戻した。ステップごとに実行と補償を対で持ち、失敗したら逆順に取り消す(Saga)。
コード探偵ロックの事件簿:帳票3種を PDF・CSV・HTML で出すフォーマッターが isa で帳票を判定し、CSV だけ1つ書き忘れた。漏れをクラス構築時のエラーにする(Double Dispatch)。
コード探偵ロックの事件簿:受注処理のすべてが500行のメソッドに詰まり、1行直すと無関係な箇所が壊れる。上司には「テストを書いてから直せ」と言われたが、入口が1つではテストできない。処理を独立したステージに分け、順に流す(Pipeline)。
コード探偵ロックの事件簿:税率計算の浮動小数点の丸めで請求金額が1円ずれ、翌週には USD の送金額に JPY の手数料が足された。金額を最小単位の整数と通貨の組で持ち、違う通貨どうしの計算をエラーにする(Money Pattern)。
コード探偵ロックの事件簿:10年保守してきた料金設定クラスの属性がすべて rw で、フロントチームが受け取った割引率を書き換えて誤請求が出た。属性を ro にして書き換えを封じ、変えたいときは新しいオブジェクトを返す(Immutable Object)。
コード探偵ロックの事件簿:不動産の物件管理で、同じ住所どうしを比べても false、名前を更新した物件を更新前と比べても false になる。住所は値で比べて不変に、物件は ID で比べる。Entity と Value Object の違いを Perl と Moo で実装します。
コード探偵ロックの事件簿:3部門の顧客を1つのモデルに統合したら、営業のメール変更で配送通知の宛先まで変わった。部門ごとにモデルを分け、共有は ID と名前だけにする(Bounded Context)。
コード探偵ロックの事件簿:注文確定のメソッドがメール・在庫引き当て・ポイント加算を直接呼んでいて、ポイント加算を足したら在庫引き当てが二重に走った。「注文が確定した」を出来事のオブジェクトとして発行し、後続の処理は購読側に任せる(Domain Event)。
コード探偵ロックの事件簿:EC の注文明細を外から直接書き換えられるため、月末のたびに経理から「合計金額が明細と合わない」と連絡が来て、SQL で手直ししてきた。明細の変更は必ず注文を通し、合計を自動で再計算させる(Aggregate)。
コード探偵ロックの事件簿:キャンペーンのルール200本以上を文字列で DB に置いて eval で実行していたため、括弧の閉じ忘れ1つで3時間の本番停止になった。ルールを式のオブジェクトの木にして評価し、構文の誤りをデプロイ前に見つける(Interpreter)。
コード探偵ロックの事件簿:チャネルごとの if-elsif でできた通知基盤で、Webhook を足したら Slack 通知が壊れた。チャネルをプラグインに分け、登録で足す(Plugin)。