varnishでbackendのapacheにPOSTしているときにたまに(1/1000ぐらい)503 Service Unavailable になる現象はpassをpipeに変えたら出なくなった
これも同じような感じ?
backendの設定とbackendに投げる設定のvclはこんな感じ(抜粋)
- backend
probe healthcheck { .url = "/index.html"; .interval = 30s; .timeout = 10s; .threshold = 3; .window = 3; .expected_response = 200; } backend apache1 { .host = "192.168.0.1"; .port = "80"; .probe = healthcheck; .connect_timeout = 60s; .first_byte_timeout = 60s; .between_bytes_timeout = 60s; } backend apache2 { .host = "192.168.0.2"; .port = "80"; .probe = healthcheck; .connect_timeout = 60s; .first_byte_timeout = 60s; .between_bytes_timeout = 60s; } director apache fallback { { .backend = apache1; } { .backend = apache2; } }
- default.vcl
sub vcl_recv { (中略) if (req.url ~ "^/(foo|bar)") { set req.backend = apache; return (pass); } return (lookup); }
で、このときに携帯からapacheへPOSTするときに1/1000 ぐらいの頻度で503になってた。そのときのvarnishlog を見ていると以下のようなものが流れている。varnishlog にはbackend write error と出ているが、backendのapacheのログにはerrorらしきものは見当たらない。
66 Hash c varnish.example.com 66 VCL_return c hash 66 VCL_call c pass pass 66 Backend c 25 apache apache1 66 FetchError c Resource temporarily unavailable 66 FetchError c backend write error: 11 (Resource temporarily unavailable) 66 VCL_call c error restart 66 VCL_call c recv pass 66 VCL_call c error deliver 66 VCL_call c deliver deliver 66 TxProtocol c HTTP/1.1 66 TxStatus c 503 66 TxResponse c Service Unavailable 66 TxHeader c Server: Varnish 66 TxHeader c Content-Type: text/html; charset=utf-8 66 TxHeader c Retry-After: 5 66 TxHeader c Content-Length: 366 66 TxHeader c Accept-Ranges: bytes 66 TxHeader c Date: Tue, 28 May 2013 04:38:12 GMT 66 TxHeader c X-Varnish: 1888567253
passとpipeの違い
xcirさんのvarnish cache 入門からの引用
pipe クライアントとバックエンド間のコネクションが閉じられるまで、継続的に スルーします。Varnish は内容に対する操作は行いませんし、キャッシュも 行いません。単純に右から左へ通信を中継するだけです。 pass Varnish はキャッシュしません。しかし、返却時にレスポンスヘッダに追加 で項目を加えるなどの操作は可能です。
curl などで見てみるとたしかにpassの場合はvarnishのヘッダが追加されている。
- pass の場合
$ curl -I http://varnish.example.com/foo/ HTTP/1.1 200 OK Server: Apache Content-Type: text/html Accept-Ranges: bytes Date: Tue, 28 May 2013 14:50:04 GMT X-Varnish: 1889133345 Age: 0 Via: 1.1 varnish Connection: keep-alive
- pipe の場合
$ curl -I http://varnish.example.com/foo/ HTTP/1.1 200 OK Date: Tue, 28 May 2013 14:51:56 GMT Server: Apache Connection: close Content-Type: text/html
追記
pipe を使うと、そのリクエストはvarnishncsa ログに記録されなくなっていることに気づいた。
tcpのコネクションを丸投げしてるだけでvarnishは何もしていないから?
というわけでログを残す必要がある場合はやっぱりpassを使わないといけない。