リアクティブアーキテクチャ
はじめに
アーキテクチャについていろいろと調べているうちに、「リアクティブシステム」「メッセージ駆動」といったワードを見つけてどんなものなのかが気になったので簡単にまとめました。同じテーマで学習されている方の参考になれば幸いです。
リアクティブ宣言
リアクティブ宣言とは、AkkaやScalaを開発しているLightbend社が「大規模で要求が高度化する昨今のソフトウェアアーキテクチャはリアクティブであるべき」という宣言で、2014年の9月から変わらずに公開されています。
最終的に届けたい価値は、どんな状況でもレスポンシブ(即応性)が確保されている状態。=「いつでも使えるシステム」の実現です。
このある種の当たり前を、伸縮性 や 耐障害性 を原理として、メッセージ駆動 で実現していくというのがコンセプトとなります。
また、即応性、伸縮性、耐障害性、メッセージ駆動を実現できれば、メンテナンス性や拡張可能性の高いシステムに繋がります。
メッセージ駆動
リアクティブ宣言にある4つの構成要素のうち、リアクティブなシステムを構成する上で不可欠となる手段が「メッセージ駆動」です。
- 非同期・ノンブロッキングなメッセージングによってコンポーネント間の境界を確立します
- 疎結合性、隔離性、位置透過性を確立します
- エラーすらもメッセージとして委譲する手段を確保して耐障害性をもたらします
- ノンブロッキングにより、メッセージの受信側はアクティブな時だけリソースを消費し、オーバーヘッドを抑制し、弾力性をもたらします
- 位置透過なメッセージングを使います
- クラスターを跨ぐ場合も、単一のホストの中で閉じる場合も同じ構成とセマンティックで扱うことができ、耐障害性をもたらします
AWS・GCPのメッセージングに関連するサービス
AWSはこちらにサービスの一覧がまとまっています。
https://aws.amazon.com/jp/messaging/
GCPの Pub/Sub に関する説明はこちらで確認できます。
https://cloud.google.com/pubsub?hl=ja
身近な例だと、インフラの予算上限を監視していて上限を超えたら AWS SNS から Slack に通知を飛ばすのに活用しています。
メッセージングにより負荷を管理したり、メッセージキューによる監視や、必要に応じたバックプレッシャーを適用することでフロー制御が可能となり、弾力性をもたらしています。
リアクティブシステム
アーキテクチャレベルでリアクティブ原則に従ったシステムがリアクティブシステムとなります。
- リアクティブ原則
- 応答性を維持する
- 不確実性を受け入れる
- 失敗を受け入れる
- 自律性を表明する
- 一貫性を調整する
- 時間を分離する
- 空間を分離する
- ダイナミクスを処理する
例えば、ローカルキャッシュを使用していたら、ローカルキャッシュを複数のノードと同期させる方法はないのでスケールアップが非常に難しくなり、最大のスケーラビリティと可用性(=一貫性を調整する)を維持できないので、「RxJava等のリアクティブプログラミングでコーディングしているから」「Akkaを使っているから」といって必ずしもリアクティブシステムにはなりません。
上記の説明としてソフトウェアアーキテクチャ例
この記事の説明がわかりやすかったので紹介します。
『“止まらないシステム”ではなく“回復する能力”に価値がある リアクティブシステムを実現するためのCQRSとEvent Sourcing』
まず、ショッピングカートがあったとして、カートを制御するClientからショッピングカートに、アイテム追加のタスクを依頼するメッセージを送信したとします。
このとき、ショッピングカートからClientへ成功・失敗の結果を返すが、Client側はメッセージを投げた後、依頼したタスクの完了を待ちません。戻りが来るまでの間は別のタスクを行うことで、スループットを最適化していくという「非同期・ノンブッキング」の特徴を持っています。
また、メッセージに反応するかは受信側のコンポーネントの状況次第。処理する仕事がなければリソースはまったく消費しません。
ショッピングカートは状態を持っていますが、「アイテムの追加」等という仕事がなければ、CPUのリソースを食わないという「位置透過性」の特徴を持っています。
さらに、このまま構築したシステムを1つのノードにデプロイした場合、そのノードがクラッシュするとシステム全体が失われて、「リアクティブ原則:失敗を受け入れる」ことができていない状態となってしまいます。
この場合、複数のAvailability zone/リージョンにノードを分散することで、システム全体が同時にダウンする確率を下げたり、アプリケーションやサーバの負荷に応じてオートスケーリングをするなどの対応によって応答性が高い状態を維持することができます。
リアクティブ、メッセージ駆動についてはあまり説明されている本や日本語のコンテンツがなかったので、そもそも何?の部分を学びたく、まとめてみました。
ここまでを頭に入れた上で、今後は実際に何かを作りながら理解を深めていこうと思います。