あんまり話題に上らないで個人的に悔しいVarnishのESI(Edge Side Include)ですが
非常に癖がありますのではまりやすいポイントをとりあえず自分用のメモ程度に
2010/06/23追記:Ver2.1.2では多少注意事項が変わっていますのでこちらも参照ください
そもそもESIってなに?
ページは様々な要素で構成されていますが大きく分けて二つに分かれます
表示される度に更新しなくてはいけないもの(広告・タイムライン)
表示される度に更新しなくてもいいもの(フォロワーなどの数)
別にフォロワー数を表示するためにPHPを動かして、DBかmemcacheにアクセスして整形して・・・
といった処理をしてもいいのですが
PVが多いWEBサイトの場合、毎回呼ばれる処理はできるだけしたくありません
PHP→memcacheとしても負荷が結構痛いです
そういう時にESIがあると、ページの構成要素ごと キャッシュを行い、Varnish側で組み立てて返却してくれます
PHPやDBまでアクセスがこないので負荷に強くなるとともに、そのキャッシュした構成要素を別の画面で再利用できます
PC向けの場合Ajaxなどもあるので、一概にESIがすごく有効とも言い辛いのですが(例でTwを上げましたがちょっと悪かったかも)
携帯向けなどJSが使えない環境で、毎回一枚のHTMLを出力しないといけない場合非常に効果的です
また転送速度が上がるのでPVが上がるかも しれませんしSEOにも効果がありそうです
(Googleはどれぐらいでページが表示されるかをSEOの評価としてるみたいです)
Keep-AliveはOFFにするべき
ESI使用時はcontent-lengthがブラウザ側に返却されないようなのでOFFはほぼ必須です
どうしても使いたい場合はESIを使用するときのみkeep-aliveをOFFに・・・
TTLの指定はデフォルトだとできない
もともとESIはAkamaiやオラクルなどが作ったのですがオラクルの技術資料をみると
<esi:include src="xxx.html" max-age=10 />
といかにもページごとにTTL(キャッシュ時間)を指定できそうですがVarnishではできません
じゃぁどうすればいい?
<esi:include src="/esi/max-age/10s/index.php"/>
のように適当にURLを作ってやってreq.urlを評価してobj.ttlを設定してあげればOKです
またバックエンドへリクエストを投げる際はbereq .urlから/esi/max-age/10sを抜いて上げる必要があります
直Varnishはやめた方がいい
Keep-aliveをオフにしても特定のクライアント(ab/wgetなど)で接続が維持されて5秒ほど待ってしまうことがあります
つまりKeep-Aliveが有効かつcontent-lengthがないときの挙動と同じになります
じゃぁどうすればいいか?
自分はフロントにNginxを置いてそこからVarnishにproxyしています
ログ取得には工夫が必要
キャッシュされるので PHPなどが動いてるApacheにたいして必ずアクセスがあるとは限りません
じゃぁVarnishでログをとればいい?
varnishncsaというのもあるのですがログがカスタマイズできないうえ(ソースを直接いじればカスタムは可能です)
バックエンドへのリクエストやらESIへのアクセスもログしてしまうのでカオスになりがちです
素直にフロントにNginxやApacheをおいてそこでログをとるべきでしょう
なんかNo ESI processing, first char not ‘< ‘とかいうエラーがでる
/etc/sysconfig/varnishの起動コマンドに
-p esi_syntax=0x1
と追加してみましょう
たいてい動くようになります
正直varnishのESIはとりあえず実装してみました!
という匂いが個人的にはプンプンしますので非常に癖があります
max-ageぐらい指定できるとありがたいんですがねー
参考
Varnish公式