« Leopard (MacOS 10.5.1) の Windows shareの bug回避 | トップページ | Foneraの WLAN access pointが怪しい »

2008年2月28日 (木)

Polipoが覗く HTTP/1.1の深淵(?)を UMLGraphで解説してみる

DolipoPolipoが 話題になっているようで。 でもその原理になっている HTTP/1.1の仕組みとかはそれほど理解されてなさそう。 この記事 でも Poor Man's Multiplexingは飛ばしちゃってるし。

ということで、自分の思い出すのと UMLGraphの練習を兼ねて 解説したいと思います。 Sequence図の UMLGraph sourceももれなく公開という大盤振る舞いです (って、だれが喜ぶんだろう)。

HTTP 0.9

まず、HTTPの基本形とは以下のようなかんじです。
Requestがあって Responseがあるという単純なもの。 そして重要なのが transactionごとに TCPを張り直すということ。 これは、HTTP/0.9時代は responseの終わりを TCP Disconnectionで 示すという荒っぽい仕様だったためしかたないっす。

つまり、三つの tranasctionがあったら以下のようになります。

TCPの SYNや FINの時間がもったいないっすね。

HTTP/1.1 の工夫

ということで出てくるのが persistent connectionです。 これは HTTP/1.0では Content-length headerでコンテントの 終わりを明示できるのでできる技です。 HTTP/1.1ではこれが標準になってます:
絵の上からでも短くなったのが分かるでしょう。

さらに、全体の応答時間 (latency) を短くするための 工夫が pipeliningです。

絵ではちとズルをして縦幅を短くしてありますが、 Responseを待ってから次の Requestを 投げるより、Requestを立て続けに投げた方が 全体として時間を無駄にしてないのはイメージできますよね?

あともう一つ、Range Requestの話もしときます。 これは、コンテンツを頭から読み出すんじゃなくて 指定したバイトから指定した長さだけ呼び出すってもの。

たとえば PDF Pluginとかで使われてます。 Web最適された文書の場合、読みたいページに飛んだらそこの 内容だけを読み出すようにして、いらない途中のページの転送時間をかけない。 だから、PDFは Downloadして Helper applicationで読むより、 Pluginで読む方が早いはず。

でも、個人的には昔の Pluginが不安定だったり、 Pluginだと画面が狭くなるので、Helper applicationで呼んでますが。

polipoはこういう技術をバリバリ慎重に使ってる

で、こういう風な工夫がされているのが HTTP/1.1なんだけど、 実のところ積極的には使用されてないような気がします。 調べたわけじゃないので断言できないけど。 少なくとも某社のブラウザとかでは。

なぜかといえばいろいろ実運用上問題があるから。

たとえば典型的な問題に pipeline stallというのがあります。 上の sequece chartでいえば、 Response1 がすごく重い CGIで生成される画像で、 Response2 がちっちゃい静的な画像だったりします。 そうすると、Response1の生成に時間がかかってるせいで、 Response2の画像も画面に表示することができない。 複数 connectionを張っていれば、Response2はサクッと 素早く取り出せたのに。

まあ、そういうしがらみがあって、みんな保守的にやってるのかもしれません。 そこを、polipoは果敢に使える機能は使っちゃってるので いい感じに早くなってるのかも。 そして、そういう問題を回避する know howとかも入ってるんじゃ ないかなあ、って documentも読まずに想像してます。

「polipoのパイプラインについて」(わかつも) によると

polipoはサーバーがパイプラインをサポートしているか慎重に調べ(carefully probes)てからパイプラインを使うぜ
だそうです。ここら辺が肝なんでしょうねえ。

最後に Poor Man's Multiplexing

で、最後に問題の Poor Man's Multiplexingについて説明します。

でもドキュメント見ると polipoの PMMって既定値では offなんですよね。 やっぱり "an intrinsically unreliable technique" (本質的に信頼できない技巧) だからねえ。 ということで PMMは polipoの高速性にはあんまり貢献してないと思うんですが、 乗りかかった船ということで。

最初に、Multiplexingとは何かと言うと、 複数の transactionを順番じゃなくて同時に送っちゃうことです。

本来 Persistent connectionや pipelineを使っても、objectは順番にしか 取り出せないわけです。 で、 pipeline stallとかの問題が起こるわけです。

ちょっと前の (今でも?) お行儀の悪い web browserとかでは、 そこらへんは 複数 connecitionで回避してたわけです。 Operaの connectionの張り方なんてすごかった気がします。 最近はおとなしくなったんでしょうか。

HTTP/1.1 では client ごとに 2本だけの connectionにしとけよ! って 仕様にかかれていて、やっぱりこれを守りつつ multiplexしたい! というと PMMになっちゃったんでしょう。 っていういみでは、Poor Manじゃなくて、規約を守る Nice Man's Multiplexingって気もしますが。

どうやってやるかというと、Pipelining と Range requestを 駆使するんだと思います。多分。実験しないでかいて申し訳ありませんが。

Content{0, 1, 2} を擬似的に同時に取りたい場合、

  1. Content0 を先頭から 1KiB だけ
  2. Content1 を先頭から 1KiB だけ
  3. Content2 を先頭から 1KiB だけ
  4. つぎに Content0 を 1KiB目から 1KiB
  5. 以下続く
って感じに Pipeliningを使ってやるんだと思います。 試してませんが。

まあ、でもこれも Content2が重い CGIだったりすると stallする 可能性は大なので、労多くして益少なし、ってことで offになってるんでしょう。

まとめ

UMLGraphは便利だけど、いまどき PSを吐くので Pngにするのが面倒です。 ここら辺、自動的にやってくれないかなあ。

|

« Leopard (MacOS 10.5.1) の Windows shareの bug回避 | トップページ | Foneraの WLAN access pointが怪しい »

NetServices」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック


この記事へのトラックバック一覧です: Polipoが覗く HTTP/1.1の深淵(?)を UMLGraphで解説してみる:

» polipo、、、結構テキトーなのでは? [わかつも]
ぜんぜんソースも読まないし、ましてやインストールする気も無いのに、何故か気になるアイツ。 ちゃんとソース見てくれた人によると。 私もざっくりとしか見ていないので、断定はできかねるのですが、server.c で「らしい」処理が確認できます。 (中略) server-pipelin... [続きを読む]

受信: 2008年2月29日 (金) 09時51分

» 話題のProxyソフト「polipo」ちょっとだけまとめ [SmileStation]
最近話題になっているプロキシソフトpolipoをちょっとだけまとめてみました。 公式 http://www.pps.jussieu.fr/~jch/software/polipo/ polipoって何? はてな... [続きを読む]

受信: 2008年3月 1日 (土) 17時03分

« Leopard (MacOS 10.5.1) の Windows shareの bug回避 | トップページ | Foneraの WLAN access pointが怪しい »