Varnish とは
- 正式名 Varnish HTTP Cache
- cache機能を持つリバースプロキシ
- 基本的にはcacheサーバとして使われる
- VCL - Varnish Configuration Language という独自言語で設定を行う
- 最新バージョンは6.0.2 (2018/11/12 Release)
VCLについて
- 手続き型言語
- これだけでIP制限やbasic認証をかけられたりと意外に器用
- 特定の処理ごとに、VCLに定義されたサブルーチンが呼びだされる(後述)
Varnishのcacheについて
- cacheは hash と呼ばれる領域に格納される
- すべてオンメモリなので高速(らしい
- デフォルトでは、hashのキーはリクエストのURLとドメイン/IPアドレス
- それとオリジンサーバの
Varyヘッダ
(後述) の組み合わせをキーにしてcacheが行われる
- それとオリジンサーバの
- 後述する
vcl_recv
でcacheの可否。vcl_hash
でhashのキーの定義ができる
Varyヘッダについて
- キャッシュサーバに対して、どのようにcacheを分けるかを指示するための情報
- オリジンサーバからのレスポンスヘッダに格納されている
- 例えば
Vary: Accept-Encoding
ならば、Varnish側のhashキーが同一でもAccept-Encoding
が異なるRequestは別の情報としてcacheされる
VCLでよく使う関数
- include: 別のvclファイルをincludeする
- set: 変数に値を格納する
- unset: 変数の値を削除する
- call: サブルーチンの呼び出し
VCLでよく使われる変数
サブルーチンによって、使えたり使えなかったりするので注意
- client : クライアントの情報
- server : サーバの情報
- req : クライアントからのリクエスト
- bereq : サーバに実際送るリクエスト
- beresp: サーバから帰ってきたレスポンスヘッダ
- resp: クライアントに返すレスポンスヘッダ
Varnishの処理の流れ
- Requestを受け取った時や、hashのキーを決定するときなど、それぞれのタイミングで サブルーチン が呼ばれる
- その サブルーチン を定義することで、独自の設定をVarnishに加えることができる
- サブルーチンの流れは、こちらの公式ドキュメントを参照
ざっくりした流れ
vcl_recv
- Requestを受けると最初に呼ばれるサブルーチン
- 主に、
hash
,pass
,pipe
のいずれかをreturn
の引数に入れる - hash : cacheする場合に選択。次はhashのキーを確定する
vcl_cache
が呼びだされる - pass : cacheしない場合に選択。次はpassした場合に呼び出される、
vcl_pass
が呼び出される - pipe: 処理をパイプ(キャッシュサーバは何もせず、クライアントとサーバの通信をパイプするだけ)する場合に選択。次はpipeした場合に呼び出される、
vcl_pipe
が呼び出される
- 主に、
vcl_pipe
vcl_recv
がreturn(pipe)
したら来る- あんまりいじることはない。長い処理の場合、タイムアウト値を変更したりする
vcl_pass
vcl_recv
がreturn(pass)
したら来る- passの場合だけリクエストヘッダをいじったりしたいときにはここに追記する
return(fetch)
すれば、オリジンサーバに問い合わせをする直前のサブルーチンvcl_backend_fetch
が呼び出される
vcl_hash
vcl_recv
がreturn(hash)
したら来る- hashのキーを定義する
- Varnishでは、cacheされたデータは hash に格納される
vcl_hash
では、そのhashを取り出すためのキーを定義する- 関数
hash_data
に値を追加していって、その値の組み合わせがキーになる - 最後に
return (lookup)
する - この後は、キーにhitするcacheがあれ
vcl_hit
。無ければ、vcl_miss
が呼び出される
参考
この場合、リクエストURLと、ホスト(もしくはipアドレス)の組み合わせがhashのキーとなっている
sub vcl_hash { hash_data(req.url); if (req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); } return (lookup); }
ここに、webサービスの特性に応じてhash_dataを設定していく
- スマホとPCでcacheを別にするとか
- ログインユーザ毎に異なるcacheを表示するとか
vcl_hit
- cacheがヒットした場合に呼び出される
return(deliver)
すれば、vcl_deliver
(cacheをクライアントにわたす直前のサブルーチン) が呼び出されるreturn(miss)
すれば、vcl_miss
(cacheがヒットしなかった場合のサブルーチン) が呼び出される
vcl_miss
- cacheがヒットしなかった場合に呼び出される
return(fetch)
すれば、オリジンサーバに問い合わせをする直前のサブルーチンvcl_backend_fetch
が呼び出される
vcl_backend_fetch
- オリジンサーバに問い合わせる直前のサブルーチン
- Requestを加工したりするのはここ
return(fetch)
すれば、オリジンサーバに問い合わせた後、vcl_backend_response
が呼び出される
vcl_backend_response
- オリジンサーバに問い合わせた後のサブルーチン
- Responseを加工したりするのはここ
return(deliver)
すれば、vcl_deliver
(cacheをクライアントにわたす直前のサブルーチン) が呼び出される
vcl_deliver
- クライアントに配信する直前のサブルーチン
vcl_hit
かvcl_backend_response
の後に呼び出されるreturn(deliver)
すると、クライアントにcacheが渡される
参考
👇 弊社blog記事。最初に読むと概要をつかみやすい
👇 v3.0.1 時代に作られたわかりやすい同人誌
👇 公式ドキュメントのサブルーチンの流れの解説
👇 公式ドキュメントのサブルーチンの解説