レビュー説明資料 - katataku/webserv GitHub Wiki

レビュー説明資料

課題の概要

「HTTPサーバ(webサーバ)」を作成する課題。代表的なwebサーバである「nginx」というアプリケーションの仕様を参考にして実装しました。

課題のポイントは、

  • HTTPは、RFCで規格が定められているので、RFCを見ながら実装すること。(RFCはあくまで標準規格であり、全ての詳細仕様決められていない。詳細は、自分達で決めた仕様に基づく。)
  • I/O multiplexing(I/O多重化)を行うこと。そのためにSelect (or equivalent)を使うこと。
  • configファイルを使って、いろんな設定を切り替えられるようにすること。
  • ストレステストツール(siege)を使った大量リクエストにも、対応できるようにすること。

です。

HTTPサーバとは

クライアント(webブラウザなど)からリクエストを受け取り、レスポンスを返却する。

リクエスト/レスポンスの内容はプロトコル「HTTP(Hyper Text Transfer Protocol」)に従う。

通信の基本

プログラム同士が通信を行う際にはSocketという仕組みを使います。

Socketでは「自分の80番ポートは、192.128.0.1:8080と通信している」みたいな情報を管理しています。

Socketに対して書き込みを行うと、相手側で受け取ることができます。(だいたいのイメージ)

Socket通信の流れ(細かいのでソースコードを見るタイミングで参考にする用)

ポイントとなる流れは

  • サーバ側でソケットを用意する。(bind/Listen)
  • クライアントからの接続を受け付ける。(Connect/Accept)
  • 接続完了後、 データのやり取りを行う。(Read/Write)
  • 使い終わったソケットのお片付け。(Close)

です。

I/O multiplexing(I/O多重化)

「一つのプロセス(スレッド)」で、複数のクライアントからのリクエストを処理できるようにする。

昔は

複数のクライアントの処理を「複数のプロセス」でやってた。しかし、この方法はすぐに性能の限界が来ちゃうのでイマイチ。(C10K問題)

I/O multiplexingでは

その対策として1つのプロセスとして処理する。ただし、普通にやってもダメなので、Read/Writeの処理に「ノンブロッキングI/O」という工夫をする。

  • 昔の処理(ブロッキング):準備ができるまで、他の処理をブロックして、待つ。(読み込むためのデータが届いているか、書き込む準備ができているかなど。)
  • 今回の処理(ノンブロッキング):準備ができるまで待たない(ブロッキングしない)。その代わり、準備できてるか事前確認してから処理する。

select/poll/epollというシステムコールを使って、Socketを使う準備ができているか確認する。

(参考)コンビニでわかるノンブロッキングI/O

シングルスレッド×ブロッキングIO

マルチスレッド×ブロッキングIO

シングルスレッド×ノンブロッキングIO