051.2 レッスン 1
Certificate: |
Open Source Essentials |
---|---|
Version: |
1.0 |
Topic: |
051 ソフトウェア開発基礎 |
Objective: |
051.2 ソフトウェアアーキテクチャ |
Lesson: |
1 of 1 |
はじめに
現代では、あらゆる場所でインターネットにアクセスして、Webアプリケーションやモバイルアプリケーションを利用できます。世界中の人々がシームレスに利用し、個人的なチャットから大企業の採掘設備の購入といった複雑な活動まで、あらゆる活動を支えています。
こうした一見すると単純なインターフェイスとオンラインサービスの背後には、ソフトウェアを巧妙に組み合わせた アーキテクチャ が存在します。インターネットの各部が協働し、ソフトウェアが価値ある機能を実現する仕組みを理解するには、このアーキテクチャについて少し知っておく必要があります。
このレッスンでは、サーバー上で動作するWebアプリケーションが採用しているアーキテクチャを概観します。
サーバーとクライアント
オンラインシステムを使っていると、処理中のサンプル画面のような「処理中」というメッセージを目にすることがあります。
この画面を目にする少し前に時間を巻き戻してみましょう。銀行のWebサイトから銀行口座にアクセスしようとしていました。ノートパソコンで銀行のWebサイトにアクセスするときには、Google ChromeやFirefoxといったWebブラウザと呼ばれるソフトウェア(アプリケーション)を使います。そのノートパソコンのブラウザが、Webサイトをホストしている別のコンピュータにリクエストを送ります。Webサイトをホストしているコンピュータを サーバー と呼びます。サーバーは、24時間365日稼働するよう設計されており、絶えず世界中から送られるリクエストに対応します。
サーバーは、仕事やゲームやプログラミング演習に使うコンピュータと同じようなコンピュータなのですが、一つ大きな違いがあります。サーバーは、通常、そこで稼働させている特定のソフトウェア(アプリケーション)にリソースを集中させます。先ほどの例では、サーバーで稼働しているのはWebアプリケーションと呼ばれるソフトウェア(後述)であり、それにリソースを集中させます。
「処理中のサンプル画面」では、サーバーがブラウザからのリクエストを受け取り、サーバーで稼働しているアプリケーションが処理を行っています。銀行顧客の詳細情報をデータベースに問い合わせたり、次の借入れに適用できる優遇措置を確認するために別のサーバーと通信したりする処理です。
この例では、ノートパソコンで動いているブラウザを クライアント(クライアントアプリケーション) と呼びます。クライアントはリモートサーバーとやり取りします。
クライアントとサーバーとの間の通信は、企業ネットワーク内で完結するかもしれませんし、インターネットを経由するかもしれません。クライアント/サーバー間通信の一般的な特徴として、一つのサーバーが多数のクライアントと同時に通信するということが挙げられます。先の例で言うと、銀行のWebサイトをホストする1台のサーバーが、各地のユーザーが自分の銀行口座にアクセスする数千ものリクエストを同時にさばくということです。
上記の銀行の例では、ほぼすべての処理をサーバーが行っていますが、クライアントが主に処理を行うケースもあります。クライアント自体が大部分の処理を行うアプローチを、ファットクライアント(fat client) あるいは シッククライアント(thick client) と呼びます。先ほどの銀行の例のように、クライアント(ブラウザ)からのリクエストをサーバーが処理し、結果をブラウザが表示するアプローチを、シンクライアント(thin client) と呼びます。
ビデオゲームはファットクライアントの代表例です。ローカルマシンが、自らのCPU、RAM、GPU、ストレージを利用し、大部分のデータ処理を行います。特にオフラインでゲームをプレイするときは、外部のサーバーに頼るということはありません。
どちらのアプローチにも長所と短所があります。シッククライアントは、リモートサーバーに頼るシンクライアントと比べると、ネットワークが不安定でも問題になることが少ないですが、ソフトウェアに更新を適用するのが難しく、より多くのコンピュータリソースを必要とします。シンクライアントには、リソースをあまり必要とせず低コストですむ利点があります。
Webアプリケーション
Webアプリケーション とは、サーバーで動作し、ネットワークを通じてアクセスしたユーザーと対話しながら処理を進めるソフトウェアです。ファットクライアントのこともあればシンクライアントのこともあります。すべてのWebサイトがWebアプリケーションであるとは限りません。ユーザーと対話しながら処理を進めることがない静的なWebページは、Webアプリケーションではありません。サーバーは、要求に応答する処理を行うアプリケーションプログラムを実行していないからです。
Webアプリケーションは大きく2つに分けられます。SPA(Single Page Application / シングルページアプリケーション) と MPA(Multi-Page Application / マルチページアプリケーション) です。SPAは、Webページが一つしかなく、再読込やリダイレクトなしにデータをやり取りして新しい内容を読み込みます。MPAは、Webページが複数あり、データのやり取りには再読込やリダイレクトを伴います。
銀行のサイトにアクセスして自分の口座の取引履歴を確認するという、先ほどの例で考えてみましょう。銀行のサイトが読み込まれたところから話を始めます。この銀行のサイト(Webアプリケーション)がSPAであれば、取引履歴が再読込やリダイレクトなしに表示されます。自分の借入状況を確認するとしても、新しいページにリダイレクトされるのではなく、同じページの一部に新しい情報が表示されます。リダイレクトがないので動線がスムーズです。
MPAであれば、自分の借入状況を確認するときに、別のページにリダイレクトされます。
SPAの代表例はGmail(Google Mail)です。例えば、迷惑メールフォルダを表示しようとしたら、新しいページにリダイレクトされるのではなく、同じページにとどまったまま、表示の一部が更新されて迷惑メールフォルダが表示されます。
MPAの代表例は、Eコマースの大手であるAmazon.comです。各商品が別々のページに表示されます。
MPAがSPAに勝っている点は、アクセスを集計して分析しやすいという点です。サイト管理者が検索エンジンの結果を最適化するためには、この点が決定的に重要です。
通常、Webアプリケーションは、フロントエンド と バックエンド に分けられます。フロントエンドはブラウザへの表示をつかさどる部分で、見た目とユーザーによる操作(クリック、選択、キー入力など)を担当します。
Webアプリケーションの大部分は、一般的にバックエンドが担当します。ビジネスロジックを実装し、ユーザーの要求に応じた処理を行い、データを加工して保存します。データの保存には、サーバーに接続したデータベース管理システムを用いるのが普通です。
フロントエンドとバックエンドは相互にやり取りします。リクエストはフロントエンドからバックエンドへと送られ、バックエンドが生成して返したレスポンスはフロントエンドで整形されてユーザーに表示されます。
銀行口座の取引履歴を取得するという例を見ていきましょう。ブラウザで実行されるフロントエンドが、ユーザーのアクションを解釈します。次に、インターネットを通じてリクエストがアプリケーションのバックエンドへと送られ、バックエンドではユーザーがそのアクション(この例では取引履歴の取得)を実行可能かどうか検証します。実行可能であれば、取引履歴をブラウザのフロントエンドに返し、ブラウザがその取引履歴を整形してユーザーに表示します。
アプリケーションプログラミングインターフェイス(API)
およそどのようなソフトウェアも、内部的ないし外部的に別のコンポーネントやプログラムと通信を行います。Webアプリケーションで、クライアントはどのように通信するのでしょうか。フロントエンドはどのようにデータをバックエンドに送るのでしょうか。
ソフトウェア(アプリケーション)は、基本的なインターネットプロトコルを利用して動作する API(Application Programming Interface / アプリケーションプログラミングインターフェイス) を通じて相互にやり取りします。プロトコルとは、複数のアプリケーションが命令やデータをやり取りできるように定められた規格や規則のことです。
APIを用いると、アプリケーションを機能ごとに分離して、それらを協働させてデータを処理できるという大きな利点があります。すべての人が行き来する際に通らなければならない門のように、データの流れを事前に定められた経路に集約するという利点もあります。Webアプリケーションが機能するためには、APIが非常に重要です。ユーザーとやり取りして、情報を加工して配信し、データを保存する、といった諸々の動作はAPIを通じて行われます。サーバーがそうしたAPIを用意して、クライアントはAPIを通してサーバーにリクエストを送ります。
先ほどの銀行の例に戻りましょう。Webアプリケーションでログインするために、ユーザー名とパスワードを入力して「ログイン」ボタンを押します。ブラウザはこの情報を取得し、バックエンドのAPIを呼び出します。リモートサーバーで動いているWebアプリケーションがそのデータを受け取り、ユーザーの検証を行い、ユーザーがアクセス可能かどうかを確かめ、最終的にレスポンスをブラウザに返します。ユーザーがサーバーとやり取りするには、クライアントとサーバーがデータを送り合います。これを可能にするのがAPIです。
この銀行のWebアプリケーションでは、必要最小限のデータしかやり取りせず、他の機密情報は含まないことに着目してください。
APIによる通信にはさまざまなプロトコルを使えますが、ほとんどの場合は HTTP(HyperText Transfer Protocol / ハイパーテキスト・トランスファー・プロトコル) を使います。ハイパーテキスト とは、ほかのテキストやページへのリンクを含むテキストのことで、Webページを記述するHTMLの基礎となる概念です。
HTTPは非常にシンプルなプロトコルで、所定の書式でクライアントがサーバーに1つのリクエストを送り、サーバーは1つのレスポンスを同じ通信チャンネル経由でクライアントに返送します。1回のやり取りは、クライアントとサーバーの間を1往復して終わることがポイントです。
構造化されたWebアプリケーションでは、ソフトウェアエンジニアが部品(モジュールやコンポーネント)を組み合わせてアプリケーションを構築します。そうすることによって、部品それぞれのタスク(機能)と責任が明確になり、開発と保守が容易になります。
2つのモジュールから構築されたアプリケーションの例を考えてみましょう。1つのモジュールが自社のビジネスロジックを実装し、もう1つのモジュールが外部のサービスとのやり取りを制御しているとします。ここで利用している外部のサービスは、APIを通じて提供される天気予報だとしましょう。この外部のサーバーがダウンし、天気予報を取得できなくなりました。天気予報のデータが自社のサービスに欠かせないとしたら、自社のユーザーを困惑させてしまいかねません。
そこで、このダウンした天気予報サービスから、同じ天気予報APIを提供している別のサービスに切り替えます。モジュールが分離していますから、1つのモジュールを更新するだけですみます。もう1つのモジュールの自社のビジネスロジックには手を加える必要はないでしょうし、手を加える必要があるとしても最小限の変更ですみます。
タスク(機能)と責任を明確にするモジュール構造は、使いやすいAPIの設計にも影響を与えます。データのやり取りを行うアプリケーションの設計ガイドラインである REST(REpresentational State Transfer) という概念が、使いやすいAPIのアーキテクチャとして広く受け入れられています。
RESTには6つの原則がありますが、このレッスンではそのうちで重要な3つの原則を取り上げます。
- クライアントとサーバーの分離
-
クライアント側ではバックエンドのURIだけを把握し、そのURIを通じてサーバーとやり取りします。この原則に従うと柔軟性を担保できます。例えば、バックエンドでリファクタリングを行ったりデータベースに大きな変更を加えたりしても、フロントエンドではそれに伴う更新の必要はありません。同じURIに同じHTTPリクエストを送り続けるだけです。
- ステートレス(状態を保持しない)
-
リクエストは過去のリクエストから独立しています。この原則は、REST原則を採用するアプリケーションが用いるHTTPプロトコルの性質と密接に関連しています。HTTPでは、1つ1つのリクエストは独立しているので、それぞれのリクエストにすべての必要な情報を含めなければなりません。例えば、この原則に従うWebアプリケーションでは、クライアントがログインしているかどうかという状態(ステート)を保持しません。そのため、クライアントは、HTTPリクエストのたびに認証トークンを送ることで正当なユーザーであることを示す必要があります。サーバーでは、送られてきたトークンに基づいて、そのリクエストを拒否するか処理するかを判断します。
スケールのしやすさがこの原則の大きな利点です。サーバーは、ユーザーがログインして認証済みであるといった過去の振る舞いに基づく状態を記憶しておく必要がないので、多数のリクエストを平行して処理できます。
- 階層化(レイヤー構造)
-
アプリケーションを複数のレイヤーで構成し、レイヤーごとにセキュリティやデータ取得など固有のロジックを実装します。クライアントからは、レイヤー数や、どのレイヤーとやり取りしているのかを意識する必要はありません。
REST原則に従うAPIは RESTful (レストフル)であると言われます。現代のWebアプリケーションの多くはREST原則に従っています。RESTfulなAPIがHTTPを用いることは必須ではありませんが、シンプルかつ堅牢で、Web環境では普遍的に利用できるため、主にHTTPが使用されています。
アーキテクチャタイプ
Webアプリケーションの構造を体系化しようとするアーキテクチャやモデルが乱立しており、それぞれのアーキテクチャやモデルの長所と短所が議論されています。従来の モノシリックアーキテクチャ に対置される、マイクロサービスアーキテクチャ は重要なパラダイムです。
独立した複数の相互に依存する サービス を組み合わせて最終的なアプリケーションを組み立てるソフトウェアモデルを、マイクロサービスアーキテクチャと呼びます。このアーキテクチャでは、プログラムコードを単機能化した小さなソフトウェアコンポーネントに分権化することを目指します。すなわち、ソフトウェアのレイヤーを整理して、それぞれのレイヤーを複数の小さなアプリケーションに分割することで、維持管理を行いやすくします。(マイクロサービスアーキテクチャの概念図)
マイクロサービスアーキテクチャと対照をなすモノリシックアーキテクチャでは、最終的なアプリケーションに必要なサービスやリソースを、すべて一つのアプリケーションに閉じ込めます。(モノリシックアーキテクチャの概念図)
「マイクロサービスアーキテクチャの概念図」が示すように、マイクロサービスモデルではサービス(機能)ごとにソフトウェアコンポーネントが分権化されており、アプリケーションは複数のサービスを組み合わせて利用します。それぞれのサービスが、独自のソフトウェアコンポーネント、データベース、サーバーのリソースなどを管理します。「マイクロ」という名前からわかるように、それぞれのマイクロサービスは、すべてのサービスを一箇所で扱うモノリシックアーキテクチャよりもかなり小さくなります。
モノリシックアプリケーションでは、すべてのリソースを一箇所にまとめます。ビジネスロジック、データ、プログラムコードをすべて集権化して一つの大きな塊を作るので、モノリシック(一枚岩)と呼ばれます。
Webアプリケーションがモノリシックモデルなのかマイクロサービスモデルなのか、ユーザーからはほとんどわかりません。先ほどから例に挙げている銀行のWebアプリケーションを、支払い、取引、借入れなどすべてのビジネスロジックを一つのプログラムで扱うモノリシックモデルで作ることもできれば、マイクロサービスモデルで作ることもできます。マイクロサービスモデルでは、支払いサービスや借入れサービス、さらには債務不履行の可能性を分析するサービスなどがあるかもしれません。銀行のWebアプリケーションでしたら、数千のサービスが存在してもおかしくありません。
モノリシックなアプローチでは、特に複数のチームが同じコードに対して作業を行う場合には、アプリケーションが大きくなるにつれて、維持管理の負荷が大きくなります。集権化されたソフトウェアでは、あるチームの変更が別のチームの担当箇所に影響を及ぼすことがよくあります。大規模なチームでは、これが本当に悩ましい問題です。
マイクロサービスでは一つのサービスを一つのチームが管理しますから、その点ではるかに柔軟です。コードの変更を簡単に行うことができ、競合が問題になることは本質的にありません。一つのチームが複数のサービスを管理しても差し支えありません。マイクロサービスにも短所はあります。各サービスが相互に結びついていますから、どこか一つのサービスで障害が発生すると、それがアプリケーション全体に波及する可能性があります。データベースインスタンス、サーバー、相互に通信する外部APIが複数存在するため、アプリケーション全体の耐障害性(レジリエンス)は、最も弱いサービスが決定づけることになります。
モノリシックなアプローチでは、データベースも集権化されているので、データの重複が発生しにくいという利点があります。また、多数の小さなサーバーを用意するよりも一つの大きなサーバーを用意するほうが必要なリソースが少なくてすむので、リソースの消費を抑えられるという長所もあります。同じくらいの規模のアプリケーションであれば、マイクロサービスのほうがリソースの負担は大きくなります。
演習
-
ファットクライアントとシンクライアントの主な違いは何ですか?
-
すべてのWebサイトがWebアプリケーションだと考えるのは正しいですか?
-
RESTモデルとは何ですか?
-
現代的な大規模Webアプリケーションを複数のチームで開発する際に好ましいアーキテクチャはどのようなものか、理由とともに説明してください。
-
Webアプリケーションでデータをやり取りするために、最もよく使われるプロトコルは何ですか?
-
SPAと比べてMPAにはどのような欠点があるか、2つ挙げてください。
-
モノリシックアーキテクチャとマイクロサービスアーキテクチャを比較して、それぞれの長所を一つずつ挙げてください。
発展演習
-
2021年にNASAの探査機が火星に着陸しました。火星に生命が存在したかどうかを確かめることがその目的の一つでした。探査機は遠く離れた地球上のアプリケーションから制御することもできましたが、ほとんどの状況では自律的に制御できるようになっていました。なぜこの探査機を自律制御が可能なファットクライアントとして設計したのでしょうか?
-
外部のサーバーに接続してデータをやり取りする自動走行の自家用車があるとします。これはファットクライアントであるべきでしょうか、それともシンクライアントであるべきでしょうか?
まとめ
このレッスンでは、Webアプリケーションのソフトウェアアーキテクチャの基本概念を説明しました。一般的なWebアプリケーションを体系的に説明し、モノリシックアーキテクチャとマイクロサービスアーキテクチャの違い、サーバー/クライアントという概念、Webアプリケーションでのクライアント/サーバー間通信の基本に触れました。
演習の解答
-
ファットクライアントとシンクライアントの主な違いは何ですか?
ファットクライアントは、リモートサーバーと常時接続して情報をやり取りする必要がありません。シンクライアントは、情報が外部のサーバーで処理されることを前提にしています。別の観点から違いを述べると、ファットクライアントは、大部分の処理を自ら担当するので、シンクライアントよりもコンピューティングリソースを多く必要とします。
-
すべてのWebサイトがWebアプリケーションだと考えるのは正しいですか?
正しくありません。WebアプリケーションではないWebサイトが存在します。Webアプリケーションは、入力されたデータに応じた処理を行うなど、ユーザーと対話しながら処理を進めます。例えば、バナー広告のようにイベントを告知する単純なWebサイトは、Webアプリケーションではありません。こうした静的なWebサイトは管理しやすいですし、コンピューティングリソースをごくわずかしか使いません。Webアプリケーションは、ユーザー認証やデータの保存などの機能を備えていることが多く、たくさんのコンピューティングリソースを使うので、より強力なサーバーに配備(デプロイ)するのが一般的です。
-
RESTモデルとは何ですか?
RESTモデルとは、扱いやすく、明確で、保守しやすいWebアプリケーションを開発するためのガイドラインを提供するソフトウェアアーキテクチャモデルです。開発ガイドラインの中には、APIが特定のコンポーネントに依存することを回避するために、機能ごとに 階層化 するアーキテクチャも含まれています。
-
現代的な大規模Webアプリケーションを複数のチームで開発する際に好ましいアーキテクチャはどのようなものか、理由とともに説明してください。
マイクロサービスアーキテクチャが好ましいです。マイクロサービスアーキテクチャは、大規模なWebアプリケーションを複数のチームが平行して保守するといった、チームの協働をサポートする柔軟なフレームワークだからです。サービスごとにきちんと分権化しておけば、自分たちの担当箇所を変更しても、ほかのチームの担当箇所に影響を及ぼすことはありません。
-
Webアプリケーションでデータをやり取りするために、最もよく使われるプロトコルは何ですか?
サーバーとクライアントとの間でデータや命令をやり取りするためには、HTTPプロトコルが最もよく使われます。
-
SPAと比べてMPAにはどのような欠点があるか、2つ挙げてください。
MPAでは、ユーザーが何らかのアクションを実行したときに、変更箇所だけでなくWebページの要素全体を再読込しなければなりません。そのため、パフォーマンスに劣るという欠点があります。ページの読み込みがユーザー体験を損ねるという欠点もあります。SPAで視覚効果をうまく活用すればスムーズなユーザー体験を提供できます。
-
モノリシックアーキテクチャとマイクロサービスアーキテクチャを比較して、それぞれの長所を一つずつ挙げてください。
モノリシックアーキテクチャでは、データがあちこちに分散しておらず一箇所に集約されているので、データを管理しやすいという長所があります。マイクロサービスアーキテクチャでは、コードの開発と保守がしやすいという長所があります。ほかのチームの邪魔をせずに複数のチームが同時に作業できます。
発展演習の解答
-
2021年にNASAの探査機が火星に着陸しました。火星に生命が存在したかどうかを確かめることがその目的の一つでした。探査機は遠く離れた地球上のアプリケーションから制御することもできましたが、ほとんどの状況では自律的に制御できるようになっていました。なぜこの探査機を自律制御が可能なファットクライアントとして設計したのでしょうか?
地球と火星の位置関係によって違いがあるにせよ、通信信号を地球から送って火星で受信するのにかかる時間は20分にも及びます。よって、動いている探査機に命令を送って制御することは不可能です。予想外の状況が発生しうることを考慮するとなおさらです。探査機がほとんどの状況下で自律制御できるのが理想です。人工知能(AI)の機械学習訓練により自律制御が可能になり、探査機は地球からの手動制御から独立できました。ほとんどの状況で自律制御して遠くからの信号にできるだけ頼らないようにするために、探査機は多くのリソースを搭載し、自ら大部分の計算を行いました。これはまさにファットクライアントです。
-
外部のサーバーに接続してデータをやり取りする自動走行の自家用車があるとします。これはファットクライアントであるべきでしょうか、それともシンクライアントであるべきでしょうか?
データ処理の多くを外部の信頼できるサーバーに委ねる可能性を考えることはできますが、命に関わるようなデータ処理が必要ですから、そうしてしまうとオフライン時に危険です。よって、自動車は大部分の処理を自前で行わなければなりません。つまり、冗長性を確保したファットクライアントであるべきです。