Advertisement
Advertisement

More Related Content

Similar to 社内勉強会資料(Varnish Module)(20)

Advertisement

社内勉強会資料(Varnish Module)

  1. Varnish Cache ことはじめ 2012/07/20 技術統括部 いわなちゃん(@xcir)
  2. Varnishの特徴 ● コンテンツのキャッシュ ● Cライクなドメイン言語VCLによる柔軟な制御 ● むしろVCL中にC言語が書ける(インラインC) ● 高速なリバースプロキシ ● フラグメントキャッシュなESIへの対応 ● ロードバランシングとヘルスチェックが可能 ● gzipの圧縮解凍が可能 うちでは主に静的コンテツに使ってます
  3. とまぁ細かい点は 僕のブログにある VarnishCache入門をご覧ください(ステマ) http://blog.xcir.net/
  4. VCLでできること・できないこと ● できること ● 条件分岐 ● 数値演算・文字列操作(結合・正規表現) ● できない・難しいこと ● 文字列から数値への変換 ● 時刻計算 ● Base64などの符号化やハッシュ作成 ● バックエンドからのResponseヘッダを除く 外部のリソースを取得すること 設定ファイルとしては非常に柔軟だが 微妙に痒いところがある
  5. 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); }
  6. インラインCでできること・できないこと ● できること ● Cでできることなら大抵できる ● できない・難しいこと ● セッション跨いだをデータの維持 – コストの高いデータを初期化しても 次のセッションでまた初期化する必要が・・・ ● Varnish本体側の各種関数や変数へのアクセス – 重要な構造体のメンバにアクセスできなかったり・・・
  7. 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); } }C sub 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;
  8. インラインCだけだと正直キツイ へ(^o^)へ わーい設定に    |へ   / \(^o^ )へ インラインでCが書けるぞー   \|    > <( ^o^)> よっしゃ複雑な処理を・・・  三) )三 < ̄ ̄> Σ ( ^o^)  <) )>グキッ < ̄ ̄> _人人 人人_ > 突然の死 <  ̄Y^Y^Y^Y ̄ VCLコード中のちょっとした日付演算などには いいけど大規模なコードを書くには向かない VCL中にコードを書くため配布もしづらい
  9. Varnish Module(VMOD) ことはじめ 2012/07/20 技術統括部 いわなちゃん(@xcir)
  10. VMODでできること・できないこと ● できること ● Cでできることなら大抵 ● セッションを跨いだデータの保持 ● Varnish本体の各種関数や変数へのアクセス ● できないこと ● あまりない モジュール形式なので配布もしやすいし 使いやすい
  11. 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); } ■VCL example.mcset("Last:req.xid",req.xid);
  12. いろんなVMODの紹介 ● 公式でリストされているVMODを紹介します ● https://www.varnish-cache.org/vmods ● 紹介しているサンプルコードは基本的に ドキュメントから拾って改変してます ● 流石に全部動作確認する時間はなかったので 動かないかも ● 明らかに動かないものは省いてます 試しに使ってみたいものがあれば 聞いてみてください
  13. 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); } }
  14. crashhandler ● セグフォを起こしてバックトレースを取得する VMODやインラインCでのデバッグに使う ● Developed by Kristian Lyngstøl ● https://github.com/varnish/libvmod-crashhandler サンプルコード import crashhandler; vcl_recv{ if(req.url ~ "^/crash/") { crashhandler.crash(); } }
  15. 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(); }
  16. 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){ .... } }
  17. DeviceAtlas Mobile Detection ● モバイルデバイスの各種情報を取得 ● Developed by Varnish Software ● Varnishソフトウェアが有償で提供しています ● https://www.varnish-cache.org/vmod/deviceatlas-mobile-detection
  18. 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!"; } }
  19. 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"); }
  20. 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"); }
  21. 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); }
  22. 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); }
  23. POST/GET/Cookie parse ● POST/GET/Cookieの内容をパースする わ た し で す    / ̄\    ● Developed by   | ^o^ |     \_/    ● https://github.com/xcir/libvmod-parsereq サンプルコード import parsereq; vcl_recv{ if(parsereq.post_header("hoge")){ ... } }
  24. redirect ● Varnishのめんどくさいリダイレクトを簡単にする わ た し で す    / ̄\    ● Developed by   | ^o^ |     \_/    ● 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"); } }
  25. 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"); }
  26. 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") } }
  27. 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(); } }
  28. std - the standard VMOD ● VCL中からログ出力を行うなどの基本的なVMOD VMODのサンプルコード的な役割も ● Developed by Per Buer ● 標準でインストールされます サンプルコード import std; sub vcl_recv { std.log(“hogehoge”); }
  29. 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); }
  30. 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); }
  31. 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 ); } }
  32. いろいろVMODが存在 ● 公式でリストされてないものだと ● LDAP認証 ● Firewall ● などなど これらを使うことで より高度なVarnishライフが・・・
  33. それでも欲しい機能がないなら・・・
  34. VMODを作ってみよう 僕のブログにある inline-C/VMODガイドブック をご覧ください(ステマ)
  35. ご清聴ありがとうございました
Advertisement