ããã¯ããªã«ãããããŠæžãããã®ïŒ
å°ãåã«ãVarnish 6.0ãã€ã³ã¹ããŒã«ããŠã¿ãŸããã
Varnish 6.0をUbuntu Linux 18.04 LTSにインストールする - CLOVER🍀
ãã®æã¯ããšããããã€ã³ã¹ããŒã«ããã ãã ã£ãã®ã§ãä»åã¯ããå°ãèšå®ãæ±ã£ãŠã¿ãŸãããã
ç°å¢
ä»åã®ç°å¢ã¯ããã¡ãã
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 18.04.3 LTS Release: 18.04 Codename: bionic
Varnishã®ããŒãžã§ã³ã¯ããã¡ãã§ãã
$ varnishd -V varnishd (varnish-6.0.4 revision 14d4eee6f0afc3020a044341235f54f3bd1449f1) Copyright (c) 2006 Verdens Gang AS Copyright (c) 2006-2019 Varnish Software AS
Varnishããã³ããã¯ãšã³ããµãŒããŒã皌åããŠãããµãŒããŒã®IPã¢ãã¬ã¹ããã³ãã¢ã¯ã»ã¹ããã¯ã©ã€ã¢ã³ãã®IPã¢ãã¬ã¹ã¯ã
以äžãšããŸãã
- Varnish and ãªãªãžã³ãµãŒã㌠⊠192.168.33.10
- ã¯ã©ã€ã¢ã³ã ⊠192.168.33.1
ããã©ã«ãã®Varnishã®èšå®
ãŸãã¯ãããŒã¹ãšãªãVarnishã®èšå®ã確èªããŠã¿ãŸããã³ã¡ã³ãã¢ãŠããšé£ã°ããšããããªæãã§ããã
$ grep -vE ' *#' /etc/varnish/default.vcl vcl 4.0; backend default { .host = "127.0.0.1"; .port = "8080"; } sub vcl_recv { } sub vcl_backend_response { } sub vcl_deliver { }
ããã¯ãšã³ããµãŒããŒïŒãã¹ãçšã®ãµãŒããŒïŒ
ä»åã¯ãããã¯ãšã³ããµãŒããŒãç°¡åã«Pythonã®HTTPãµãŒããŒã§çšæããŸãã
ã«ã¬ã³ããã£ã¬ã¯ããªãšããµããã£ã¬ã¯ããªã«ãã¡ã€ã«ãã²ãšã€çšæããŠãããŒã8080ã§èµ·åã
$ echo 'Hello Varnish!!' > hello.txt $ mkdir sub-dir $ echo 'Hello Cache Server!!' > sub-dir/cache.txt $ python3 -m http.server 8080
Varnishãžã¯ãããŒã6081è¶ãã«ã¢ã¯ã»ã¹ããã°ãVarnishãçµç±ããŠãã£ãã·ã¥ããªããã°ããã¯ãšã³ããµãŒããŒãžã®ã¢ã¯ã»ã¹ãšãªããŸãã
$ curl 192.168.33.10:6081/hello.txt Hello Varnish!!
ãã«ãã€ã³ã®èšå®ïŒ
ãšããã§ãçšæãããŠããããã©ã«ãã®èšå®ãã¡ã€ã«ïŒ/etc/varnish/default.vclïŒã®äžã«ã¯ç¹ã«ãªã«ãèšå®ããªãããã§ãããã
ãã£ãã·ã¥ã¯ãã§ã«æå¹ã«ãªã£ãŠããæãã§ããã
ã©ããªã£ãŠãããã§ãããïŒ
ãã«ãã€ã³ã®èšå®ãã¡ã€ã«ãããããã§ãã
https://github.com/varnishcache/varnish-cache/blob/varnish-6.0.4/bin/varnishd/builtin.vcl
$ curl -s https://raw.githubusercontent.com/varnishcache/varnish-cache/varnish-6.0.4/bin/varnishd/builtin.vcl | grep -vE '*#' /*- * Copyright (c) 2006 Verdens Gang AS * Copyright (c) 2006-2015 Varnish Software AS * All rights reserved. * * Author: Poul-Henning Kamp <phk@phk.freebsd.dk> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * This is the builtin VCL code */ vcl 4.0; sub vcl_recv { if (req.method == "PRI") { /* This will never happen in properly formed traffic (see: RFC7540) */ return (synth(405)); } if (!req.http.host && req.esi_level == 0 && req.proto ~ "^(?i)HTTP/1.1") { /* In HTTP/1.1, Host is required. */ return (synth(400)); } if (req.method != "GET" && req.method != "HEAD" && req.method != "PUT" && req.method != "POST" && req.method != "TRACE" && req.method != "OPTIONS" && req.method != "DELETE" && req.method != "PATCH") { /* Non-RFC2616 or CONNECT which is weird. */ return (pipe); } if (req.method != "GET" && req.method != "HEAD") { /* We only deal with GET and HEAD by default */ return (pass); } if (req.http.Authorization || req.http.Cookie) { /* Not cacheable by default */ return (pass); } return (hash); } sub vcl_pipe { return (pipe); } sub vcl_pass { return (fetch); } sub vcl_hash { hash_data(req.url); if (req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); } return (lookup); } sub vcl_purge { return (synth(200, "Purged")); } sub vcl_hit { if (obj.ttl >= 0s) { // A pure unadulterated hit, deliver it return (deliver); } if (obj.ttl + obj.grace > 0s) { // Object is in grace, deliver it // Automatically triggers a background fetch return (deliver); } // fetch & deliver once we get the result return (miss); } sub vcl_miss { return (fetch); } sub vcl_deliver { return (deliver); } /* * We can come here "invisibly" with the following errors: 500 & 503 */ sub vcl_synth { set resp.http.Content-Type = "text/html; charset=utf-8"; set resp.http.Retry-After = "5"; set resp.body = {"<!DOCTYPE html> <html> <head> <title>"} + resp.status + " " + resp.reason + {"</title> </head> <body> <h1>Error "} + resp.status + " " + resp.reason + {"</h1> <p>"} + resp.reason + {"</p> <h3>Guru Meditation:</h3> <p>XID: "} + req.xid + {"</p> <hr> <p>Varnish cache server</p> </body> </html> "}; return (deliver); } sub vcl_backend_fetch { if (bereq.method == "GET") { unset bereq.body; } return (fetch); } sub vcl_backend_response { if (bereq.uncacheable) { return (deliver); } else if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Surrogate-control ~ "(?i)no-store" || (!beresp.http.Surrogate-Control && beresp.http.Cache-Control ~ "(?i:no-cache|no-store|private)") || beresp.http.Vary == "*") { set beresp.ttl = 120s; set beresp.uncacheable = true; } return (deliver); } sub vcl_backend_error { set beresp.http.Content-Type = "text/html; charset=utf-8"; set beresp.http.Retry-After = "5"; set beresp.body = {"<!DOCTYPE html> <html> <head> <title>"} + beresp.status + " " + beresp.reason + {"</title> </head> <body> <h1>Error "} + beresp.status + " " + beresp.reason + {"</h1> <p>"} + beresp.reason + {"</p> <h3>Guru Meditation:</h3> <p>XID: "} + bereq.xid + {"</p> <hr> <p>Varnish cache server</p> </body> </html> "}; return (deliver); } sub vcl_init { return (ok); } sub vcl_fini { return (ok); }
ããã©ã«ãã§çšæãããŠããèšå®ãã¡ã€ã«ã®å
é ã®ã³ã¡ã³ããèªããšããã®èšå®ãã¡ã€ã«ã®åŸã«ãã«ãã€ã³ã®å
容ãåãããã«
èªããŸããã
$ head -n 6 /etc/varnish/default.vcl # # This is an example VCL file for Varnish. # # It does not do anything by default, delegating control to the # builtin VCL. The builtin VCL is called when there is no explicit # return statement.
èšå®ãã¡ã€ã«ãèªãã
ãšããã§ãèšå®ãã¡ã€ã«ã¯VCLãšããèšèªã§æžããããªã®ã§ãã
VCL - Varnish Configuration Language — Varnish version 6.0.4 documentation
èªã¿æ¹ãããããããŸãããïŒ
ã·ã³ã¿ãã¯ã¹ããã³ãªãã¡ã¬ã³ã¹ã¯ããã¡ãã
VCL Syntax — Varnish version 6.0.4 documentation
VCL — Varnish version 6.0.4 documentation
ã§ãããããã ãã ãšããã®ãããªèšå®ã¯ã¡ãã£ãšèªããŸããã
sub vcl_recv { if (req.method == "PRI") { /* This will never happen in properly formed traffic (see: RFC7540) */ return (synth(405)); } if (!req.http.host && req.esi_level == 0 && req.proto ~ "^(?i)HTTP/1.1") { /* In HTTP/1.1, Host is required. */ return (synth(400)); } if (req.method != "GET" && req.method != "HEAD" && req.method != "PUT" && req.method != "POST" && req.method != "TRACE" && req.method != "OPTIONS" && req.method != "DELETE" && req.method != "PATCH") { /* Non-RFC2616 or CONNECT which is weird. */ return (pipe); } if (req.method != "GET" && req.method != "HEAD") { /* We only deal with GET and HEAD by default */ return (pass); } if (req.http.Authorization || req.http.Cookie) { /* Not cacheable by default */ return (pass); } return (hash); }
ãããèªãã«ã¯ããã«ãã€ã³ã®ãµãã«ãŒãã³ãšãç¶æ é·ç§»ã®ããã¥ã¡ã³ããèªããšããããã§ãã
ãã«ãã€ã³ã®ãµãã«ãŒãã³ãšç¶æ é·ç§»ã®ããã¥ã¡ã³ãã¯ãã¯ã©ã€ã¢ã³ããµã€ããšããã¯ãšã³ããµã€ãã«åãããŠããŸãã
Built in subroutines — Varnish version 6.0.4 documentation
Varnish Processing States — Varnish version 6.0.4 documentation
ã¯ã©ã€ã¢ã³ããµã€ãã®å³ã
ããã¯ãšã³ããµã€ãã®å³ãã¯ã©ã€ã¢ã³ããµã€ãã®å³ã®ãsee backend graphãã®éšåã該åœããŸãã
å³ãèŠãŠãããšããã«ãã€ã³ã®ãµãã«ãŒãã³ãšããµãã«ãŒãã³ãè¿ãå€ã§ç¶æ é·ç§»ã決ãŸãããšããªããšãªãããããŸãã
äŸãã°ãvcl_recvã§ãpassããè¿ããšã次ã¯vcl_passã«ç§»ãããšããå ·åã§ããã
vcl_passãŸãã¯vcl_missã®ããšã¯ãããã¯ãšã³ãã«ç§»ãããªãªãžã³ãµãŒããŒãžã®ã¢ã¯ã»ã¹ãè¡ãããŸãã
ãã«ãã€ã³ã®ãµãã«ãŒãã³ã®æå³ããããã£ãšçºããŠã¿ãŸãããã
Built in subroutines — Varnish version 6.0.4 documentation
- ã¯ã©ã€ã¢ã³ããµã€ã
- vcl_recv ⊠ãªã¯ãšã¹ãã®éå§æã«åŒã³åºãããŸãããã®åŸã«ãã©ã®ãããªåŠçã«æ¯ãåããããæ±ºå®ããŸã
- vcl_pipe ⊠ãã€ãã¢ãŒãã«å ¥ãæã«åŒã³åºãããŸãããã®å Žåãã¯ã©ã€ã¢ã³ããšããã¯ãšã³ãã®ããåãã¯æ¥ç¶ãçµäºãããŸã§ããã®ãŸãŸã®å å®¹ã§æž¡ãããŸããåçŽãªãããã·ã«ãªããšããããšã§ã
- vcl_pass ⊠ãªã¯ãšã¹ããããã¯ãšã³ããµãŒããŒã«æž¡ããŸãããã®å Žåãã¬ã¹ãã³ã¹ã¯ãã£ãã·ã¥ã«ã¯ä¿åãããŸããããããã·ã«ãªãããã§ãã
- vcl_hash ⊠vcl_recvã®åŸã«åŒã³åºãããŸãããªã¯ãšã¹ãã«å¯Ÿããããã·ã¥å€ãäœæãããã£ãã·ã¥æç¡ã®ç¢ºèªã«äœ¿ãããŸã
- vcl_purge ⊠ãã£ãã·ã¥ã®ããŒãžãå®è¡ãããŸã
- vcl_miss ⊠ãªã¯ãšã¹ãã«å¯Ÿå¿ãããã£ãã·ã¥ããªãå Žåã«åŒã³åºãããããã¯ãšã³ããµãŒããŒãžã®åŒã³åºããè¡ããŸãããŸããvcl_hitãfetchãæ»ããå Žåã«ãåŒã³åºãããŸãïŒdeliverããªïŒïŒ
- vcl_hit ⊠ãªã¯ãšã¹ãã«å¯Ÿå¿ãããã£ãã·ã¥ããããããå Žåã«åŒã³åºãããŸã
- vcl_deliver ⊠ã¯ã©ã€ã¢ã³ãã«ã¬ã¹ãã³ã¹ãè¿ããŸã
- vcl_synth ⊠syntheticãªããžã§ã¯ããé ä¿¡ããããã«åŒã³åºãããŸããsyntheticãªããžã§ã¯ãã¯VCLã§äœæãããããã¯ãšã³ããµãŒããŒããã¯ååŸãããŸãã
- ããã¯ãšã³ããµã€ã
- vcl_backend_fetch ⊠ããã¯ãšã³ããµãŒããŒãžã®ãªã¯ãšã¹ããéä¿¡ããåã«åŒã³åºãããŸããããã¯ãšã³ããµãŒããŒã«éä¿¡ãããªã¯ãšã¹ãã倿Žããã®ã«äœ¿ãããŸã
- vcl_backend_response ⊠ã¬ã¹ãã³ã¹ããããŒããããã¯ãšã³ããµãŒããŒããæ£åžžã«æ»ã£ãŠããæã«åŒã³åºãããŸã
- vcl_backend_error ⊠ããã¯ãšã³ããµãŒããŒããã®ãã§ããã«å€±æããå ŽåããŸãã¯max_retriesãè¶ ããå Žåã«åŒã³åºãããŸã
ãšããããããèŠã€ã€ããã1åºŠç¶æ é·ç§»ã®å³ãçºããŠã¿ããšãããããããŸããã
èšå®ã倿ŽããŠã¿ã
ããã§ã¯ã詊ãã«ããã€ãããã©ã«ãã®èšå®ãã¡ã€ã«ã倿ŽããŠã¿ãŸãããã
ã/hello.txtãã«ã¢ã¯ã»ã¹ãããæã¯ãåçŽã«ãããã·ããããã«ããŠã¿ãŸãããã
sub vcl_recv { if (req.url == "/hello.txt") { return (pass); } }
èšå®ãå€ããããVarnishãrestartãŸãã¯reloadããŸãã
確èªã
$ curl 192.168.33.10:6081/hello.txt Hello Varnish!!
ã¢ã¯ã»ã¹ãã°ãèŠãŠã¿ãŸãã
$ sudo varnishncsa -F '%h %l %u %t "%r" %s %b "%{Referer}i" "%{User-ent}i" %{Varnish:hitmiss}x'
äœåºŠã¢ã¯ã»ã¹ããŠããmissãã«ãªããããã¯ãšã³ããµãŒããŒãžãªã¯ãšã¹ããéä¿¡ãããŸãã
192.168.33.1 - - [05/Oct/2019:10:09:44 +0000] "GET http://192.168.33.10:6081/hello.txt HTTP/1.1" 200 16 "-" "curl/7.58.0" miss 192.168.33.1 - - [05/Oct/2019:10:09:45 +0000] "GET http://192.168.33.10:6081/hello.txt HTTP/1.1" 200 16 "-" "curl/7.58.0" miss
ãµããã£ã¬ã¯ããªã®ã³ã³ãã³ãã«ã¢ã¯ã»ã¹ããŠã¿ãŸãã
$ curl 192.168.33.10:6081/sub-dir/cache.txt Hello Cache Server!! $ curl 192.168.33.10:6081/sub-dir/cache.txt Hello Cache Server!!
ãã¡ãã¯ã2åç®ã¯ãã£ãã·ã¥ã䜿ãããŸãã
192.168.33.1 - - [05/Oct/2019:10:10:29 +0000] "GET http://192.168.33.10:6081/sub-dir/cache.txt HTTP/1.1" 200 21 "-" "curl/7.58.0" miss 192.168.33.1 - - [05/Oct/2019:10:10:29 +0000] "GET http://192.168.33.10:6081/sub-dir/cache.txt HTTP/1.1" 200 21 "-" "curl/7.58.0" hit
æ£èŠè¡šçŸã䜿ããã®ã§ãäŸãã°ããã ãšåçŽãªãããã·ãµãŒããŒã«ãªããŸããã
sub vcl_recv { if (req.url ~ "^.+") { return (pass); } }
è«çæŒç®ã®äŸãGETã¡ãœãããã€ã/sub-dir/cache.txtããžã®ã¢ã¯ã»ã¹ã®æã¯ããã£ãã·ã¥ããªãâŠãŸããããäœçºçãªäŸã§ããã
sub vcl_recv { if (req.method == "GET" && req.url == "/sub-dir/cache.txt") { return (pass); } }
ããŠãvcl_recvã¯æ»ããŸãããã
sub vcl_recv { }
次ã¯ãUser-Agentã§ãã£ãã·ã¥ã®çš®é¡ãåããŠã¿ãŸãããã
å ã»ã©ããcurlã§ç¢ºèªããŠããŸãããcurlãšwgetã§å©çšãããã£ãã·ã¥ã倿ŽããŠã¿ãŸãããã®å Žåãvcl_hashã䜿ããŸãã
sub vcl_hash { if (req.http.user-agent ~ "curl.+") { hash_data("curl"); } else if (req.http.user-agent ~ "Wget.+") { hash_data("wget"); } }
ãã®ç¶æ ã§Varnishãåèµ·åããŠãcurlã§2åã¢ã¯ã»ã¹ã
$ curl 192.168.33.10:6081/hello.txt Hello Varnish!! $ curl 192.168.33.10:6081/hello.txt Hello Varnish!!
ã¢ã¯ã»ã¹ãã°ãèŠãŸãã2åç®ã¯ããã£ãã·ã¥ãããŠããŸããã
192.168.33.1 - - [05/Oct/2019:10:33:25 +0000] "GET http://192.168.33.10:6081/hello.txt HTTP/1.1" 200 16 "-" "curl/7.58.0" miss 192.168.33.1 - - [05/Oct/2019:10:33:26 +0000] "GET http://192.168.33.10:6081/hello.txt HTTP/1.1" 200 16 "-" "curl/7.58.0" hit
ç¶ããŠãwgetã§ã¢ã¯ã»ã¹ã
$ wget -q 192.168.33.10:6081/hello.txt -O /dev/stdout Hello Varnish!! $ wget -q 192.168.33.10:6081/hello.txt -O /dev/stdout Hello Varnish!!
äºåã«curlã§ã¢ã¯ã»ã¹ããŠããã«ãé¢ãããã1åç®ã®ãªã¯ãšã¹ãã¯ãã£ãã·ã¥ãã¹ããŸããã
192.168.33.1 - - [05/Oct/2019:10:33:27 +0000] "GET http://192.168.33.10:6081/hello.txt HTTP/1.1" 200 16 "-" "Wget/1.19.4 (linux-gnu)" miss 192.168.33.1 - - [05/Oct/2019:10:33:27 +0000] "GET http://192.168.33.10:6081/hello.txt HTTP/1.1" 200 16 "-" "Wget/1.19.4 (linux-gnu)" hit
OKããã§ãã
ãŸããã¢ã¯ã»ã¹æã®ãã¹ã«åãããŠãTTLã倿ŽããŠã¿ãŸããããããã§ã¯ãvcl_backend_responseå ã§å®çŸ©ããŸãã
sub vcl_backend_response { if (bereq.url == "/hello.txt") { set beresp.ttl = 10s; } else if (bereq.url == "/sub-dir/cache.txt") { set beresp.ttl = 5s; } }
ã/hello.txtãã§ã¯10ç§ãã/sub-dir/cache.txtãã§ã¯5ç§ããããããã£ãã·ã¥ããŸãã
æåŸã«ãè€æ°ã®ããã¯ãšã³ããµãŒããŒã䜿ãäŸã詊ããŠã¿ãŸããããããã¥ã¡ã³ãã®ä»¥äžãåèã«ããŠ
è€æ°ã®backendãå®çŸ©ããŠã
backend default { .host = "127.0.0.1"; .port = "8080"; } backend other { .host = "127.0.0.1"; .port = "3000"; }
vcl_recvã§ãæ¡ä»¶ã«å¿ããŠãreq.backend_hintãã§æ¯ãåããŸãã
sub vcl_recv { if (req.url ~ "^/other/") { set req.backend_hint = other; } else { set req.backend_hint = default; } }
ãããã詊ããŠã¿ãŸããããå°ãVCLã«æ £ããŠããæããããŸãã
åºæ¬çãªããšã¯ãã§ããããªæãã§ããããïŒ