monolithic kernel

HTTPでVarnishのキャッシュをpurge

Varnishは標準でvarnishadmコマンドとtelnetによる管理が実装されていますが、VCLを少し記述するとHTTPで操作することもできます。認証がかけられないという問題はありますが、IPアドレスによる制限は可能ですし、Webアプリに組み込むのであればHTTPのほうが楽な気がします。

今回はWebアプリで使う頻度が高いであろうpurgeをHTTPから実行してみます。

VCLの記述

methodがPURGEのリクエストが送られてきた場合にはreq.urlをパスの正規表現と解釈してpurgeを行うように記述します。また、以下の例ではHostヘッダで対象とするVirtualHostを指定できるようにしています。

backend app {
.host = "127.0.0.1";
.port = "9000";
.connect_timeout = 30s;
}
// Access Control List
// 接続を許可するホストの一覧を記述している
acl purge {
"localhost";
}
sub vcl_recv {
if (req.request == "PURGE") {
// ~ 演算子を使うとACLに含まれるかどうかを判定できる
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
// パターンにマッチするキャッシュを削除する
purge("req.http.host == " req.http.host " && req.url ~ " req.url);
error 200 "Purged.";
}
elsif (req.http.host == "app.example.com") {
// purge以外の処理
set req.backend = app;
}
return(lookup);
}

コマンドラインからの呼び出し

Terminal window
curl -X PURGE -H 'Host: app.example.com' 'http://localhost:6081/posts/' -I
HTTP/1.1 200 Purged
Server: Varnish
Retry-After: 0
Content-Type: text/html; charset=utf-8
Content-Length: 451
Date: Sun, 16 Jan 2011 06:35:25 GMT
X-Varnish: 528212595
Age: 0
Via: 1.1 varnish
Connection: close

Rubyからの呼び出し(Net::HTTP)

require 'net/http'
class Net::HTTP
class Purge < Net::HTTPRequest
METHOD = 'PURGE'
REQUEST_HAS_BODY = false
RESPONSE_HAS_BODY = true
end
end
Net::HTTP.start('localhost', 6081) do |http|
req = Net::HTTP::Purge.new('/posts/')
req['Host'] = 'app.example.com'
p http.request(req)
end

Rubyからの呼び出し(EventMachine)

EventMachineのほかにEM-HTTP-Requestを使っています。

require 'eventmachine'
require 'em-http'
class EventMachine::HttpRequest
def purge(options = {}, &block)
setup_request(:purge, options, &block)
end
end
EventMachine.run do
http = EventMachine::HttpRequest.new('http://localhost:6081/posts/').purge(:head => { 'Host' => 'app.example.com' })
http.callback do
p http.response
EventMachine.stop_event_loop
end
http.errback do
p http.response
EventMachine.stop_event_loop
end
end

参考