見出し画像

アーキテクチャの7つの設計パターンを読んでみた

これを読んでみました。
正直聞いたこともなかったが今後どこかで使えそうなパターンもあって面白かったのでまとめます。

ここでは7つ説明がありました。

Circuit Breaker Pattern

このパターンは、外部システムへの依存性が高く、そのシステムが頻繁に失敗するか、またはレスポンスが遅い場合に有効。

例えば、あなたのアプリケーションが外部の天気予報APIに依存しているとします。このAPIが頻繁にダウンすると、ユーザーは天気情報を取得できなくなります。ここでCircuit Breaker Patternを導入すると、APIがダウンしている間は、アプリケーションはデフォルトの天気情報(例えば、「現在の天気情報は利用できません」)を表示します。APIが再び利用可能になると、アプリケーションは正常な動作に戻ります。

このパターンを実装するためには、通常は特定のライブラリ(例えばResilience4jなど)を使用するみたいです。

Event Sourcing Pattern

このパターンは、アプリケーションがデータの変更履歴を追跡する必要がある場合、またはデータの状態を特定の時点に戻す必要がある場合に有効。

例えば、銀行の口座管理システムを考えてみましょう。口座の残高は、預金と引き出しのイベントの結果として計算されます。Event Sourcing Patternを使用すると、すべての預金と引き出しのイベントを保存し、これらのイベントを再生することで任意の時点での口座残高を計算できます。

このパターンを実装するためには、イベントストアと呼ばれる特殊なデータベース(例えば、EventStore、Kafka、Azure Event Hubsなど)が必要です。イベントストアは、システムの状態を変更するすべてのイベントを保存します。

一方でリレーショナルデータベースをカスタマイズしてイベントストアとして使用することも可能。

いずれにせよイベントは、過去の任意の時点から再生することができます。

イベントソーシングは、CQRSパターンと組み合わせて使用されることが多いらしいです。

SideCar Pattern

このパターンは、アプリケーションが追加のサービス(ログ記録、モニタリング、設定管理など)を必要とする場合に適しています。

例えば、あなたのアプリケーションがログをCloudWatchに送信する必要があるとします。しかし、ログ送信のコードをアプリケーションのメインコードに混ぜると、コードが複雑になります。ここでSideCar Patternを使用すると、ログ送信の機能を別のコンテナ(SideCar)に分離できます。アプリケーションはログをローカルに書き込み、SideCarがそれをCloudWatchに送信します。

CQRS (Command and Query Responsibility Segregation)

このパターンは、読み取りと書き込みの負荷が大きく異なる、またはそれぞれの操作に対して異なる最適化が必要な場合に有効。

例えば、あなたのアプリケーションが大量のデータを扱い、ユーザーがデータを頻繁に検索するとします。しかし、データの更新は比較的稀で、大量のデータを一度に更新する必要があります。この場合、読み取りと書き込みの操作を分離するCQRSパターンが有効です。

Rate Limiting Pattern

このパターンは、一部のリソースが過度に消費されるのを防ぐため、または特定のサービスが過度に使用されるのを防ぐために使用されます。

例えば、あなたのAPIが大量のトラフィックを受け取り、サーバーに過度の負荷をかけてしまう場合があります。Rate Limiting Patternを使用すると、各ユーザー(またはIPアドレス)が一定時間内にAPIを呼び出すことができる回数を制限できます。

ちなみにアルゴリムは以下です

トークンバケットアルゴリズム

StripeはAPIリクエストを制御するためにトークンバケットアルゴリズムを使用しています。このアルゴリズムでは、リクエストが来るたびにバケットからトークンを取り、さらに処理します。トークンがない場合、リクエストはドロップされ、ユーザーは再試行する必要があります。

リーキーバケットアルゴリズム

リーキーバケットは、キューを使用してレート制限を実装するシンプルで直感的な方法です。これは単純な先入れ先出しのキュー(FIFO)です。新しいリクエストがキューに追加され、新しいリクエストのスペースがない場合、それらは破棄(リーク)されます。

スライディングウィンドウアルゴリズム

このアルゴリズムはリクエストのタイムスタンプを追跡します。タイムスタンプデータは通常、Redisのようなキャッシュに保持されます。新しいリクエストが来ると、すべての古いタイムスタンプを削除します。新しいリクエストのタイムスタンプをログに追加します。ログのサイズが許容カウントと同じかそれ以下であれば、リクエストは受け入れられます。それ以外の場合は拒否されます。

Strangler Fig Pattern

このパターンは、既存のシステムを新しいシステムに段階的に置き換える必要がある場合に有効。

例えば、あなたの会社が古いeコマースシステムを新しいシステムに移行する必要があるとします。しかし、一度にすべてを移行するのは困難です。Strangler Fig Patternを使用すると、新しいシステムに一つずつ機能を移行していくことができます。既存のシステムを新しいシステムに段階的に置き換える必要がある場合に有効。

もうちょい具体的なイメージにするならこんな感じ。

  1. 既存のシステムと新しいシステムの間にプロキシまたはAPIゲートウェイを配置します。 このプロキシは、入ってくるリクエストを既存のシステムまたは新しいシステムにルーティングします。

  2. 新しいシステムの一部が完成したら、その部分に対応するリクエストを新しいシステムにルーティングします。 例えば、ユーザー管理機能が新しいシステムで完成したら、ユーザーに関するリクエスト(ユーザーの作成、更新、削除など)を新しいシステムにルーティングします。

  3. 新しいシステムが完全に完成するまで、上記のプロセスを繰り返します。 新しいシステムの各部分が完成するたびに、その部分に対応するリクエストを新しいシステムにルーティングします。

  4. 新しいシステムが完全に完成したら、既存のシステムを完全に取り外します。 この時点で、すべてのリクエストは新しいシステムにルーティングされます。

Health Endpoint Monitoring Pattern

このパターンは、アプリケーションの健全性を定期的にチェックする必要がある場合に有効。

例えば、あなたのアプリケーションがクラウド上で動作しているとします。このアプリケーションの健全性を定期的にチェックする必要があります。Health Endpoint Monitoring Patternを使用すると、アプリケーションは健全性チェックのための特別なエンドポイントを提供します。

まとめ

ソフトウェアアーキテクチャの7つの設計パターンについての記事のまとめを行いました。

アーキテクチャの名前は知らなかったけど、あのプロジェクトの時に考えていたことはこういう名前だったのかみたいなものもあると思います。

これらのパターンを理解し、適切な場面で適用することでより効率的で堅牢なソフトウェアを設計・実装することができると思うので何かの参考になれば幸いです。


この記事が気に入ったらサポートをしてみませんか?