Hatena::ブログ(Diary)

Yet Another Hackadelic

2007-08-20 ねれねーよ

X-REPROXY-CACHE-FORを使いたい人向けショートBK

id:tokuhiromさんとかid:precuredaisukiさんとか既知だろうけども。。。

CREATE SERVICE balancer
  SET listen          = 0.0.0.0:81
  SET role            = reverse_proxy
  SET pool            = myclusters
  SET persist_client  = on
  SET persist_backend = on
  SET verify_backend  = on
  SET enable_reproxy  = true
  SET reproxy_cache_maxsize = 1048576
ENABLE balancer

このreproxy_cache_maxsizeを忘れると見事にX-REPROXY-CACHE-FORがスルーされるので激しく注意!

ってのも、Perlbal::Serviceの中で、

    'reproxy_cache_maxsize' => {
        des => "Set the maximum number of cached reproxy results (X-REPROXY-CACHE-FOR) that may be kept in the service cache. These cached requests take up about 1.25KB of ram each (on Linux x86), but will vary with usage. Perlbal still starts with 0 in the cache and will grow over time. Be careful when adjusting this and watch your ram usage like a hawk.",
        default => 0,
        check_role => "reverse_proxy",
        check_type => "int",
        setter => sub {
            my ($self, $val, $set, $mc) = @_;
            if ($val) {
                $self->{reproxy_cache} ||= Perlbal::Cache->new(maxsize => 1);
                $self->{reproxy_cache}->set_maxsize($val);
            } else {
                $self->{reproxy_cache} = undef;
            }
            return $mc->ok;
        },
    },

と合って、この設定が有効になっていないとそもそもPerlbal::Cacheのインスタンス自体作られないからでした。

見事にはまったー。

2006-12-12 風雲急

Catalyst-View-Reproxyをリリースしました

というわけでX-REPROXY_URL, X_REPROXY_FILE, X_Sendfileヘッダーを吐いたしてくれるViewクラスってのを作りました。

なんでViewなんですかと言えば、デバッグ時にフロントにPerlbal, Lighttpdじゃなかったりする場合にはLWPで取ってきたりしちゃうよーってのと、将来的にMogileFSのFileを吐き出すViewってを作りたかったんで、こいつを先に作ってみようかなと。

実はもう少しテストの内容だとか修正したかったんですけど、本業の方がアレなのでひとつ大人の事情でアレでナニな訳です。(ぇ


とりあえずPODがおかしいのでそれは直します。ほんとごめんなさい。

2006-12-08 先ほど

X-SendFile, X-REPROXY-FILE, X-REPROXY-URLを試してみる

  • lighttpd : 1.4.13
  • perlbal : 1.53

で試してみました。

一応簡単なノート

X-SendFile

id:typesterさんのCatalyst::Plugin::XSendFileを使いました。

sub index: Private {
    my ($self, $c) = @_;

    $c->res->sendfile('/path/to/file');
}

こんなんで普通にファイルが出力されるんですけども、この時注意しなければいけないのは、Content-TypeもContent-Lengthも出力されないって事です。

自前で$c->res->content_type, $c->res->content_lengthに値を設定する必要があります。

これに関しては後述のX-REPROXY-FILE, X-REPROXY-URLも同じ事が言えます。

X-REPROXY-FILE, X-REPROXY-URL

こちらに関しては次のように使います。

X-REPROXY-FILE: /path/to/file
X-REPROXY-URL: http://mydomain/path/to/file

このようなレスポンスヘッダーがあればPerlbalの方で、出力してくれます。

Content-Type, Content-Lengthに関してはX-SendFileと同様です。

perlbalの設定は凄い簡単にやりました。

/etc/perlbal/perlbal.confにて、

CREATE POOL dynamic
  POOL dynamic ADD 127.0.0.1:80

CREATE SERVICE balancer
  SET listen          = 0.0.0.0:8080
  SET role            = reverse_proxy
  SET pool            = dynamic
  SET persist_client  = on
  SET persist_backend = on
  SET verify_backend  = on
  SET enable_reproxy  = true
ENABLE balancer

SET enable_reproxyをtrueにしておかないとX-REPROXY-*は使えません。

Catalyst側では、

$c->res->header('X-REPROXY-URL', join(" " => 
    "http://mydomain1/path/to/file",
    "http://mydomain2/path/to/file"
));

なんて感じで吐き出せば、このノードリストのいずれかからファイルを取ってきてくれます。


ちなみにX-REPROXY-EXPECTED-SIZEヘッダーを付けると、

期待どおりのファイルサイズが取れない場合はエラーって扱いに出来るみたいです。

正しい場合はContent-Lengthヘッダーを付けてレスポンスを返してくれるのを確認しました。

まとめ

X-REPROXY-*を使う時はX-REPROXY-EXPECTED-LENGTHを併用するのが吉かと。

Content-Typeに関しては、何らかの形で事前に取得しといて自前で設定しないとダメだと思います。


X-Sendfile, X-REPROXY-FILE, X-REPROXY-URL

d:id:spiritloose:20061025:1161770915

ApacheでもlighttpdのX-Sendfileが使えるみたい。

ここで言及されてるX-REPROXY-FILEなんだけど、Perlbalの機能です。

付属のdocにあるreproxying.txtによると、

This can be useful for having URLs that get mapped to files on disk without

giving users enough information to map out your directory structure. For

example, you can create a file structure such as:

/home/pics/$userid/$pic

Then you can have URLs such as:

http://foo.com/mysite/users/$userid/picture/$pic

When this URL gets passed to the backend web node, it could return a simple

response that includes this header:

X-REPROXY-FILE: /home/pics/$userid/$pic

Perlbal will then use asynchronous IO to send the file to the user without

slowing down Perlbal at all.

とあるので、ちとlighttpdのX-Sendfileを勘違いしてる鴨ですが、

単純にPerlbalがアクセス可能なファイルシステムに対するPATHを記述すると

Perlbalが代理でファイルの内容を取得して返すってだけじゃないのかなぁ。。。

だから僕の理解*1だとX-Sendfile = X-REPROXY-FILE なんだけどどうすかね。

MogileFSとの組み合わせだと最強だと思われるのが、X-REPROXY-URLですかね。

This support also extens to URLs that can be located anywhere Perlbal has

access to. It's the same syntax, nearly:

X-REPROXY-URL: http://foo.com:80/resource.html

You can also specify multiple URLs:

X-REPROXY-URL: http://foo.com:80/resource.html http://baz.com:8080/res.htm

Just specify any number of space separated URLs. Perlbal will request them

one by one until one returns a response code of 200. At that point Perlbal

will proxy the response back to the user just like normal.

って訳でバックエンドのストレージノードのURLを列挙してあげれば、

代わりに取りに行ってくれるって理解で合ってるはず。


ちとそのうち試して追って報告するです。(誰?

*1:まだ未検証だけどもw