HTTPでの要求でIMS(if-modified-since)というものがあります
ようはこんな感じのやりとりです
ブラウザ「今この日付でオブジェクトもってるんだけどこれって最新?使ってもいい?」
(If-Modified-Since: Sun,14 Feb 2010 03:01:19 GMT)
サーバ「最新だからそれ使ってもいいよ」
(304 Not Modified)
普通であればまったく問題ないやり取りです
ただトラフィックが非常に大きいサーバの場合深刻な問題になります
さっきのやり取りをもうちょい具体的にかくと
ブラウザ「今この日付でオブジェクトもってるんだけどこれって最新?使ってもいい?」
(If-Modified-Since: Sun,14 Feb 2010 03:01:19 GMT)
サーバ「ちょっとまってね(HDDのファイルの更新日時を調べる・・・)最新だからそれ使ってもいいよ」
(304 Not Modified)
もしくは
ブラウザ「今この日付でオブジェクトもってるんだけどこれって最新?使ってもいい?」
(If-Modified-Since: Sun,14 Feb 2010 03:01:19 GMT)
サーバ「ちょっとまってね(HDDのファイルの更新日時を調べる・・・)古いからこれ使って」
(200 OK で実ファイル転送)
いらないioが発生してしまいます
ioといってもファイルの更新日時程度なので少々ならまったく問題ないのですが非常に多いとそれだけでiowaitが大変なことに・・・
304で実ファイルは転送されないため見かけ上のトラフィックはさほど発生せずiowaitが発生してなんだろう?と悩むこともあるかも?
5/29にちょこっと修正しました(vcl_error追加)
ちなみにvarnishやsquidを間に挟んでいても
ブラウザ「今この日付でオブジェクトもってるんだけどこれって最新?使ってもいい?」
(If-Modified-Since: Sun,14 Feb 2010 03:01:19 GMT)
varnish「ちょっとまってね調べるわー」
(If-Modified-Since: Sun,14 Feb 2010 03:01:19 GMT)
バックエンドサーバ「それ更新してないよ」
(304 Not Modified)
varnish「最新だからそれ使ってもいいよ」
(304 Not Modified)
こんな感じのやりとりとなります
なので理想的には
ブラウザ「今この日付でオブジェクトもってるんだけどこれって最新?使ってもいい?」
(If-Modified-Since: Sun,14 Feb 2010 03:01:19 GMT)
varnish「持ってるの使っていいよ!」
(304 Not Modified)
とバックエンドにアクセスせずにvarnishに解決させたいです
ということで書き方はこんな感じでできます
sub vcl_recv { if(req.http.If-Modified-Since) { error 304; } } sub vcl_error{ return(deliver); }
IMS要求がきた場合無条件でそれ使っていいよと返していまします
なので同じファイル名で更新がある場合は多少の工夫が必要ですが
(スンゴク簡単だと更新日をクエリに付加するなど xxx.jpg?i=20100215012201)
一回作成したファイル名は再利用しないもしくはファイルのハッシュ値をとっている場合は有効に使えます
また内容が実質ないvcl_errorを書いてるのは304 Not Modifiedはレスポンスボディを含んではだめなためです
デフォルトだとボディをつけてくれるのでこのように書いています
304以外はエラー画面を使いたいというのであれば
sub vcl_error{ if (obj.status == 304) { return(deliver); } }
でもいいかなー