朝日薫さん、
>dhcp005〜7
については、AN HTTPD では実質的に帯域制限がかかってしまっている感じですね。
どこでどうなっているのかを調べておきます。
帯域制限を考える上で、同じ環境で同時に複数の接続で実行した場合に転送レートがそれぞれどう変化するかも調べておいてもらえるとうれしいです。
>望むようなものになるかどうかは保証の限りではありませんけど。
おっしゃられるまでもなく!(^^A;
開発に関する決定権はすべて中田さんが持ってるのであって、
わたしらユーザやファンには、フィードバックを重ねることしかできません。
AnHttpd はWindows9x系でも安定動作できるWebサーバの筆頭です。
NTカーネル系だと選択肢は増えますが、9xでも稼動するコンパクトなもの、
設定が容易なもの、というとどうしても限られていますしね。
(もっとも最近は、メモリ64MB以下のシステムでは少々厳しくなった気もしますが…)
で、報告。→ http://multix.jp/~askn/cgi-bin/bench2/trans.html
dhcp005〜7 がそれぞれ同一PC上で稼動させた、IIS/PWS、AnHttpd、Apache の実行結果例です。
テストサーバとはP2P直結で、不要なプロセスは可能な限りとめています。
PI〜FILE が誤差の範囲で近似してるのは同一のPerlを呼んでるのですから当然ですが、
転送レートについてのみ、何故これだけの明確な差が付いてしまうのかはよくわかりません。
(ただ、トータルの実行ファイル+DLLサイズは、Apacheがいまや最小なのは確か…)
(Apacheの場合はUNIX互換の(素人には手におえない)テキストによる設定方式で、
ダイアログ回りがない分小さい、という推測はできますけど、それ以上はなんとも)
朝日薫さん、
Webサーバの方は複数のリクエストに対応させることは比較的容易にできましたが、プロクシ/キャッシュの方がちょっと手間取りそうです。
>そろそろ各機能をプラグイン化して
というあたりは、考え方はもちろんわかるのですが、いざ実行しようとするとどうも、、といったところですね。
とはいえ、一通りつかめてきたような気がするので、今作成中のバージョン2ではそういうことも考えてはいます。 朝日さんの望むようなものになるかどうかは保証の限りではありませんけど。
そろそろ各機能をプラグイン化して、なんらかの設定ファイル(やプロパティ)で動的に
組み込めたり、実行できたりする方向へ向かっていくのもいいのではないかしら?
サーバ本体は小さくて軽いままにして置けるし。(コンパクトなシステムほど堅実に動く、というのは自分の持論ですが)
APIを決めてラッパーを用意すれば、第三者が独自のアドオンを設計できるかもしれない。
朝日薫さん、
すべて納得、了解です。
近々対応版を出しますので、それでまたやってみてください。
その後の追試です。
>パフォーマンスにどのくらいの差が出ますか
AnHttpd に限っていえば、動的コンテンツに対しては
HTTP/1.0 でアクセスした方が“だんまり”がまったくないので、
プログレスバーが消えるまでの時間は短いです。
特にアクセスカウンタなどで
1桁分の画像表示毎に個別にCGIを呼ぶタイプでは、
見た目にもすぐに差がわかります。
>忘れてしまうケース
先の投稿の httpget.cgi の場合、受信開始の前にふたつの
GETリクエストを一括送信しています。
しかし AnHttpd では最初の1つのリクエストしか受け付けません。
おなじことは telnet で80番ポートに接続して、直接サーバと対話しても再現可能です。
=SEND=============================================
GET /html0201/grace.html HTTP/1.1 <1個目のリクエスト
Host: 192.168.1.21
Connection: Keep-Alive
User_agent: HttpGet/1.1
GET /html0201/grace.html HTTP/1.1 <2個目のリクエスト
Host: 192.168.1.21
Connection: Close
User_agent: HttpGet/1.1
<ここまでを(何かを受信する前に)1回で送信
=RECV=============================================
HTTP/1.1 200 Document follows <1個目の応答
MIME-Version: 1.0
Server: AnWeb/1.38c
Date: Tue, 12 Feb 2002 13:29:19 GMT
Content-Type: text/html
Accept-Ranges: bytes
Content-Length: 1994
ETag: "3c5cbea7-7ca"
Last-Modified: Sun, 03 Feb 2002 04:37:59 GMT
<html><head><meta name="robots" content="index,follow">
<meta http-equiv="Content-type" content="text/html; charset=Shift_JIS">
<link rel="SHORTCUT ICON" href="http://multix.jp/favicon.ico">
:
:
<1個目の受信が終わったところでだまりこみ、15秒後に切れる
==================================================
結果的に(ブラウザから見れば)「Connection: close」を(ブラウザから)送信しているにも
関わらず、AnHttpd はこれを見てなくてそのまま keep-alive 待ちに
なっている……ということです。
従ってブラウザ側が“keep-alive できない”と判断して
ソケットを切らないと無駄な時間を消費してしまいます。
「コンテンツの受信が完了するまでは次のリクエストをしてはいけない」という
決まりは、たしかなかったように思うのでこの方法が間違いかどうかは判りません…。
(Apacheは静的/動的の両方、IISは静的コンテンツのみは問題なく返してきます)
(またどちらのサーバも keep-alive 出来ないときは、サーバ側からソケットを切ります)
通常はソケットをブロッキングモードで扱う、PerlやJavaでコーディングした
ブラウズアプリの場合、サーバ側がソケットを切るまで受信待ちになるので、
だんまりになるんですよ…。プロキシや先読アクセラレータの類もそうです。
真面目にチャンクや Content-length からエンドを計算すればよいのでは?といわれそうですが、
動的コンテンツでは Content-length が存在しないことが多い(つまり当てにならない)ので、
サーバ側からソケットが切られるまでは受信データがある“かもしれない”と
判断するアプリが大多数ではないかと思います。そもそも
コンテンツデータが最後まで、誤りなく到達する保証は一切ないわけですし。
サーバ側から送られる Connection ヘッダがあれば、ヘッダを読み終わった段階で
次のリクエストをどうすべきか(ソケットを切るか否か等の)
判断する指針になるのでしょうけれど…。
>静的コンテンツでチャンクを返すことはないはず
SSIの項目で「index.html」にチェックをすると、「index***.html」という
名前のファイル“index1.html”や“index_top.html”等が
このケースに該当し、細切れチャンクになりました。
このチェックを外した場合はまったく正常なので、バグ…かな?
>304 は Not Modified
失礼しました。「403」を返します。具体的には、
=SEND=============================================
GET http://192.168.1.21/cgi-bin/bench.cgi HTTP/1.0
Connection: Close
User_agent: HttpGet/1.1
=RECV=============================================
HTTP/1.1 403 Forbidden
MIME-Version: 1.0
Server: AnWeb/1.38c
Date: Tue, 12 Feb 2002 13:19:31 GMT
Content-Type: text/html
Connection: close
Content-Length: 238
<HTML><HEAD><TITLE>Error </TITLE></HEAD>
<BODY>
<H1>Error 403</H1>
Server Error: doesn't pass protocol : http://192.168.1.21/cgi-bin/bench.cgi<HR><ADDRESS><a href="http://www.st.rim.or.jp/~nakata/">AnWeb/1.38c</ADDRESS>
</BODY></HTML>
==================================================
となりました。つまり以下の形式以外には応答していません。
=SEND=============================================
GET /cgi-bin/bench.cgi HTTP/1.0
Connection: Close
User_agent: HttpGet/1.1
=RECV=============================================
HTTP/1.0 200 Document follows
MIME-Version: 1.0
Server: AnWeb/1.38c
Date: Tue, 12 Feb 2002 13:22:14 GMT
Transfer-Encoding: chunked
Pragma: no-cache
Last-Modified: Tue, 12 Feb 2002 13:22:14 GMT
Content-type: text/plain;
==================================================
このタイプのアクセスは本来はプロキシ目的ですが、時々サーバログに
散見できますから、許容範囲だと思ってたました。違うのかな?
(実際に IISや Apacheは問題なく受け付けてくれるし)
朝日薫さん、
Keep-Alive(というか、HTTP/1.1 のデフォルトの持続型接続)については、実装方法に迷いもあって、まともにしないといけないと思っている部分ではあります。
ただ、パフォーマンスとの関係では、それ以前の問題があると思っていて、Keep-Alive は後回しになっています。
いくつか疑問もあるので、以下に列挙します。
(1)Apache で Keep-Alive を使う場合と使わない場合とでパフォーマンスにどのくらいの差が出ますか?
(2)AN HTTPDで「前のコンテンツ出力の途中で受けたリクエストはまったく見ていないか、忘れてしまうようです。」ということはないと思いますが、そう思える状況がどんなものなのかをもう少し説明してください。
(3)リクエストとレスポンスが両方とも HTTP/1.1 なら Connectionヘッダは必須ではないはずだと思っています。「...結局“Keep-alive に対応していない”と判断するブラウザ」というのはどのブラウザですか? また、そのブラウザがそう判断したと思った理由は何でしょうか?
(4)AN HTTPD で静的コンテンツでチャンクを返すことはないはずです。 .html で SSI が有効になっているのではないでしょうか?
(5)304 は Not Modified ですね。 リクエストが HTTP/1.0 の場合は Host: ヘッダがなくてもいいはずです。
参考までに、ベンチマークのURLを残しておきます。希望者は遠慮なく参加してください。
http://multix.jp/~askn/cgi-bin/benchsvr.cgi
また、WebサーバのHTTP応答を直接確認したい場合は
http://multix.jp/~askn/cgi-bin/httpget.cgi
を使ってみてください。(悪用はしないでくださいね)
どうも keep-alive が完全には機能していないようです…。>1.37dと1.38cで確認
AnHttpdの場合、1つのコンテンツの送信が完全に終わってから
次のリクエストのKeep-alive 待ちになるようですが、
前のコンテンツ出力の途中で受けたリクエストは
まったく見ていないか、忘れてしまうようです。
認証に失敗することがあるのは、この辺に原因があるのかも。
Apache1.3.18あたり以降の場合、max値以内の数のリクエストは
予め最初の一回で一気に受け取れ、正しく応答します。
(1.3.6の頃は一個ずつしか受け付けませんでしたが…)
それに「Keep-Alive: timeout=15, max=100」
といったリクエストヘッダも返さず、
「Connection: Keep-Alive」も帰ってこないので、
結局“Keep-alive に対応していない”と判断するブラウザもあります。
Connection レスポンスがないのは、明らかにおかしいですね。
プロセスの終了待ちが遅れる〜というのは、この関係に思えます。
(ブラウザの方は別のソケットを新たに張りなおします。だからネゴが遅くなる)
実は、数日前から各種Webサーバの性能計測を行うプログラムを組んでいて、
その過程で AnHttpd や IIS のパフォーマンスがどうしても
Apache for Windows の数分の1しか出せず、原因追求に苦労してました(´д`;)
Apacheの場合はCGIやSSIなどの動的コンテンツも Keep-alive 出来るため、
一本のソケットを張るだけですべてのデータをなめらかに拾得できます。(これなら確かに速い)
そして AnHttpd の場合、静的コンテンツでさえも1行単位のチャンクにして
送り返すため、ブラウズ側の負担が明らかに増加してしるのが現状です。
(チャンクデータが小さすぎて、バッファ能率が落ちる)
余談ですが「GET http://hoo.hoo/ HTTP/1.1」といったプロトコル/ホスト名付きの
リクエストを貰うと、受け取られずに「304エラー」で拒否されてしまいます。
これはこれで仕様のような気もしますが、HTTP/1.0 では VirtualHost を実現するために
(Host: ヘッダがなくても機能するように)許された書式なので
すこし融通が利かないように思いました。