Webアプリケーションの全体像を掴む

## プログラミングしかしらない。。。
私は会社で主にサポート対応を担当しています。不具合が見つかったりすると、その原因を特定し、修正をするといった仕事です。

ただ一概に不具合といっても、プログラミングのコードが生み出したバグが原因のときもあれば、Webサーバにアクセスが集中してパフォーマンスが低下することが原因のときもあります。

プログラミングに触れ始めてから2年が経過しましたが、私はプログラミングのことしか勉強してきませんでした。Webアプリケーションがどのように構成されているのか全く知らないがために、不具合の調査するときに原因を特定できないといったことを何度か経験しています。

このままだと効率力よく不具合調査を進められないことを危機に感じ、入門書として「プロになるためのWeb技術入門」という本を手に取りました。

## これは何の記事か？
プログラミングしか学んでこなかったエンジニアが「プロになるためのWeb技術入門」を通じて、Webアプリケーションの構成要素についてまとめた記事です。

**対象読者**

- プログラミングしか学んでこなかった
- Webアプリケーションの全体像について知りたい

## この記事のゴール
- Webアプリケーションの構成要素を把握すること

## なぜWebアプリケーションの構成を理解するべきなのか
Webアプリケーションを開発する立場の人は、Webアプリケーションを利用する人たちに期待通りのWebページを表示させなければなりません。

そのため、Webアプリケーションの規模によって、サーバサイドのどのノードにどの役割を担わせるかを考えなければなりません。

そうしないとWebサーバにアクセスが集中することでパフォーマンスが低下し、利用者に期待通りのWebページを提供できなくなったり、障害が起きたときにどこに原因があるのか特定が難しくなったりします。

そういった理由から、Webアプリケーションを運用していくには、Webアプリケーションの構成要素を理解しておくべきということです。

## Webアプリケーション構成の歴史
結論から言うと現代のWebアプリケーションのほとんどは、**Webサーバ**・**データベースサーバ**・**アプリケーションサーバ**の**三層構成**になっています。

ではなぜ**三層構成**になったのか。

これはWebアプリケーションの歴史的背景を知ることでより理解が深まります。以下ではWebアプリケーションの歴史をベースに、なぜ**三層構成**が基本的な構成になったのかを説明をします。

### Webサーバだけの構成だった時代
WWWが生まれた当初は、HTMLのみで記述された静的ページだけを表示するサイトがほとんどだったこともあり、多くのシステムはWebサーバだけの構成でした。

![1.png](https://qiita-image-store.s3.amazonaws.com/0/186009/87a973b5-5a1a-bac6-b237-34cd383e3126.png)

その後**CGI**（**Common Gateway Interface**）の発明により、Webページを動的に生成できるようになりました。しかし、この段階ではまだひとつのノード上でWebサーバとCGI経由で呼び出されるアプリケーションの2つのプロセスが動作している状態でした。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/186009/a920ed81-be85-607e-9c9c-86ac4852673a.png)

CGIを利用すると毎回Webサーバとは別のプロセスが同一ノード上で起動するため、効率が悪くなってしまいます。それを改善するために、Webサーバ内でプログラムを直接実行できるようにしました。

![3.png](https://qiita-image-store.s3.amazonaws.com/0/186009/2b9f38a9-96ad-c22f-ad95-9ec3ef16cc0d.png)


### データベースサーバの登場
アプリケーションが高度化してきたことで、利用者とのやりとりの情報を蓄積し、効率よく検索できるようなソフトウェアが必要になりました。（紙とボールペンだけで記録したり、記録した紙からデータを抽出することは人間の能力だけでは限界があるからです。）

例えば、ECサイトを運用するにあたり、どういった人はどういったものを購入するのか、そういったデータを蓄積して、それらを分析すれば、もっと利益をあげることだってできるわけです。

そういった背景から、大量の情報を蓄積することができる**データベース**が登場し、それの実現と取り扱いに特化した**データベース管理システム（DBMS:Database Menagement System）**も登場しました。

WebアプリケーションからDBライブラリを通じて、データベースにクエリを送ることで、データを記録したり、検索したりすることができます。

データベースサーバの登場により、Webアプリケーションの構成が以下のように変化しました。

![4.png](https://qiita-image-store.s3.amazonaws.com/0/186009/b24f661a-dd41-360a-8c09-e13e9edff6a1.png)

データベースサーバを別ノードで稼働させるようにすることで、情報の記録や検索処理を分離しています。これにより、データベースが大きくなって、情報の記録や検索処理を実行しても、WebサーバのCPUに負荷をかけないような構成になっています。


### アプリケーションサーバの登場
CGI経由で動的コンテンツを生成すると、Webサーバへリクエストが届くたびにプロセスが起動するため、時間がかかるといった性能面の問題と、当時使用されていた`Perl`は現状の制約から大規模システムの開発に向かないという問題がありました。

それらの問題を解決するひとつの方法として広まったのが、`Java`でした。では、`Java`プログラムがWebアプリケーションの中でどのように実行されているかを説明します。

※ Webサーバが`Apache`で、APサーバが`Tomcat`が使われているWebアプリケーションを例としています。

![5.png](https://qiita-image-store.s3.amazonaws.com/0/186009/7bb864f8-802e-b813-bff0-edc08fbeffb9.png)


`Java`プログラムは、Webサーバのノード上に存在する`JavaVM`と呼ばれる仮想的なコンピュータが実行をしています。（Webサーバとは別プロセスで実行されています）

`JavaVM`上では**アプリケーションサーバ（Application Server）**と呼ばれるソフトウェアが常駐しており、それが`Java`プログラムを実行するという構造になっています。

Webサーバとアプリケーションサーバはどのように連携しているかというと、特に標準的な方法が決まっているわけではありません。ここでは`Apache`と`Tomcat`の組み合わせを例に説明がされています。

Webサーバとアプリケーションサーバは異なるプロセスであるため、連携するには何らかの通信を行う必要があります。それを実現する方法として一般的なのは、アプリケーションサーバ側によって作成された連携用モジュールをWebサーバに組み込むという方法です。

今回の例では、`Tomcat`が`Apache`向けに提供している`mod_jk`と呼ばれるモジュールを`Apache`に組み込むことで連携を実現しています。

こうすることで、HTTPリクエストをWebサーバが窓口となって受け取り、動的処理が必要な場合はアプリケーションサーバに処理をお願いするといった役割分担がなされます。

またデータベースサーバのように、アプリケーションサーバを別ノードで動かすことも可能です。

![6.png](https://qiita-image-store.s3.amazonaws.com/0/186009/9654e297-7ffc-7064-f76b-e91537b94441.png)

## 一般的なWebアプリケーションの構成
Webアプリケーションの構成にはいろいろなパターンがありますが、その中でも一般的な構成が、**Webサーバ**と**アプリケーションサーバ**と**データベースサーバ**をそれぞれ別のノード上に配置する構成です。

![7.png](https://qiita-image-store.s3.amazonaws.com/0/186009/d9f5fb6d-1b6f-26d8-4c80-e4ee88f7a54c.png)

こうすることで、それぞれのコンピュータのもつリソースを各サーバの役割へ最大限振り分けることができます。

## まとめ
Webアプリケーションは**Webサーバ**と**データベースサーバ**と**アプリケーションサーバ**の**三層構成**になっている。

- Webサーバ
    - HTTPリクエストの一次窓口
    - 静的ページがリクエストされたときはそのままHTTPレスポンスを返す
    - 動的処理が必要なページがリクエストされたときは、アプリケーションに処理を依頼し、生成されたHTMLをHTTPレスポンスとして返す
- データベースサーバ
    - 利用者とのやりとりで必要な情報をデータとして記録する
    - データベースから特定のデータを検索・抽出する
    - アプリケーションから送られるクエリによって上記の操作ができる
- アプリケーションサーバ
    - Webサーバから動的処理を依頼されるサーバ
    - データベースサーバとクエリを通じてやりとりを行うサーバ

## 参考にした本

[「プロになるためのWeb技術入門」 ――なぜ、あなたはWebシステムを開発できないのか ](https://www.amazon.co.jp/%E3%80%8C%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AEWeb%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80%E3%80%8D-%E2%80%95%E2%80%95%E3%81%AA%E3%81%9C%E3%80%81%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AFWeb%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E9%96%8B%E7%99%BA%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E3%81%AE%E3%81%8B-%E5%B0%8F%E6%A3%AE-%E8%A3%95%E4%BB%8B/dp/4774142352)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/186009/71ae1978-55bb-0634-cf14-5400ccb2be23.png)


## 所感
今までプログラミングしか学んでこなかったので、Webアプリケーションがどのように構成されているか全くわかっていませんでした。これがわかっていないと、何か障害が起きた時にどこに原因があるか調査する時に、アプリケーションサーバ以外のWebサーバやデータベースサーバが候補にすら上がらないことになると実感しました。

またアプリケーションサーバの負担が多くなってきたら、HTTPリクエストに含まれるURLのよって、動的処理を任せるアプリケーションサーバを分ける方法もあることを知り、Webアプリケーションのインフラ周りの楽しさが垣間見えた気がします。

これをきっかけにAWSなどについても学びを広げていきたいと思います。