1 はじめに

現在もっとも広く使われているWEBサーバーはApacheである。Apacheの多くはUNIX上で動作している。
Apacheはフリーソフトであり、その性能は高く評価されている。優秀であるが故に、その機能は多く逆に、Apacheの動作に影響があるといえる。
そのため、限りなく機能を限定したWEBサーバーを作ることで、より高速な動作が可能になるのではないかと考えられる。
Apacheは、Linux、WindowsでのVersionがリリースされている。
本研究では簡単な機能を持つ自作のWEBサーバーをつくり、計測プログラムにより、Apacheとの性能の比較を行う。

1.1 WWWの歴史

1945年
MIT(マサチューセッツ工科大学)副学長のVannever Bush(ヴァンヴァー・ブッシュ)がWWW(World Wide Web)の概念「メメックス(Memex)」を構想。

1965年
テッド・ネルソンがハイパーテキストのプログラム「ザナドゥ(Xanadu)」を発表。

1989年
CERN(欧州素粒子物理学研究所)のティム・バーナーズ・リー(Tim Berners-Lee)氏が、WWW の基本的な仕組みを考案。 WWW(World Wide Web)の命名、NeXT コンピュータ上でサーバーとブラウザを試作。

1993年
イリノイ大学の NCSA(National Center for Supercomputing Applications) のマーク・アンドリーセン(Mark Andreessen)氏らが、Next 上のブラウザ Mosaic 1.0 をリリース。

1994年3月
Mosaic の将来性に目をつけた SGI(Sylicon Graphics)社のジム・クラーク(Jim Clark)氏が、アンドリーセン氏を引きぬいて Mosaic Communications 社(現在の Netscape Communications 社)を設立。 (以下 Netscape社)

1994年10月
バーナーズ・リー氏、HTML などの仕様を作成する機関として W3C(WWW Consortium)を設立。

1994年12月
Netscape社が Mosaic Nwtscape(後の Netscape Navigator) 1.0 をリリース。(Windows, Macintosh用)開発コードの Mozilla は、Mosaic と怪獣 Gozilla の合成語。翌年4月には 1.1、7月には 1.2 をリリース。パーソナルユーザーにもブラウザが広まる。

1995年3月
当時、Webサーバーとしては、CERN httpd と NCSA httpd が主だったが、NCSA httpd 1.3 に対するパッチの形式で Apache 0.2 が初公開。
 
1995年8月
Microsoft社が Internet Explorer 1.0 をリリース。コードは Info Mosaic をベースにしている。11月には早くも2.0をリリース。
 
1995年11月
IETF、HTML2.0(RFC1866)発行。
 
1996年3月
Netscape社、Netscape Navigator 2.0 をリリース。JavaScript 1.0 と Java をサポート。

1996年8月
Netscape社、Netscape Navigator 3.0をリリース。同時期に Microsoft社も Internet Explorer 3.0をリリース。Netscape Navigator 2.0 の JavaScript 相当の機能をサポート。スタイルシートの一部の機能を先取りサポート。

1996年12月
W3C、CSS1.0を勧告。

1997年1月
W3C、HTML3.2を勧告。それまで検討されていた HTML3.0 は廃案に。
 
1997年6月
Netscape社、Netscape Communicator 4.0 をリリース。スタイルシートや、ダイナミックHTML機能をサポート。

1997年10月
Microsoft社、Internet Explorer 4.0 をリリース。スタイルシート、XML をサポート、ダイナミックHTML機能をサポート。

1997年12月
W3C、HTML4.0を勧告。1999年12月にはマイナー改版の 4.01 を勧告。

1998年2月
W3C、XML1.0を勧告。

1998年5月
W3C、CSS2.0を勧告。

1998年7月
Netscape社、Netscape Communicator 4.5をリリース。他にも、4.06、4.6、4.7 など、マイナーバージョンアップを繰り返す。Netscape もブラウザの無償配布を始め、Mozilla開発の主体をボランティアに移す。
 
1998年11月
Netscape社、AOL社に買収される。
 
1999年2月
NTTドコモ、携帯電話で「iモード」サービスを開始。

1999年3月
Microsoft社、Internet Explorer 5.0をリリース。この頃から、Internet Explorer のシェアが Netscape のシェアを上回るようになる。

2000年1月
W3C、XHTML1.0を勧告。

2000年7月
Microsoft社、Internet Explorer 5.5をリリース。

2000年11月
Netscape社、Netscape 6 をリリース。最初から作りなおしたに等しいもの。最新の仕様に準拠している。

2000年12月
W3C、XHTML Basicを勧告。

2001年1月
NTTドコモ、iモードで Java アプリケーションを動かす「iアプリ」サービスを開始。

2001年8月
Netscape社、Netscape 6.1 をリリース。Microsoftも Internet Explorer 6.0 をリリース。

1.2 Apacheの歴史

Apacheは、NCSA版Webサーバーをベースにパッチ当てから歴史が始まった。
Apacheのソースパッケージに含まれる src/CHANGES によると、Apache 0.2が1995/3/18 に公開された事になっており、それはNCSA httpd 1.3に対してパッチを当てたものとされている。
その後、Apache 1.0に至るまで、バグ修正と新機能の追加を繰り返し行ってきており、またさまざまなOSで動作するように移植が繰り返された。

1.3 サーバー・クライアントについて

WEBサーバーとは、HTTPを利用して情報を提供するソフトウェアである。インターネット上においてTCP/IPと呼ばれるプロトコルを介して、WEBブラウザによって見ることができるホームページや掲示板、チャットのシステムやデータ・画像等を置くためのスペースとなるコンピュータシステムソフトウェアのことを示している。WEBサーバーの基本的な動作は、大きく分けて2種類存在する。WEBブラウザ(Internet Explorer や Netscape 等)から要求されたファイルを返すか、要求されたプログラム(たとえば、CGIなど)を実行して、その結果を返すかのどちらかである。



                                  図1 WEBサーバーの動作

サーバーの特定(IPアドレス)コンピュータ同士が通信する際には、”プロトコル”と呼ばれる通信手段を決定し、お互いに同じプロトコルを使わなくてはならない。プロトコルとは、通信を行う手順である。通信を行うもの同士は同じプロトコルをつかわなければならないので、必ずあらかじめ決めておく必要がある。これは、人間同士が会話するときに、同じ言語を使うのと類似している。プロトコルには、さまざまな種類が存在し、また、組み合わされている。インターネット上ではインターネットプロトコル(IP)というプロトコルを利用されるが、さらに通常はデータ通信にTCPというプロトコルが、使用される。特にこの2つはまとめてTCP/IPなどと書かれる。

WWWでは、このTCP/IP上でさらにHTTP(Hyper Text Transfer Protocol)というプロトコルを組み合わせて利用する。HTTPは単に情報を要求すると、それに対して情報を提供するだけという単純なプロトコルである。したがって、WEBサーバーの基本機能はきわめて単純である。クライアントもHTTPに従い情報を取り出し、HTMLに従い情報を表示するというのが基本機能である。

クライアント側に必要となるソフトは、見るためのWEBブラウザだけなので、オペレーティングシステム(OS)はWindows、Macintosh、UNIXなど何でもよいのが大きな特徴である。最近では携帯情報端末からでもWebページを閲覧できるようになってきている。

                     図2 相手先のIPアドレスの指定

2 WWWシステムについて

本実験においてもっとも重要なシステムであるWWWシステムは、先に述べたようにサーバー・クライアント形式で提供されるものである。
そこで、WWWシステムでの、サーバーからクライアントへ送信される情報とクライアントからサーバーに送信される情報について説明する。
そして、計測に使うプログラムのApacheBenchについても説明する。

2.1 WWWサーバーの仕組み

クライアントからサーバーへのリクエスト
例として、
GET /a.jpg HTTP/1.0
Accept: */*
Accept-Encoding: gzip
Connection: close
Host: c.net.dendai.ac.jp
のようなメッセージがサーバーへ送信される。

サーバーからクライアントへのレスポンス
上記のようなメッセージを受信したサーバーは、クライアントのリクエストに対し、様々な反応を示す。
例えば、クライアントがリクエストしたファイル(上記の場合a.jpg)がサーバー内で発見された場合、次のようなメッセージをクライアントに返信する。

HTTP/1.0 200 OK
Date: Tue, 17 Jul 2001 15:59:52 GMT
Server: Apache/1.2.7-dev
Last-Modified: Tue, 17 Jul 2001 11:15:45 GMT
Content-Length: 3837588
Accept-Ranges: bytes
Connection: close
Content-Type: image/jpeg

<ここからはJPEGのデータ本体>


しかし、サーバー内にファイルが発見できない場合は次のようなメッセージをクライアントに返信する。

HTTP/1.0 404 Not Found
Date: Tue, 17 Jul 2001 15:30:03 GMT
Server: Apache/1.3.12 (Unix) mod_perl/1.24
Connection: close
Content-Type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>404 Not Found</TITLE>
<BODY><H1>Not Found</H1>The requested /$filename URL was not found on this server.
<P></P></BODY></HTML>


ブラウザ表示メッセージは以下のようになる。

Not Found

The requested /$filename URL was not found on this server.

最低限度のヘッダ
GET /a.jpg HTTP/1.0
のように、クライアントからサーバーへのリクエストは、最低限この一行だけを送ればよい。これは、クライアントの要求するデータ名を送信することで、サーバーが最低限その有無を判断することができるからである。

最低限度のエラー処理
HTTP/1.0 404 Not Found
のように、サーバーからクライアントへのエラーレスポンスは、ステータスコードを返すことで処理できる。

2.2 最小構成のWWWサーバーの構成について

処理の概要
クライアントからサーバーへのリクエストに対し、サーバーからクライアントへのレスポンスを必ず返す。

受け入れるメッセージ
クライアントからは
GET /a.jpg HTTP/1.0
の一行だけをクライアントから受け取る。

処理の仕様
クライアントからの
GET /a.jpg HTTP/1.0
などのリクエストに対し、サーバーからクライアントへのレスポンスとして、
HTTP/1.0 200 OK
などのレスポンスを返す。

実際のプログラムの流れ
Linux用Dserverのプログラムの場合
ソケットCLIENT_WAITINGを作り、待機状態にする。
CLIENT_WAITINGに対して、4引数selectで入力があるか調べる。
入力があった場合、つまりクライアントが接続してきた場合はaccept して、データコネクション用ソケット CLIENT_0 を生成する。
CLIENT_WAITINGとCLIENT_0 に対して、4引数selectで入力があるか調べる。 CLIENT_WAITING に対して入力があった場合は、同様に accept して、新たなデータコネクション用ソケットCLIENT_1を生成する。その後、新たなコネクションが張られるたびに、 CLIENT_2、CLIENT_3 … というソケットを生成する。CLIENT_0 や CLIENT_1 などのデータコネクションが読み出し可能なら、ソケットから一行読み出して、
GET /a.jpg HTTP/1.0
からa.jpg を取り出し、その有無を確認する。

a.jpgがあった場合
1 200のステータスコードを返す。
2 クライアントからアクセスされた時間を返す。
3 サーバー名を返す。
4 Content-Length、Accept-Rangesを返す。
5 Connectionを返す。
6 Content-Type返す。(Content-Typeの判別にはファイルのヘッダを調べてを判別する。)
7 一行空ける。
8 データ本体を返す。

HTTP/1.0 200 OK
Date: Tue, 17 Jul 2001 15:59:52 GMT
Last-Modified: Tue, 17 Jul 2001 11:15:45 GMT
Server: Devio
Content-Length: 3837588
Accept-Ranges: bytes
Connection: close
Content-Type: image/jpeg

<ここからはJPEGのデータ本体>

a.jpgがなかった場合
1 404のステータスコードを返す。
2 クライアントからアクセスされた時間を返す。
3 サーバー名を返す。
4 Connectionを返す。
5 Content-Type返す。
6 一行空ける。
7 404をブラウザで表示するHTML文書を返す。

HTTP/1.0 404 Not Found
Date: Tue, 17 Jul 2001 15:30:03 GMT
Server: Devio
Connection: close
Content-Type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>404 Not Found</TITLE>
<BODY><H1>Not Found</H1>The requested /$filename URL was not found on this server.
<P></P></BODY></HTML>

アクセスされた時間、リクエストされたファイル名、結果をテキストファイルで形式でログを保存する。
送信終了後、ソケットをクローズし、再び待機状態にする。

Windows用Dserverのプログラムの場合
ソケットオブジェクトを作成する。このオブジェクトを$server_socketに格納し、accept関数で待機状態にする。
もし、クライアントが接続してきた場合、クライアントと接続するためソケットオブジェクトを$client_socketに格納する。
ソケットから一行読み出して、
GET /a.jpg HTTP/1.0
からa.jpg を取り出し、その有無を確認する。

a.jpgがあった場合
1 200のステータスコードを返す。
2 クライアントからアクセスされた時間を返す。
3 サーバー名を返す。
4 Content-Length、Accept-Rangesを返す。
5 Connectionを返す。
6 Content-Type返す。(Content-Typeの判別にはファイルのヘッダを調べてを判別する。)
7 一行空ける。
8 データ本体を返す。

HTTP/1.0 200 OK
Date: Tue, 17 Jul 2001 15:59:52 GMT
Last-Modified: Tue, 17 Jul 2001 11:15:45 GMT
Server: Devio
Content-Length: 3837588
Accept-Ranges: bytes
Connection: close
Content-Type: image/jpeg

<ここからはJPEGのデータ本体>

a.jpgがなかった場合
1 404のステータスコードを返す。
2 クライアントからアクセスされた時間を返す。
3 サーバー名を返す。
4 Connectionを返す。
5 Content-Type返す。
6 一行空ける。
7 404をブラウザで表示するHTML文書を返す。

HTTP/1.0 404 Not Found
Date: Tue, 17 Jul 2001 15:30:03 GMT
Server: Devio
Connection: close
Content-Type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>404 Not Found</TITLE>
<BODY><H1>Not Found</H1>The requested /$filename URL was not found on this server.
<P></P></BODY></HTML>

アクセスされた時間、リクエストされたファイル名、結果をテキストファイルで形式でログを保存する。
送信終了後、ソケットをクローズし、再び待機状態にする。

2.3 ApacheBenchについて

ApacheBenchとはApacheに標準で付属しているWEBサーバーの動作確認及び計測プログラムである。このプログラムを使用することでApache以外のWEBサーバーの動作確認および計測することもできる。

This is ApacheBench, Version 1.3d <$Revision: 1.58 $> apache-1.3
Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright (c) 1998-2001 The Apache Group, http://www.apace.org/

使い方
Usage: [options] [http[s]://]hostname[:port]/path
例として、CドライブにApacheBench(ファイル名ab.c)がある場合
C:\>ab -n 1000 http://localhost:80/a.jpg
で実行される。
これはlocalhostのポート80番に接続して、a.jpgを要求することを意味する。

オプション

Options are:
	-n requests	Number of requests to perform
	-c concurrency	Number of multiple requests to make
	-t timelimit	Seconds to max. wait for responses
	-p postfile	File containg data to POST
	-T content-type	Content-type header for POSTing
	-v verbosity	How much troubleshooting info to print
	-w 		Print out results in HTML tables
	-i		Use HEAD instead of GET
	-x attributes	String to insert as table attributes
	-y attributes	String to insert as tr attributes
	-z attributes	String to insert as td or th attributes
	-C attribute	Add cookies, eg. 'Apache=1234'(repeatable)
	-H attribute	Add Arbitrary header line, eg. 'Accept-Encoding: zop'
			Inserted after all normal header lines. (repeatable)
	-A attribute	Add Basic WWW Authentication, the attributes
			are a colon separated usename and password.
	-P attribute	Add Basic Proxy Authentication, the attrivutes
			are a colonseparated username and password.
	-V		Print version number and exit
	-k		Use HTTP KeepAlive feature
	-d		Do not show percentiles served table
	-s		Do not show confidence estimators and warnings
	-g filename	Output collected data to gnuplot format file.
	-e filename	Output CVS file with percentage served
	-s		Use httpS instead of HTTP (SSL)
	-h		Display usage information (this message)
結果
Server Software:		/*servername
Server Hostname:		/*hostname
Server Port:		/*port
Document Path:		/*path
Document Length:		/*document length
Concurrecy Level:		/*concurrency
Time taken for tests:	/*time
Complete requests:		/*complete repuests
Failed requests:		/*failed requests
	(Connect: ,Length: ,Exceptions:)	/*(error connet, error length, error exceptions)
Broken pipe errors:	/*error pipe
Non-2xx responses:		/*error response
Keep-Alive requests:	/*keep-alive requests
Total transferred:		/*total read
Total POSTed:		/*total posted
HTML transferred:		/*total byte read
Requests per second: [sec]	/*time
Time per request: [ms]	/*time per request
Time per request: [ms]	(across all concurrent requests)
Transfer rate: [Kbytes/sec] receved	/*transfer rate
	kb/s sent
	kb/s total

ApacheBenchが送信するリクエスト

GET,HEADの場合
"GET "or"HEAD "(URL)" HTTP/1.0"
"User-Agent: ApacheBench/"(VERSION)
"Conection: Keep-Alive" or ""
(cokie)
(WWW Autentication)
"Host: " (hostname)
"Accept: */*"
(header line)

POSTの場合
"POST "(URL)" HTTP/1.0"
"User-Agent: ApacheBench/"(VERSION)
"Conection: Keep-Alive" or ""
(cokie)
(WWW Autentication)
"Host: " (hostname)
"Accept: */*"
"Content-Length: "(POST Length)
"Content-type: ""text/plain"or(etc)
(header line)
"INFO: POST header == "
---
(repuest)
---


3 実験

3.1 実験の目標

Apacheと自作のWEBサーバーについて、ApacheBenchを使い測定結果を元に両者の比較をする。

3.2 実験を行った装置と構成

Apache、自作のWEBサーバー(Dserver)を動かすための同一のハードウェアを用意する。
LinuxをインストールしたコンピュータにLinux用のApacheとDserverを起動できる段階までにしておく。
同じくWindows2000をインストールしたコンピュータにもWindows用のApacheとDserverを起動できる段階までにしておく。
計測にはLinuxをインストールしたコンピュータにApacheBenchを起動できるようにする。
それぞれの端末からスイッチングハブを用いて100BaseTXで接続した。


       図3 接続構成図

3.3 実験方法

Linux上のApache、Dserver、Windows上のApache、Dserverに対し、ApacheBenchを用いて次の要求を1000回行い所要時間を計測した。
1 1KBのファイルの要求
2 10KBのファイルの要求
3 100KBのファイルの要求
4 1MBのファイルの要求

3.4 実験結果

        表1 Time taken for tests(sec)
   Linux    Windows
Apache Dserver Apache Dserver
1KB 8.110 3.891 2.443 6.137
10KB 8.558 4.694 3.303 7.469
100KB 11.442 13.974 109.996 20.057
1MB 90.743 102.299 1260.737 130.291


                                                図4 Time taken for testsのグラフ

         表2 Requests per second
       Linux

     Windows

Apache Dserver Apache Dserver
1KB 123.46 257.00 409.33 162.95
10KB 116.85 213.04 302.76 133.89
100KB 87.40 71.56 9.09 49.86
1MB 11.02 9.78 0.79 7.68


                                           図5 Requests per secondのグラフ

      表3 Transfer rate(kb/s received)
        Linux      Windows
Apache Dserver Apache Dserver
1KB 160.62 295.81 519.44 187.71
10KB 1229.14 2208.78 3174.99 1388.27
100KB 8974.04 7337.13 933.21 5111.93
1MB 11558.57 10251.38 831.92 8048.96


                                                        図6 Transfer rateのグラフ


3.5 結果の解説とまとめ

LinuxではApacheの転送にかかった時間がDserverより時間がかかった。これはDserverの大きな特徴である、機能の限定による結果である。比較的低容量での転送に対しては効果が出たものの、比較的容量の大きいものに対してはあまり効果のない結果となった。

WindowsではDserverはLinux同様に安定した動作を見せたが、Apacheは比較的低容量に対しては速い転送速度を記録したが、比較的容量の大きいものに対しては残念な結果を残した。これは、オペレーティングシステム(OS)の違いによるものと考えられる。Linuxは現在あるハードウェア上では非常に動作が軽く負担がかからない。しかし、WindowsはLinuxよりも負荷がかかるため、このような結果が出たと考えられる。

結果として、機能を限定して制作したWEBサーバーは高負荷時にはApacheを超える転送性能を発揮した。これは、Apacheに搭載される様々な機能はパフォーマンスに悪い影響を与えていることがわかった。又、Apacheは大きなファイルの転送を行う際、特にパフォーマンスが悪くなることがわかった。

その他


参考資料
[1] 日本Apacheユーザ会(仮), JAPAN APACHE USERS GROUP, http://www.apache.jp/, 2000
[2] Copyright (C) 1998-2001 杜甫々, とほほのWWW入門, http://tohoho.wakusei.ne.jp/, 1996
[3] 68user, 68user's page, http://x68000.startshop.co.jp/~68user/, 1997
[4] Okamura.Lab, 岡村 宗治, http://www.sit.ac.jp/user/okamura/, 1999
[5] 武藤健志/トップスタジオ編著, 独習Perl, 翔泳社, 2000
[6] R. Fielding UC Irvine H. Frystyk MIT/LCS, Hypertext Transfer Protocol -- HTTP/1.0 RFC1945, 1996