私はWeb開発とソフトウェアアーキテクチャにずっと興味を持っていました。なぜなら、実際に動作するシステムのマクロ的な視点を見るのが好きだからです。モバイルアプリケーションであれWebアプリケーションであれ、構築するアプリケーションはインターネットに接続し、異なるモジュール間でデータを交換する必要があります。つまり、Webサービスが必要なのです。 アプリケーションのバックエンドとしてクラウドシステムを選択すると、バックエンドサービスが水平方向と垂直方向にスケーリングし、さまざまなサービスをオーケストレーションできるため、より強力なコンピューティング能力を活用できます。ただし、クラウドバックエンドを使用するかどうかにかかわらず、柔軟で安定性、高速性、そして安全なフォールトトレラントシステムの構築が不可欠です。 フォールトトレラントシステムを理解するために、Facebook、Amazon、Google、Netflixを例に挙げてみましょう。数億人ものユーザーがこれらのプラットフォームに同時にアクセスし、ピアツーピアおよびユーザーサーバーネットワークを介して膨大な量のデータを送信しています。これらのユーザーの多くは、ハッキングやサービス拒否(DoS)攻撃を行うなど、悪意のあるユーザーであることは間違いありません。それでも、これらのプラットフォームはダウンタイムなしで24時間365日稼働しています。 これらのシステムの基盤は機械学習とインテリジェントなアルゴリズムですが、1分たりともダウンタイムを発生させることなく継続的にサービスを提供できる能力は称賛に値します。高価なハードウェアと大規模なデータセンターは確かに重要ですが、サービスを支える洗練されたソフトウェア設計も同様に重要です。さらに、フォールトトレランスは、このような高度なシステムを構築するための基本原則の一つです。 製造工程でエラーを引き起こす2つの行動これはフォールトトレラントシステムについての別の考え方です。アプリケーションサービスをローカルで実行しているときは、すべてが完璧に見えます。素晴らしい!しかし、サービスを本番環境にスケールアップすると、すべてがうまくいかなくなります。このような状況では、フォールトトレラントシステムは、障害停止動作とビザンチン動作という2つの問題に対処することで役立ちます。 障害停止動作システムクラッシュは、システムが突然停止したり、システムの一部に不具合が生じたりした場合に発生します。サーバーのダウンタイムとデータベースへのアクセス不能はどちらもこのカテゴリに該当します。例えば、下の図では、サービス2にアクセスできないため、サービス1はサービス2と通信できません。 サービス2: ダウンタイムによる停止動作 ただし、次の図に示すように、サービス間にネットワークの問題がある場合にも、この問題が発生する可能性があります。 ネットワーク障害による動作停止 ビザンチンの行動ビザンチン動作とは、実行は継続されるものの、期待される動作 (不正確または無効なデータなど) が生成されないシステムを指します。 次の例のように、サービス 2 のデータ (値) が破損している場合、サービスが正常に実行されているように見えても、ビザンチン障害が発生する可能性があります。 サービス欠陥によるビザンチン障害 あるいは、悪意のある中間者攻撃が発生し、サービス間のデータを傍受して不要なデータを挿入する可能性もあります。 悪意のある仲介者によるビザンチン障害 フォールトトレラントなシャットダウンもビザンチン挙動も理想的ではないため、これらを防止または修正する方法が必要です。ここでフォールトトレラントシステムが役立ちます。これらの問題を解決するのに役立つ8つのオープンソースツールをご紹介します。 フォールトトレラントシステムを構築するためのツール本当に実用的なフォールト トレラント システムを構築するには、詳細な「分散コンピューティング理論」と複雑なコンピュータ サイエンスの原理が必要になりますが、フォールト トレラント システムを構築することで悪影響を軽減するソフトウェア ツール (その多くはオープン ソース) が数多くあります。 切断モード: Hystrix と Resilience4jサーキット ブレーキング モードは、サービスに障害が発生したときに、準備された仮想応答または単純な応答を返すのに役立つ手法です。 切断モード Netflix のオープンソース Hystrix は、回路遮断モードの最も人気のあるアプリケーションです。 私がこれまで勤務した多くの企業で、この優れたツールが使われてきました。驚いたことに、NetflixはHystrixのアップデートを停止すると発表しました(ええ、知っていました)。代わりに、Java 8と関数型プログラミングをサポートするResilence4jや、Adaptive Concurrency Limitに似たものといった代替ソリューションを提案しました。 負荷分散: Nginx と HaProxy負荷分散は分散システムにおける最も基本的な概念の一つです。本番環境品質の環境には負荷分散が不可欠です。ロードバランサーを理解するには、まず冗長性の概念を理解する必要があります。本番環境レベルのWebサービスはすべて、1台のサーバーに障害が発生した場合に引き継いでサービスを維持するための冗長性を提供する複数のサーバーで構成されています。 負荷分散 現代の航空機を考えてみましょう。デュアルエンジンは冗長性を提供し、片方のエンジンが火災を起こしても安全に着陸できます。(これは、ほとんどの民間航空機が最先端の自動化システムを備えていることにも役立っています。)しかし、複数のエンジン(または複数のサーバー)を備えているということは、障害発生時にシステムを効果的にルーティングするための何らかのスケジューリングメカニズムが必要であることも意味します。 ロードバランサーとは、複数のサービスノードのバランスをとることで、大量のトランザクションを最適化するデバイスまたはソフトウェアです。例えば、数千ものリクエストが到着した場合、ロードバランサーはミドルウェア層として機能し、トラフィックを複数のサーバーにルーティングして均等に分散します。1台のサーバーがダウンした場合、ロードバランサーはリクエストを他の稼働中のサーバーに転送します。 利用できるロードバランサーは多数ありますが、最もよく知られているのは Nginx と HaProxy の 2 つです。 Nginxは単なるロードバランサーではありません。HTTPおよびリバースプロキシサーバー、メールプロキシサーバー、そして汎用TCP/UDPプロキシサーバーとしても機能します。Groupon、Capital One、Adobe、NASAなどの企業で使用されています。 HaProxyは、TCPおよびHTTPベースのアプリケーションに高可用性、負荷分散、プロキシ機能を提供する、無料かつ高速で信頼性の高いソリューションであることも人気の理由です。GitHub、Reddit、Twitter、Stack Overflowなど、多くの大手ネットワーク企業がHaProxyを使用しています。Red Hat Enterprise LinuxもHaProxyをサポートしています。 参加者モデル: Akka参加者モデルは、計算の基本単位である「参加者」がメッセージを受信したときに責任を割り当てる並行設計パターンです。参加者は、複数の参加者を作成し、それらの参加者にメッセージを委任することができます。 Akkaは、参加者モデルの最もよく知られた実装の一つです。このフレームワークは、JVMベースのJavaとScalaの両方をサポートしています。 メッセージキューを使用した非同期非ブロッキングI/O: KafkaとRabbitMQマルチスレッド開発はかつては一般的でしたが、現在では非推奨となり、非同期かつ非ブロッキングなI/Oモデルに置き換えられています。Javaの場合、これはEnterprise JavaBean (EJB)仕様で明確に規定されています。
現在、ストリーミングAPIや参加者モデルといった他のアプローチも存在しますが、KafkaやRabbitMQといったメッセージキューは、非同期およびノンブロッキングI/O機能をすぐに利用できるサポートを提供しています。これらは、並行プロセスを処理することでスレッドを置き換えることができる強力なオープンソースツールでもあります。 その他の選択肢: EurekaとChaos Monkeyフォールトトレラントシステムに役立つツールとしては、NetflixのEurekaのような監視ツールや、Chaos Monkeyのようなストレステストツールなどがあります。これらのツールは、統合(INT)、品質保証(QA)、ユーザー受け入れテスト(UAT)といった下位レベルの環境でテストを実施することで、潜在的な問題を早期に特定し、本番環境に導入される前に潜在的な問題の発生を防ぐように設計されています。 |