背景
問い
セキュリティなどの運用系コンポーネント系の横断的関心事も、
なんらかの承認チェックといった【イベント】をトリガーに、次のビジネスロジックへと進むと考えた際に、アスペクト指向とイベントストーミングを組み合わせて、
すべてのイベントを介したフローを可視化したら、仮にセキュリティコンポーネント側のプロセスにパフォーマンスのボトルネックがあった際に見つけやすくなるのではないか?
仮説
以下の図のように、
アスペクト指向とイベントストーミングを組み合わせることで、ビジネスロジックと、
それに横断的に関わるセキュリティ等の運用コンポーネントの動作を一枚地図のように可視化できるはずです。
🧠 なぜその組み合わせが強力なのか?
まず、それぞれの役割を整理します。
イベントストーミングの役割
ビジネスプロセス全体を、ドメインイベント(=ビジネスで意味のある出来事) の連なりとして可視化します。
例:「注文が確定した」「支払いが行われた」「商品が発送された」というように過去形。
これは 「ビジネスの関心事」 の地図です。
アスペクト指向(AOP)の役割
ロギング、トランザクション管理、セキュリティチェックといった 「横断的関心事」 を、
ビジネスロジックから分離して実装する技術です。
これは 「システム(技術)の関心事」 を整理する手法です。
この2つを組み合わせると、ビジネスの地図(イベントストーミング)の上に、
技術の関心事(アスペクト)がどこでどのように関わってくるかをマッピングできるようになります。
✅ ボトルネック発見の具体的なプロセス
以下のような流れでボトルネックが浮かび上がってきます。
ステップ1:イベントストーミングでビジネスフローを可視化する
まず、関係者全員でイベントストーミングを行い、ビジネスフローを付箋で洗い出します。
この時点では、まだセキュリティのことは意識していません。
ステップ2:アスペクト(横断的関心事)をマッピングする
次に、「決済を処理する」というビジネスロジックの前後に、アスペクト指向で実装されるであろうセキュリティチェックを別の色の付箋などでマッピングしていきます。
前後にアスペクトを追加
アスペクト追加後の全体像
ステップ3:ボトルネックを特定・議論する
この可視化されたフローを見ることで、チームは以下のような議論ができるようになります。
パフォーマンスの可視化
「『決済が承認された』というビジネスイベントが遅いのは、ビジネスロジックそのものではなく、同期的(ブロッキング)に実行される 『不正検知』の外部API呼び出しが遅い のが原因ではないか?」といった問い。
依存関係の明確化
「この『監査ログ記録』は、もし失敗したら決済全体をロールバックすべきか?
それとも非同期で実行して、決済処理のレスポンスを先に返すべきか?」
コストの認識
ビジネス的には一瞬に見える『決済処理』が、システム内部ではこれだけ多くの処理を直列で実行していることがわかりました。
この 『見えにくいコスト』 を削減できないか?」
APM(Application Performance Management)ツールなどを使えば、マッピングした各アスペクト(認証チェックなど)の平均実行時間を書き込むことも可能です。
これにより、「このセキュリティチェックに平均150msかかっている」といった具体的な数字で議論でき、どこがボトルネックで、どこを改善すべきかが一目瞭然になります。
ボトルネックの解消
アスペクト指向とイベントストーミングでボトルネックを可視化した後、具体的な改善策を体系的に検討する上で、ECRS原則は非常に強力な思考フレームワークとなります。
ECRSは、元々製造業の工程改善で用いられる手法ですが、ソフトウェアアーキテクチャやプロセスの改善にも極めて有効です。
可視化されたボトルネック(例:「決済処理」に割り込む不正検知アスペクトが遅い)に対して、以下の順番で改善策を検討していきます。
ここでは、「決済処理」フローの中に同期的に実行される
「不正検知APIの呼び出し(300ms)」がボトルネックとして特定された、というシナリオを想定します。
❌ E (Eliminate): 排除 – その処理をなくせないか?
概要・用途
最も効果が大きく、最初に検討すべき原則です。
ボトルネックとなっている処理そのものを、特定の条件下で完全に取り除くことを目指します。
具体的な事例
「この不正検知は、全ての決済で同期的に実行する必要があるのか?」と考えます。
過去の取引データを分析した結果、「購入履歴が豊富で信頼度の高い優良顧客」かつ
「1,000円以下の少額決済」の場合、不正率は0.001%と極めて低いことが判明したとします。
→ 改善策として、
この特定の条件を満たす決済においては、
同期的な不正検知APIの呼び出しを完全に排除し、常に成功とみなす。
メリット
・対象となるトランザクションのパフォーマンスが劇的に向上する。
・API呼び出しコスト(金銭的、計算リソース的)を削減できる。
デメリット
・わずかでも不正のリスクは残るため、ビジネス的なリスク許容度の判断が必要。
・監査やコンプライアンス要件で、全ての取引のチェックが義務付けられている場合は採用できない。
🔗 C (Combine): 結合 – 統合できないか?
概要・用途
複数の処理やデータ取得がバラバラに行われている場合、それらを一つにまとめ、オーバーヘッドを削減することを目指します。
具体的な事例
仮に、「決済処理」の裏側で、クライアントから
①ユーザー認証状態のチェック
②不正検知のチェック
③ポイント残高のチェック
という3回のAPI呼び出しが個別に行われていることが判明したとします。
→ 改善策としては、
サーバー側にBFF (Backend for Frontend) パターンなどを使い、
これら3つのチェックを 一度のAPI呼び出しでまとめて実行するエンドポイントを新たに作成する。
すると、クライアントからのネットワーク往復は1回で済むようになります。
メリット
・ネットワークのラウンドトリップタイムが削減され、UXが向上する。
・クライアント側のロジックがシンプルになる。
デメリット
・結合されたAPIが新たな単一障害点(SPOF)やボトルネックになる可能性がある。
・バックエンド側のサービス間の結合度が高まる。
🔄 R (Rearrange): 再配置 – 順序やタイミングを変えられないか?
概要・用途
処理の順序を変更したり、同期的な処理を非同期に切り替えることで、ユーザーの待ち時間を削減し、体感パフォーマンスを向上させることを目指します。
具体的な事例
「不正検知は決済完了に必須だが、ユーザーへの応答をブロックする必要はないのでは?」
→ 改善策として、処理の順序を再配置します。
①. まず、決済ゲートウェイとの通信(50ms)だけを行い、決済を完了させる。
即座にユーザーへ「決済完了」の応答を返す。
②. その後、バックグラウンドで非同期に不正検知API(300ms)を呼び出す。
もし不正が検知された場合は、注文を保留にして手動レビューに回す、あるいは補償トランザクションで決済を取り消す、といった別のフローを起動する。
メリット
・ユーザーの体感パフォーマンスが劇的に改善される(待ち時間が350ms→50msになる)。
・決済の成功率と不正検知の精度を両立できる。
デメリット
・システム全体の複雑性が増す(結果整合性、非同期処理、補償処理の実装が必要)。
・不正が検知された場合のリカバリープロセスをビジネス側と合意する必要がある。
✨ S (Simplify): 簡素化 – もっと簡単にできないか?
概要・用途
処理をなくしたり、順序を変えたりできない場合に、その処理自体をよりシンプルで高速なものに改善することを目指します。
具体的な事例
「不正検知APIの呼び出し自体を高速化できないか?」と考えます。
調査の結果、現在APIにユーザーの全プロフィール情報(20KBのJSON)を毎回送信しているが、実際にはユーザーID、決済額、IPアドレスの3つしか利用していないことが判明したとします。
→ 改善策としては、
APIのペイロードを必要最小限のデータに簡素化する。
あるいは、
不正検知サービス側で、頻繁にアクセスされる信頼度スコアなどをキャッシュする
ようにし、DBへの問い合わせを減らす。
メリット
・既存のアーキテクチャを大きく変えずに、パフォーマンスを改善できる。
・ネットワーク帯域や計算リソースの節約に繋がる。
デメリット
・改善効果が限定的である場合が多い。
・簡素化のために、本来必要だった情報(コンテキスト)が失われ、精度がわずかに低下する可能性も考慮する必要がある。
まとめ
アスペクト指向とイベントストーミングの組み合わせは、以下の効果をもたらします。
暗黙知の可視化
セキュリティのような横断的関心事が、ビジネスフローのどこに「割り込み」、
どのような影響を与えているかを全員が理解できる。
的確な問題特定
パフォーマンス問題が発生した際に、「なんとなく遅い」ではなく、
「どのセキュリティチェックが、どのビジネスイベントを遅延させているか」を具体的に特定できる。
建設的な議論の促進
ビジネスサイドと開発サイドが同じ図を見ながら、セキュリティ要件とパフォーマンスの
トレードオフについて、建設的に議論できるようになる。
これは、DevSecOpsの文化を成熟させ、安全で高速なシステムを構築するためのプラクティスと言えるでしょう。



