VarnishをHTTP サーバとして使ってみる

varnish
特定の URL へのリクエストに対して、Varnish が HTTP ステータス 200 で固定メッセージを返す設定を Varnish 3/4 向けにメモ。

これを実現するための基本的なアイデアは、HTTP リクエストのエラー処理で利用することの多いキーワード error(Varnish 3)/synth(Varnish 4) を 200番台のような正常系 HTTP レスポンスステータスでも活用すること。

ゴール

Varnish 3 向け設定

error code reason でサブルーチン vcl_error に飛ばし、vcl_error ではステータスに応じてレスポンスを書き換える。
メッセージボディーは synthetic を使う

sub vcl_recv {
  ...
  # respond HTTP 200 to /ping requests
  if (req.url ~ "^/ping") {
    error 700;
  }
  # return a 301 redirect
  if (req.url ~ "^/wrong-target") {
    error 751 "http://www.example.com/correct-target";
  }
}

sub vcl_error {
  # send response "Pong" (HTTP 200)
  if (obj.status == 700) {
    set obj.status = 200;
    set obj.response = "OK";
    set obj.http.Content-Type = "text/plain";
    synthetic {"Pong"};
    return (deliver);
  }

  # redirect 301
  if (obj.status == 751) {
    set obj.http.Location = obj.response;
    set obj.status = 301;
    set obj.response = "Moved Permanently";
    return (deliver);
  }

  # deliver all other exceptions
  return (deliver);
}

Varnish 3 向けの設定はWeb上にサンプルがたくさん転がっているので、それほど悩まなくて済むはず。
エラーメージの生成は次のリンクが参考になる

http://blog.tenya.me/blog/2012/06/25/varnish-3-dot-x-custom-error-pages/

Varnish 4 向け設定

vcl 4 はリリースしてまもないので、やる気の感じられない公式ドキュメントを参考にするしか無い。

vcl 3 vs vcl 4

vcl 3 系の error は vcl 4 系で廃止され、かわりに synth(code, reason) でサブルーチン vcl_synth に飛ばし(明示的に return すること)、vcl_synth ではステータスに応じてレスポンスを書き換える。

vcl 3 系の vcl_erro

  • vcl_synth : Varnish 内で synth(code, reason) で生成された HTTP ステータス
  • vcl_backend_error : バックエンドサーバで生成された HTTP ステータス

に分割された模様。

vcl_errorobj.xxxvcl_synth では resp.xxx に変わった。

メッセージボディーは vcl 3 系と同じく synthetic を使う

以上をまとめた VCLが以下

vcl 4.0;

backend default {
    .host = "127.0.0.1";
    .port = "8080";
}

sub vcl_recv {
    if (req.url ~ "^/ping") {
        return (synth(700, "Ping"));
    }

    if (req.url ~ "^/wrong-target") {
        return (synth(751, "http://www.example.com/correct-target"));
    }
}

sub vcl_synth {
    set resp.http.Retry-After = "5";
    if (resp.status == 700) {
        set resp.status = 200;
        set resp.reason = "OK";
        set resp.http.Content-Type = "text/plain;";
        synthetic( {"Pong"} );
        return (deliver);
    }

    if (resp.status == 751) {
        set resp.http.Location = resp.reason;
        set resp.status = 301;
        set resp.reason = "Moved Permanently";
        return (deliver);
    }

    return (deliver);
}

sub vcl_backend_response {
    # Happens after we have read the response headers from the backend.
    #
    # Here you clean the response headers, removing silly Set-Cookie headers
    # and other mistakes your backend does.
}

sub vcl_deliver {
    # Happens when we have all the pieces we need, and are about to send the
    # response to the client.
    #
    # You can do accounting or modifying the final object here.
}

References

Advertisements
Tagged with: , ,
Posted in middleware, web

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
%d bloggers like this: