社内勉強会資料(Varnish Module)

35
Varnish Cache ことはじめ 2012/07/20 技術統括部 いわなちゃん(@xcir)

description

7/20に社内勉強で発表したいろんなVMODの紹介資料ほとんど口頭なので参考程度に・・・

Transcript of 社内勉強会資料(Varnish Module)

Page 1: 社内勉強会資料(Varnish Module)

Varnish Cacheことはじめ

2012/07/20技術統括部

いわなちゃん(@xcir)

Page 2: 社内勉強会資料(Varnish Module)

Varnishの特徴

● コンテンツのキャッシュ

● Cライクなドメイン言語VCLによる柔軟な制御

● むしろVCL中にC言語が書ける(インラインC)● 高速なリバースプロキシ

● フラグメントキャッシュなESIへの対応

● ロードバランシングとヘルスチェックが可能

● gzipの圧縮解凍が可能

うちでは主に静的コンテツに使ってます

Page 3: 社内勉強会資料(Varnish Module)

とまぁ細かい点は

僕のブログにあるVarnishCache入門をご覧ください(ステマ)

http://blog.xcir.net/

Page 4: 社内勉強会資料(Varnish Module)

VCLでできること・できないこと

● できること● 条件分岐● 数値演算・文字列操作(結合・正規表現)

● できない・難しいこと● 文字列から数値への変換● 時刻計算● Base64などの符号化やハッシュ作成

● バックエンドからのResponseヘッダを除く外部のリソースを取得すること

設定ファイルとしては非常に柔軟だが微妙に痒いところがある

Page 5: 社内勉強会資料(Varnish Module)

VCLのサンプル

sub vcl_recv{ //クライアントからのレスポンスを受け取る if(req.url ~ "(\?|&)purge=1" && client.ip ~ local){//キャッシュ削除 ban("obj.http.X-HOST ~ "+ req.http.host + " && obj.http.X-URL ~ " + regsub(req.url,"\?.*$","")); error 200 "banned."; } //admin/以外のクッキー削除 if(req.http.Cookie && !(req.http.host ~ "^blog.example.net" && req.url ~ "^/admin/")){ unset req.http.Cookie; } if(req.http.host ~ "^blog.example.net"){ set req.backend = blog; if( ! req.backend.healthy){ //blog 死亡 set req.backend = cdn; //blog 死亡のためcdn/sorry.htmlに向ける set req.url = "/sorry.html"; }elseif(req.url ~ "^/admin/"){ //admin はキャッシュしない return(pass); } }elseif(req.http.host ~ "^cdn.example.net"){ set req.backend = cdn; }else{//不明なホストは403 error 403 "Forbidden"; } return(lookup);}

Page 6: 社内勉強会資料(Varnish Module)

インラインCでできること・できないこと

● できること● Cでできることなら大抵できる

● できない・難しいこと● セッション跨いだをデータの維持

– コストの高いデータを初期化しても次のセッションでまた初期化する必要が・・・

● Varnish本体側の各種関数や変数へのアクセス– 重要な構造体のメンバにアクセスできなかったり・・・

Page 7: 社内勉強会資料(Varnish Module)

Inline-Cのサンプルmemcachedに接続

C{#include <stdlib.h>#include <stdio.h>#include <libmemcached/memcached.h>void mctest(char *k ,char *v){ struct memcached_st *mmc = NULL; struct memcached_server_st *servers = NULL; memcached_return rc; mmc = memcached_create(NULL); servers = memcached_server_list_append(servers,"localhost", 11211, &rc); rc = memcached_server_push(mmc, servers); memcached_server_list_free(servers); rc = memcached_set(mmc, k, strlen(k), v, strlen(v), 600, 0); memcached_free(mmc);}}Csub mcSet{if(req.http.X-mck && req.http.X-mcv){C{char *key=VRT_GetHdr(sp,HDR_REQ,"\006X-mck:");char *value=VRT_GetHdr(sp,HDR_REQ,"\006X-mcv:");mctest(key,value);}C}remove req.http.X-mck;remove req.http.X-mcv;}sub vcl_recv{set req.http.X-mck = "Last:req.xid";set req.http.X-mcv = req.xid;call mcSet;

Page 8: 社内勉強会資料(Varnish Module)

へ(^o^)へ わーい設定に   |へ   /

(^\ o^ )へ インラインでCが書けるぞー  \|   >

( ^< o^) > よっしゃ複雑な処理を・・・ 三) )三< ̄ ̄>

Σ ( ^o^) <) )>グキッ< ̄ ̄>

_人人 人人_> 突然の死 < ̄Y^Y^Y^Y ̄

VCLコード中のちょっとした日付演算などにはいいけど大規模なコードを書くには向かない

VCL中にコードを書くため配布もしづらい

インラインCだけだと正直キツイ

Page 9: 社内勉強会資料(Varnish Module)

Varnish Module(VMOD)ことはじめ

2012/07/20技術統括部

いわなちゃん(@xcir)

Page 10: 社内勉強会資料(Varnish Module)

VMODでできること・できないこと

● できること● Cでできることなら大抵

● セッションを跨いだデータの保持● Varnish本体の各種関数や変数へのアクセス

● できないこと● あまりない

モジュール形式なので配布もしやすいし使いやすい

Page 11: 社内勉強会資料(Varnish Module)

VMODのサンプルmemcachedに接続

■vcc vmod( のヘッダファイルみたいなもの)Function VOID mcset(STRING,STRING)

■c#include <stdlib.h>#include <stdio.h>#include <libmemcached/memcached.h>void vmod_mcset(struct sess *sp, const char *k ,const char *v){ struct memcached_st *mmc = NULL; struct memcached_server_st *servers = NULL; memcached_return rc; mmc = memcached_create(NULL); servers = memcached_server_list_append(servers, "localhost", 11211, &rc); rc = memcached_server_push(mmc, servers); memcached_server_list_free(servers); rc = memcached_set(mmc, k, strlen(k), v, strlen(v), 600, 0); memcached_free(mmc);}

■VCLexample.mcset("Last:req.xid",req.xid);

Page 12: 社内勉強会資料(Varnish Module)

いろんなVMODの紹介

● 公式でリストされているVMODを紹介します

● https://www.varnish-cache.org/vmods● 紹介しているサンプルコードは基本的に

ドキュメントから拾って改変してます● 流石に全部動作確認する時間はなかったので

動かないかも

● 明らかに動かないものは省いてます

試しに使ってみたいものがあれば聞いてみてください

Page 13: 社内勉強会資料(Varnish Module)

Authentication● Basic認証を行うモジュール

ID/PWを固定で簡単に認証を入れたい時は便利● Developed by Omega Software Development Group

● https://github.com/omegasdg/libvmod-authentication

サンプルコードimport authentication;

vcl_recv{ if(req.url ~ "^/protected/") { if(!authentication.match("admin", "test")) { error 401 "Authentication Required"; } }}vcl_error{ if (obj.status == 401) { set obj.http.WWW-Authenticate = {"Basic realm="Authorization Required""}; synthetic {"Error 401 Unauthorized"}; return(deliver); }}

Page 14: 社内勉強会資料(Varnish Module)

crashhandler● セグフォを起こしてバックトレースを取得する

VMODやインラインCでのデバッグに使う● Developed by Kristian Lyngstøl

● https://github.com/varnish/libvmod-crashhandler

サンプルコードimport crashhandler;

vcl_recv{ if(req.url ~ "^/crash/") { crashhandler.crash(); }}

Page 15: 社内勉強会資料(Varnish Module)

cURL● VCL中にHTTPで他リソースを取得する

APIを叩いてその結果のような使い方ができるかも● Developed by Varnish Software

● https://github.com/varnish/libvmod-curl

サンプルコードimport curl; sub vcl_recv { curl.fetch("http://example.com/test"); if (curl.header("X-Foo") == "bar") { … } curl.free(); }

Page 16: 社内勉強会資料(Varnish Module)

dClass OpenDDR (decision classification)

● UAからデバイス情報を取得する(OpenDDR)ぱっと見た感じディスプレイサイズなども取得可能

● Developed by Weather Channel

● https://github.com/TheWeatherChannel/dClass

サンプルコードimport dclass;sub vcl_init {

dclass.init_dclass("/some/path/OpenDDR/1.0.0.0/resources");dclass.init_dclass_p("/some/path/dClass/dtrees/browser.dtree",1);

}

sub vcl_recv {set req.http.dclass_openddr = dclass.classify(req.http.user-agent);set req.http.dclass_browser = dclass.classify_p(req.http.user-agent,1);

if(dclass.get_ifield("displayWidth") > 320){....

}}

Page 17: 社内勉強会資料(Varnish Module)

DeviceAtlas Mobile Detection● モバイルデバイスの各種情報を取得

● Developed by Varnish Software

● Varnishソフトウェアが有償で提供しています

● https://www.varnish-cache.org/vmod/deviceatlas-mobile-detection

Page 18: 社内勉強会資料(Varnish Module)

Digest● HMAC-sha1などダイジェストやBase64が扱える

SHA1などのDigestの出力はHEXエンコードされているので注意

● Developed by Kristian Lyngstøl

● https://github.com/varnish/libvmod-digest

サンプルコードimport digest;

sub vcl_recv { if (digest.hmac_sha256("key",req.http.x-some-header) != digest.hmac_sha256("key",req.http.x-some-header-signed)) { error 401 "Naughty user!"; }}

Page 19: 社内勉強会資料(Varnish Module)

example vmod - hello world!● VMODを作るときに参考になります

● Developed by Martin Blix Grydeland

● https://github.com/varnish/libvmod-example

サンプルコードimport example;

sub vcl_deliver { # This sets resp.http.hello to "Hello, World" set resp.http.hello = example.hello("World");}

Page 20: 社内勉強会資料(Varnish Module)

Header manipulation● ヘッダーの操作を行うモジュール

主にクッキーの値の追加や削除を行う● Developed by Kristian Lyngstøl

● https://github.com/varnish/libvmod-header

サンプルコードimport header;

sub vcl_fetch { header.append(beresp.http.Set-Cookie,"foo=bar"); header.remove(beresp.http.Set-Cookie,"dontneedthiscookie");}

Page 21: 社内勉強会資料(Varnish Module)

Memcached● Memcacheへ値のset/get/incrなどを行う

● Developed by Aaron Stone

● https://github.com/sodabrew/libvmod-memcached

サンプルコードimport memcached; sub vcl_deliver { memcached.servers("localhost"); memcached.set("your_counter", "1", 100, 0); memcached.incr("your_counter", 10); set resp.http.count = memcached.incr("your_counter", 1);}

Page 22: 社内勉強会資料(Varnish Module)

null - Binary data in synthetic● バイナリデータを送信したいときに利用

vcl_errorでインラインCから使うのが一般的● Developed by Kristian Lyngstøl

● https://github.com/varnish/libvmod-header

サンプルコードimport null;

sub vcl_error { C{ Vmod_Func_null.synth(sp,"TEST",4); }C return(deliver);}

Page 23: 社内勉強会資料(Varnish Module)

POST/GET/Cookie parse● POST/GET/Cookieの内容をパースする

● Developed by

● https://github.com/xcir/libvmod-parsereq

サンプルコードimport parsereq;

vcl_recv{ if(parsereq.post_header("hoge")){ ... }}

わ た し で す    / ̄\      | ^o^ |     \_/   

Page 24: 社内勉強会資料(Varnish Module)

redirect● Varnishのめんどくさいリダイレクトを簡単にする

● Developed by

● https://github.com/xcir/libvmod-redirect

サンプルコードimport redirect;

sub vcl_recv { if (req.http.user-agent ~ "iP(hone|od)") { error(redirect.location(302,"http://www.example.com/iphoneversion/") , "Moved Temporarily"); }}

わ た し で す    / ̄\      | ^o^ |     \_/   

Page 25: 社内勉強会資料(Varnish Module)

Redis● Redisにコマンドを送信する

● Developed by ZephirWorks

● https://github.com/zephirworks/libvmod-redis

サンプルコードimport redis;sub vcl_init{ redis.init_redis("localhost", 6379, 200); }sub vcl_recv { redis.send("LPUSH client " + client.ip); set req.http.x-redis = redis.call("LTRIM client 0 99");}

Page 26: 社内勉強会資料(Varnish Module)

Secure download● Nginxやlighttpdにもある特定の時間まで有効な

使い捨てURL機能を実現する● Developed by Aurelien Guillaume

● https://github.com/footplus/libvmod-secdown

サンプルコードimport secdown;

sub vcl_recv { if (req.url ~ "^/protected/") { set req.url = secdown.check_url(req.url, "h4ckme", "/expired.html", "/error.html") }}

Page 27: 社内勉強会資料(Varnish Module)

Shield● クライアントの接続を即切断する機能

dDoS攻撃などの対策に使う● Developed by Martin Blix Grydeland

● https://github.com/varnish/libvmod-shield

サンプルコードimport shield;

sub vcl_recv { if (req.url ~ "i-am-an-attacker") { shield.conn_reset(); }}

Page 28: 社内勉強会資料(Varnish Module)

std - the standard VMOD● VCL中からログ出力を行うなどの基本的なVMOD

VMODのサンプルコード的な役割も● Developed by Per Buer

● 標準でインストールされます

サンプルコードimport std;

sub vcl_recv { std.log(“hogehoge”);}

Page 29: 社内勉強会資料(Varnish Module)

URL Code● URLエンコード・デコードを行う

● Developed by Fastly Inc

● https://github.com/fastly/libvmod-urlcode

サンプルコードimport urlcode;

sub vcl_recv { set req.url = "/example?url=" + urlcode.encode("http://" + req.http.host + req.url);}

Page 30: 社内勉強会資料(Varnish Module)

URL Sort● URLのクエリをソートしてクエリの順番が違うだけ

で別のキャッシュにならないように正規化する● Developed by Fastly Inc

● https://github.com/cyberroadie/varnish-urlsort

サンプルコードimport urlsort;

sub vcl_recv { set req.url =urlsort.sortquery(req.url);}

Page 31: 社内勉強会資料(Varnish Module)

Variable Support● 文字列・整数・実数が扱える変数を提供する

● Developed by Varnish Software

● https://github.com/varnish/libvmod-var

サンプルコードimport var;

sub vcl_recv {

if (req.http.user-agent ~ iP(od|ad|hone) ) { set var.set_int("idevs", var.get_int("i1") + 1 ); }}

Page 32: 社内勉強会資料(Varnish Module)

いろいろVMODが存在

● 公式でリストされてないものだと● LDAP認証

● Firewall● などなど

これらを使うことでより高度なVarnishライフが・・・

Page 33: 社内勉強会資料(Varnish Module)

それでも欲しい機能がないなら・・・

Page 34: 社内勉強会資料(Varnish Module)

VMODを作ってみよう

僕のブログにあるinline-C/VMODガイドブック

をご覧ください(ステマ)

Page 35: 社内勉強会資料(Varnish Module)

ご清聴ありがとうございました