🔩 ねじき教室 Go と Web の教室

Web サービスの全体像

読了目安 約3分

リバースプロキシ、アプリケーションサーバー、データベースという 3 つの部品の役割と、リクエストが通る経路を押さえる。

この章の目次

実際の Web サービスのサーバー側は、1 つのプログラムではなく、役割の違う複数の部品の連携でできています。 ISUCON で渡されるサーバーも同じ作りです。

3 つの部品

典型的な構成では、リクエストは次の 3 つの部品を順に通ります。

テキスト
ブラウザ
   |
   | HTTP リクエスト
   v
+------------------+      +---------------------+      +----------------+
| リバースプロキシ |----->| アプリケーション    |----->| データベース   |
| (nginx)        |      | サーバー(Go)      | SQL  | (MySQL)      |
|                  |<-----|                     |<-----|                |
+------------------+      +---------------------+      +----------------+
 入口で受けて           ロジックを実行して        データを保管し
 振り分ける             レスポンスを組み立てる    検索する
  • リバースプロキシ:すべてのリクエストを最初に受け取る入口です。画像や CSS のような固定のファイルは自分で返し、それ以外をアプリケーションサーバーへ転送します。nginx(エンジンエックス)というソフトウェアが代表です。
  • アプリケーションサーバー:サービスのロジック本体です。前章までの言葉で言えば、リクエストの内容を見て、レスポンス(HTML や JSON)を組み立てて返すプログラムです。この先の Part で Go で書いていくのは、この部品です。
  • データベース:データの保管と検索を専門に引き受けるプログラムです。アプリケーションサーバーは、SQL という言語で「この条件のデータをください」と問い合わせます。MySQL というソフトウェアが代表です。

なぜデータの保管をアプリの中で済ませず、別の部品に預けるのかは、Part 4 の最初の章(/sql/01-why-db/)で扱います。

リクエストが通る経路

掲示板サービスで投稿一覧のページを開く場面を例に、経路を追ってみます。

  1. ブラウザが GET /posts というリクエストを送ります。
  2. リバースプロキシが受け取ります。固定ファイルへのリクエストではないので、アプリケーションサーバーへ転送します。
  3. アプリケーションサーバーは、パス /posts に対応する処理を実行します。その中で、データベースへ「投稿を新しい順にください」という意味の SQL を送ります。
  4. データベースが該当するデータの行を返します。
  5. アプリケーションサーバーは、受け取った行を HTML(API なら JSON)に組み立て、レスポンスとして返します。
  6. リバースプロキシがそれをブラウザへ返し、ブラウザが描画します。

行きは図の左から右へ、答えは右から左へ、同じ経路を戻ります。

アプリケーションサーバーとデータベースの間のやり取り(SQL とその結果)は HTTP ではなく、それぞれのデータベース専用の方式で行われます。

この教室で書くのはどこか

3 つの部品のうち、自分の手で書くのは、真ん中のアプリケーションサーバーと、そこからデータベースへ送る SQL です。 スコアを左右する改善の多く(N+1 問題の解消、インデックスの追加など)も、この 2 つの領域にあります。

時間はどこで消えるか

リクエスト 1 つにかかる時間は、各部品での処理時間と、部品の間の通信にかかる時間の合計です。 したがってサービスが遅いとき、犯人はどの部品でもありえます。

どの部品で時間を食っているかは、見た目からは判断できないので、測って探すことになります。 この「測って探す」が Part 6 の主題で、章の名前もそのまま「推測するな、計測せよ」です(/isucon/02-measure/)。 ISUCON ではデータベースが最大のボトルネックになっていることが多いとよく言われ、Part 4 で SQL を学ぶのはそのためでもあります。

Part 3 へ

次の目標は、この図の真ん中にいるアプリケーションサーバーを自分で書くことです。 道具の Go は Part 1 で身につけました。 次の Part で、最小の Web サーバーから書き始めます(/server/01-hello-server/)。