Varnish A caching reverse proxy Liip AG, 25.8.2011, Stefan Paschke & David Buchmann Thursday, August 25, 2011
What is a reverse proxy again? Client Varnish Webserver Cache miss Cache hit Thursday, August 25, 2011
Configure Varnish: VCL Varnish Configuration Language Domain specific language Translated into C & compiled (speed!) Subroutine for each step – full control Thursday, August 25, 2011
Varnish state model Thursday, August 25, 2011
Example: Fast static files sub vcl_recv { if (req.request == "GET" && req.url ~ "^/static/") { unset req.http.cookie; unset req.http.Authorization; lookup; } # prepended to default vcl_recv. let default happen } Thursday, August 25, 2011
Example: Be prudent sub vcl_recv { if (req.request != "GET" && req.request != "HEAD" && req.request != "PUT" && req.request != "POST" && req.request != "TRACE" && req.request != "OPTIONS" && req.request != "DELETE") { return(pipe); } } Thursday, August 25, 2011
using the varnish monitoring utilities varnishlog 10 ReqStart c 127.0.0.1 61040 923256129 10 RxRequest c GET 10 RxURL c /2011/08/24/international/IVENB 10 RxProtocol c HTTP/1.1 10 RxHeader c Host: nzz.lo Thursday, August 25, 2011
using the varnish monitoring utilities varnishlog -i <tags> varnishlog -b varnishlog -o varnishlog -i TxRequest,TxURL -b Thursday, August 25, 2011
using the varnish monitoring utilities varnishtop varnishhist varnishsizes varnishstat Thursday, August 25, 2011
understanding header parameters Cache-Control max-age=0, public, s-maxage=60 Last-Modified Wed, 24 Aug 2011 12:31:40 GMT Thursday, August 25, 2011
Symfony Integration Set Cache-Control, Expires and Last-Modified in controller LiipCacheControlBundle URL based cache-control Varnish helper Thursday, August 25, 2011
Cache Header $response = new Response(); $response->setPublic(); $response->setMaxAge(600); $response->setSharedMaxAge(600); $response->headers-> AddCacheControlDirective( 'must-revalidate', true); HTTP headers now include: Cache-Control: s-maxage=600, max- age=3600, must-revalidate Thursday, August 25, 2011
Expires Header $date = new DateTime(); $date->modify('+600 seconds'); $response->setExpires($date); HTTP headers now include: Expires: Thu, 08 Aug 2011 12:00:00 GMT Thursday, August 25, 2011
LiipCacheControlBundle # app/config.yml liip_cache_control: rules: # the controls section values are used in a call to # Response::setCache(); - { path: /, controls: { public: true, max_age: 15, s_maxage: 30, last_modified: "-1 hour" }, vary: [Cookies, Accept-Encoding, Accept-Language] } This is all that is needed to set cache information. path: is a regular expression Thursday, August 25, 2011
Purge cached pages Use long cache lifetimes And invalidate cache from backend # config.yml liip_cache_control: varnish: domain: http://www.liip.ch ips: 10.0.0.10, 10.0.0.11 # comma separated list or array port: 80 # varnish port for incoming connections # in the controller // hardcoded url $varnish = $this->container->get('liip_cache_control.varnish'); $varnish->invalidatePath('/some/path'); // using the router to generate the url $router = $this->container->get('router'); $varnish = $this->container->get('liip_cache_control.varnish'); $varnish->invalidatePath($router->generate('myRouteName')); Thursday, August 25, 2011
Purge cached pages: VCL # who is allowed to purge from cache acl purge { "127.0.0.1"; #localhost for dev purposes "10.0.11.0"/24; #server closed network } # in sub vcl_recv # purge if client is in correct ip range if (req.request == "PURGE") { if (!client.ip ~ purge) { error 405 "Not allowed."; } purge("req.url ~ " req.url); # abort request right here error 200 "Success"; } # see also http://varnish-cache.org/trac/wiki/VCLExamplePurging Thursday, August 25, 2011
edge side includes Thursday, August 25, 2011
what Varnish gets: <div id ="topbar" class="topbar"> <header> <h1 class="active">Liip AG</h1> </header> <esi:include src="/_internal/nzz.user.controller/indexAction" /> <div class="toolbar"> <a href="/merkliste" class="button">Merkliste</a> <a href="#" class="button preferences">Einstellungen</a> </div> </div> Thursday, August 25, 2011
what the browser sees: <div id ="topbar" class="topbar"> <header> <h1 class="active">Liip AG</h1> </header> <div class="personalbar"> <a class="myProfile">Stefan Paschke</a> <a href="/logout" class="button singlepageFullLink">Logout</a> </div> <div class="toolbar"> <a href="/merkliste" class="button">Merkliste</a> <a href="#" class="button preferences">Einstellungen</a> </div> </div> Thursday, August 25, 2011
creating esi with twig <div id ="topbar" class="topbar"> <header> <h1 class="active">Liip AG</h1> </header> {% render "nzz.user.controller:indexAction" with {}, {'standalone': true} %} <div class="toolbar"> <a href="{{ path('marked_article_list') }}" class="button singlepageFullLink remember_list">Merkliste</a> <a href="#" class="button preferences">Einstellungen</a> </div> </div> Thursday, August 25, 2011
telling Symfony to render esi tags: Surrogate-Capability abc=ESI/1.0 sub vcl_recv { set req.http.Surrogate-Capability = "abc=ESI/1.0"; return (lookup); } Thursday, August 25, 2011
accessing the _internal route: _internal: resource: "@FrameworkBundle/Resources/config/routing/internal.xml" prefix: /_internal Thursday, August 25, 2011
caching content behind a paywall Client Varnish Webserver Cache miss GET /resource/xyz PHPSESSID=g4fu6Jk GET /resource/xyz Authorization PHPSESSID=g4fu6Jk Cache hit? Thursday, August 25, 2011
caching content behind a paywall Client Varnish Webserver Cache miss GET /resource/xyz PHPSESSID=g4fu6Jk GET /resource/xyz Authorization PHPSESSID=g4fu6Jk GET /resource/xyz Cache hit PHPSESSID=dfgt&5g HEAD /resource/xyz PHPSESSID=dfgt&5g Thursday, August 25, 2011
paywall config: sub vcl_recv { if (req.request == "GET") { if (req.restarts == 0) { set req.request = "HEAD"; return (pass); } else { set req.http.Surrogate-Capability = "abc=ESI/1.0"; return (lookup); } } } sub vcl_fetch { if (beresp.status >= 200 && beresp.status < 300) { if (req.request == "HEAD") { set req.request = "GET"; restart; } } else { if (req.request == "HEAD") { set beresp.http.content-length = "0"; } return (pass); } if (beresp.http.Surrogate-Control ~ "ESI/1.0") { unset beresp.http.Surrogate-Control; esi; } } Thursday, August 25, 2011
Thanks for your attention! Questions? Thursday, August 25, 2011
Recommend
More recommend