Reverse caching proxies: Varnish or Nginx? - phpuk15

Ca901ddcea38854b9783781c91fc87c9?s=47 Thijs Feryn
February 19, 2015

Reverse caching proxies: Varnish or Nginx? - phpuk15

Slides for my Varnish vs Nginx talk at PHPUK conference 2015

Ca901ddcea38854b9783781c91fc87c9?s=128

Thijs Feryn

February 19, 2015
Tweet

Transcript

  1. Reverse caching proxies Varnish or Nginx? By Thijs Feryn

  2. Hi, I’m Thijs

  3. I’m @ThijsFeryn on Twitter

  4. I’m an at Evangelist

  5. I’m a at board member

  6. None
  7. What’s a reverse proxy?

  8. Why?

  9. Why? ✓ Hide origin server ✓ SSL termination ✓ Load

    balancing ✓ Caching ✓ Compression
  10. ✓ Hide origin server ✓ SSL termination ✓ Load balancing

    ✓ Caching ✓ Compression Why?
  11. Protecting your backend server

  12. Kevin & Whitney

  13. Proxy Webserver PHP runtime Client Webserver   thinks  it’s  a

     browser Browser  things   it’s  a  webserver
  14. None
  15. None
  16. Cache-control Cache-­‐Control  “max-­‐age=3600,  s-­‐ maxage=1000,  public,  must-­‐revalidate”

  17. Expires Expires  "Wed,  1  Jan  2015  20:00:00  GMT"

  18. ETag If-­‐None-­‐Match:  "3e86-­‐410-­‐3596Sbc" ETag:  "3e86-­‐410-­‐3596Sbc" Problems with browser cache

  19. What’s not cacheable ✓HTTP POST, PUT, DELETE ✓ Cookie &

    Set-Cookie headers ✓ Authorization ✓ TTL == 0
  20. Meet the contenders Varnish Nginx

  21. None
  22. Varnish ✓Poul-Henning Kamp ✓Verdens Gang AS ✓Redpill Linpro ✓Varnish software

    ✓Reverse proxy only ✓2005: ideas @ Verdens Gang ✓2006 : development & v1 ✓2008: v2 ✓2011: v3 ✓2014: v4 (April 29th)
  23. None
  24. None
  25. Nginx ✓Igor Sysoev ✓2002: development ✓2004: first release ✓15% of

    the internet ✓CK10 problem ✓Event driven, async ✓Webserver & reverse proxy ✓Current version: 1.7.10
  26. Install

  27. curl  http://repo.varnish-­‐cache.org/debian/GPG-­‐key.txt  |  sudo  apt-­‐ key  add  -­‐   echo

     "deb  http://repo.varnish-­‐cache.org/ubuntu/  utopic   varnish-­‐4.0"  |  sudo  tee  -­‐a  /etc/apt/sources.list   sudo  apt-­‐get  update   sudo  apt-­‐get  install  varnish curl  http://repo.varnish-­‐cache.org/debian/GPG-­‐key.txt  |  sudo  apt-­‐ key  add  -­‐   echo  "deb  http://repo.varnish-­‐cache.org/debian/  wheezy   varnish-­‐4.0"  |  sudo  tee  -­‐a  /etc/apt/sources.list   sudo  apt-­‐get  update   sudo  apt-­‐get  install  varnish
  28. deb  http://nginx.org/packages/ubuntu/  utopic  nginx   deb-­‐src  http://nginx.org/packages/ubuntu/  utopic  nginx deb

     http://nginx.org/packages/debian/  wheezy  nginx   deb-­‐src  http://nginx.org/packages/debian/  wheezy  nginx Go  to  h&p://wiki.nginx.org/Pgp  for  PGP  signature   Go  to  h&p://wiki.nginx.org/Install  for  more  info
  29. Configure

  30. DAEMON_OPTS="-­‐a  :80  \   -­‐T  localhost:6082  \   -­‐f  /etc/varnish/default.vcl

     \   -­‐S  /etc/varnish/secret  \   -­‐s  malloc,256m" In  “/etc/default/varnish”
  31. backend  default  {              .host

     =  "127.0.0.1";              .port  =  "8080";   } In  “/etc/varnish/default.vcl”
  32. server  {      listen          

       80;      server_name    host-­‐name.dev;      access_log      /var/log/nginx/access.log;      error_log      /var/log/nginx/error.log;      location  /  {   proxy_pass    http://localhost:8080;   proxy_cache  proxy-­‐cache;   proxy_cache_key  "$scheme://$host $request_uri";   proxy_cache_valid      200  302    1h;   }   } In  “/etc/nginx/ conf.d/default.conf”
  33. proxy_cache_path  /tmp/  levels=1:2   keys_zone=proxy-­‐cache:10m  inactive=5m   max_size=1024; Add  to

      “/etc/nginx/nginx.conf”
  34. Backend Listen  8080   In  “/etc/apache2/ports.conf”

  35. None
  36. ✓mod_php ✓mod_fcgid & php-cgi ✓mod_proxy_fcgi & php-fpm ✓Behind Varnish &

    Nginx
  37. ✓Native fastcgi proxying for php-fpm ✓Cacheable

  38. server  {   listen            

     80;   server_name    nginx-­‐proxy.dev;      root      /home/data/www;      access_log    /var/log/nginx/access.log;      access_log    /var/log/nginx/error.log;      location  /  {      index    index.php;      }   location  ~  \.php$  {   fastcgi_split_path_info  ^(.+\.php)(/.+)$;   fastcgi_pass  127.0.0.1:9000;   fastcgi_index  index.php;   include  fastcgi_params;   fastcgi_param    SCRIPT_FILENAME      $request_filename;   fastcgi_cache      fastcgi-­‐cache;   fastcgi_cache_valid      200  302    1h;   fastcgi_cache_key  "$scheme://$host$request_uri";      }   } 38
  39. Nginx PHP-FPM Client Webserver     &     caching

     proxy
  40. h&ps://www.varnish-­‐cache.org/trac/wiki/ Future_Feature#FCGIbackendsupport

  41. What about ?

  42. sudo  apt-­‐get  install  software-­‐properties-­‐common   sudo  apt-­‐key  adv  -­‐-­‐recv-­‐keys  -­‐-­‐keyserver

     hkp:// keyserver.ubuntu.com:80  0x5a16e7281be7a449   sudo  add-­‐apt-­‐repository  'deb  http://dl.hhvm.com/ubuntu  utopic   main'   sudo  apt-­‐get  update   sudo  apt-­‐get  install  hhvm sudo  apt-­‐key  adv  -­‐-­‐recv-­‐keys  -­‐-­‐keyserver  hkp:// keyserver.ubuntu.com:80  0x5a16e7281be7a449   echo  deb  http://dl.hhvm.com/debian  wheezy  main  |  sudo  tee  /etc/ apt/sources.list.d/hhvm.list   sudo  apt-­‐get  update   sudo  apt-­‐get  install  hhvm
  43. ;  php  options   pid  =  /var/run/hhvm/pid   ;  hhvm

     specific   hhvm.server.port  =  9000   hhvm.server.type  =  fastcgi   hhvm.server.default_document  =  index.php   hhvm.log.use_log_file  =  true   hhvm.log.file  =  /var/log/hhvm/error.log   hhvm.repo.central.path  =  /var/run/hhvm/hhvm.hhbc In  “/etc/hhvm/server.ini” >  /etc/init.d/php-­‐fpm  stop   >  /etc/init.d/hhvm  start
  44. server  {   listen            

     80;   server_name    hhvm.dev;      root      /home/data/www;      access_log    /var/log/nginx/access.log;      access_log    /var/log/nginx/error.log;      location  /  {      index    index.php;      }   location  ~  \.php$  {   fastcgi_split_path_info  ^(.+\.php)(/.+)$;   fastcgi_pass  127.0.0.1:9000;   fastcgi_index  index.php;   include  fastcgi_params;   fastcgi_param    SCRIPT_FILENAME      $request_filename;   fastcgi_cache      fastcgi-­‐cache;   fastcgi_cache_valid      200  302    1h;   fastcgi_cache_key  "$scheme://$host$request_uri";      }   } 44 Same  deal  as   PHP-­‐FPM
  45. With HHVM 3.0.0 we aren't going to ship an HTTP

    server anymore. That means -m server and -m daemon won't work without -vServer.Type=fastcgi. This came about for many reasons: • About 1/2 of user questions were "how do you configure the server to do ...". • It is largely unmaintained. • Building a webserver isn't our core competency and there are many wonderful options already out there. • We built FastCGI support just for this purpose. The slowdown is negligible for most sites, but we feel the configurability you will gain is very much worth it. The default package init.d scripts and server.ini files already support FastCGI so it should work right out of the box. You can run sudo /usr/ share/hhvm/install_fastcgi.sh to configure your nginx or apache config files automatically.
  46. What about ?

  47. curl  -­‐sL  https://deb.nodesource.com/setup  |  sudo  bash  -­‐   apt-­‐get  install

     -­‐y  nodejs  build-­‐essential   npm  install  ws  wscat console.log("Server  started");   var  Msg  =  '';   var  WebSocketServer  =  require('ws').Server          ,  wss  =  new  WebSocketServer({port:  8010});          wss.on('connection',  function(ws)  {                  ws.on('message',  function(message)  {                  console.log('Received  from  client:  %s',  message);                  ws.send('Server  received  from  client:  '  +  message);          });    }); Websocket   test  script
  48. map  $http_upgrade  $connection_upgrade  {          default  upgrade;

             ''  close;   }   server  {          listen              80;          server_name    nodejs.dev;          location  /  {                  proxy_pass  http://127.0.0.1:8010;                  proxy_http_version  1.1;                  proxy_set_header  Upgrade  $http_upgrade;                  proxy_set_header  Connection  $connection_upgrade;          }   }
  49. sub  vcl_recv  {          if  (req.http.Upgrade  ~

     "(?i)websocket")  {                  return  (pipe);          }   }   sub  vcl_pipe  {          if  (req.http.upgrade)  {                  set  bereq.http.upgrade  =  req.http.upgrade;          }          set  bereq.http.Connection  =  "close";          return  (pipe);   }
  50. $>  ./node_modules/wscat/bin/wscat  -­‐-­‐connect  ws://localhost   connected  (press  CTRL+C  to  quit)

      >  test      <  Server  received  from  client:  test Websocket  client
  51. Out of the box

  52. None
  53. ✓POST, DELETE & PUT ✓cookies & auth headers ✓set-cookie headers

    ✓“no-cache", "no-store", „private” in v4 Varnish wil not cache
  54. ✓POST, DELETE & PUT ✓“no-cache", "no-store", "private” ✓set-cookie headers ✓cache

    ttl <= 0 ✓X-Accel-Expires: 0 Nginx wil not cache
  55. About cookies

  56. About cookies HTTP cookie request header via browser HTTP set-cookie

    response header via webserver
  57. set  $bypass  0;   if  ($http_cookie)  {   set  $bypass

     1;   }   fastcgi_cache_bypass  $bypass;   fastcgi_no_cache  $bypass; Nginx caches cookies by default
  58. Monitoring & Logging

  59. access_log error_log

  60. log_format  main     '$remote_addr  -­‐  $remote_user  [$time_local]  "$request"  '

         '$status  $body_bytes_sent  "$http_referer"  '      '"$http_user_agent"  "$http_x_forwarded_for"'      '"$upstream_cache_status"'; log_format  main     '$remote_addr  -­‐  $remote_user  [$time_local]  "$request"  '      '$status  $body_bytes_sent  "$http_referer"  '      '"$http_user_agent"  "$http_x_forwarded_for"'; Default log format Add more fields
  61. ✓MISS ✓BYPASS ➡caused by proxy_cache_bypass call ✓EXPIRED ➡found in cache,

    expired, request was passed to backend ✓UPDATING ➡expired, stale response was used due to proxy/fastcgi_cache_use_stale and cache_lock has timed out ✓STALE ➡expired, stale response was used due to proxy/fastcgi_cache_use_stale ✓REVALIDATED ➡proxy_cache_revalidate verified that the cached content was still valid ✓HIT $upstream_cache_status
  62. varnishstat varnishlog varnishtop

  63. Varnishstat Continuously updated state of the server

  64. None
  65. Varnishlog In memory activity log

  66. *      <<  Request    >>  17   -­‐

         Begin                    req  16  rxreq   -­‐      Timestamp            Start:  1402575535.812994  0.000000  0.000000   -­‐      Timestamp            Req:  1402575535.812994  0.000000  0.000000   -­‐      ReqStart              10.10.10.1  51762   -­‐      ReqMethod            GET   -­‐      ReqURL                  /   -­‐      ReqProtocol        HTTP/1.1   -­‐      ReqHeader            Host:  varnishv4.dev   -­‐      ReqHeader            User-­‐Agent:  Mozilla/5.0  (Macintosh;  Intel  Mac  OS  X  10.9;  rv:29.0)   Gecko/20100101  Firefox/29.0   -­‐      ReqHeader            Accept:  text/html,application/xhtml+xml,application/xml;q=0.9,*/ *;q=0.8   -­‐      ReqHeader            Accept-­‐Language:  en,nl;q=0.7,fr-­‐be;q=0.3   -­‐      ReqHeader            Accept-­‐Encoding:  gzip,  deflate   -­‐      ReqHeader            Connection:  keep-­‐alive   -­‐      ReqHeader            Cache-­‐Control:  max-­‐age=0   -­‐      ReqHeader            X-­‐Forwarded-­‐For:  10.10.10.1   -­‐      VCL_call              RECV   -­‐      VCL_return          hash   -­‐      ReqUnset              Accept-­‐Encoding:  gzip,  deflate   -­‐      ReqHeader            Accept-­‐Encoding:  gzip   -­‐      VCL_call              HASH   -­‐      VCL_return          lookup   -­‐      Hit                        2147516434   -­‐      VCL_call              HIT   -­‐      VCL_return          deliver   -­‐      Link                      bereq  18  bgfetch   -­‐      Timestamp            Fetch:  1402575535.813497  0.000503  0.000503   -­‐      Timestamp            Process:  1402575535.813508  0.000514  0.000011   Client  
  67. -­‐      Hit            

               2147516434   -­‐      VCL_call              HIT   -­‐      VCL_return          deliver   -­‐      Link                      bereq  18  bgfetch   -­‐      Timestamp            Fetch:  1402575535.813497  0.000503  0.000503   -­‐      Timestamp            Process:  1402575535.813508  0.000514  0.000011   -­‐      RespProtocol      HTTP/1.1   -­‐      RespStatus          200   -­‐      RespResponse      OK   -­‐      RespHeader          Date:  Thu,  12  Jun  2014  12:18:43  GMT   -­‐      RespHeader          Server:  Apache/2.2.22  (Debian)   -­‐      RespHeader          X-­‐Powered-­‐By:  PHP/5.4.4-­‐14+deb7u10   -­‐      RespHeader          Cache-­‐Control:  public,  max-­‐age=5   -­‐      RespHeader          Vary:  Accept-­‐Encoding   -­‐      RespHeader          Content-­‐Encoding:  gzip   -­‐      RespHeader          Content-­‐Type:  text/html   -­‐      RespUnset            Date:  Thu,  12  Jun  2014  12:18:43  GMT   -­‐      RespHeader          Date:  Thu,  12  Jun  2014  12:18:55  GMT   -­‐      RespHeader          X-­‐Varnish:  17  32786   -­‐      RespHeader          Age:  12   -­‐      RespHeader          Via:  1.1  varnish  (v4)   -­‐      VCL_call              DELIVER   -­‐      VCL_return          deliver   -­‐      RespHeader          Content-­‐Length:  64   -­‐      Debug                    "RES_MODE  2"   -­‐      RespHeader          Connection:  keep-­‐alive   -­‐      RespHeader          Accept-­‐Ranges:  bytes   -­‐      Timestamp            Resp:  1402575535.813804  0.000810  0.000296   -­‐      Debug                    "XXX  REF  2"   -­‐      ReqAcct                331  0  331  349  64  413   -­‐      End Client  
  68. *      <<  BeReq        >>  18

      -­‐      Begin                    bereq  17  bgfetch   -­‐      Timestamp            Start:  1402575535.813071  0.000000  0.000000   -­‐      BereqMethod        GET   -­‐      BereqURL              /   -­‐      BereqProtocol    HTTP/1.1   -­‐      BereqHeader        Host:  varnishv4.dev   -­‐      BereqHeader        User-­‐Agent:  Mozilla/5.0  (Macintosh;  Intel  Mac  OS  X  10.9;  rv:29.0)   Gecko/20100101  Firefox/29.0   -­‐      BereqHeader        Accept:  text/html,application/xhtml+xml,application/xml;q=0.9,*/ *;q=0.8   -­‐      BereqHeader        Accept-­‐Language:  en,nl;q=0.7,fr-­‐be;q=0.3   -­‐      BereqHeader        X-­‐Forwarded-­‐For:  10.10.10.1   -­‐      BereqHeader        Accept-­‐Encoding:  gzip   -­‐      BereqHeader        X-­‐Varnish:  18   -­‐      VCL_call              BACKEND_FETCH   -­‐      VCL_return          fetch   -­‐      BackendClose      17  default(127.0.0.1,,8080)  toolate   -­‐      BackendOpen        17  default(127.0.0.1,,8080)  127.0.0.1  41135   -­‐      Backend                17  default  default(127.0.0.1,,8080)   -­‐      Timestamp            Bereq:  1402575535.813220  0.000149  0.000149   -­‐      Timestamp            Beresp:  1402575535.828116  0.015045  0.014896   -­‐      BerespProtocol  HTTP/1.1   -­‐      BerespStatus      200   -­‐      BerespResponse  OK   -­‐      BerespHeader      Date:  Thu,  12  Jun  2014  12:18:55  GMT   -­‐      BerespHeader      Server:  Apache/2.2.22  (Debian)   -­‐      BerespHeader      X-­‐Powered-­‐By:  PHP/5.4.4-­‐14+deb7u10   -­‐      BerespHeader      Cache-­‐Control:  public,  max-­‐age=5   -­‐      BerespHeader      Vary:  Accept-­‐Encoding   Backend  
  69. -­‐      BerespHeader      Content-­‐Encoding:  gzip   -­‐

         BerespHeader      Content-­‐Length:  64   -­‐      BerespHeader      Content-­‐Type:  text/html   -­‐      TTL                        RFC  5  -­‐1  -­‐1  1402575536  1402575536  1402575535  0  5   -­‐      VCL_call              BACKEND_RESPONSE   -­‐      VCL_return          deliver   -­‐      Storage                malloc  s0   -­‐      ObjProtocol        HTTP/1.1   -­‐      ObjStatus            200   -­‐      ObjResponse        OK   -­‐      ObjHeader            Date:  Thu,  12  Jun  2014  12:18:55  GMT   -­‐      ObjHeader            Server:  Apache/2.2.22  (Debian)   -­‐      ObjHeader            X-­‐Powered-­‐By:  PHP/5.4.4-­‐14+deb7u10   -­‐      ObjHeader            Cache-­‐Control:  public,  max-­‐age=5   -­‐      ObjHeader            Vary:  Accept-­‐Encoding   -­‐      ObjHeader            Content-­‐Encoding:  gzip   -­‐      ObjHeader            Content-­‐Type:  text/html   -­‐      Fetch_Body          3  length  stream   -­‐      Gzip                      u  F  -­‐  64  44  80  80  442   -­‐      Timestamp            BerespBody:  1402575535.828260  0.015189  0.000144   -­‐      BackendReuse      17  default(127.0.0.1,,8080)   -­‐      Length                  64   -­‐      BereqAcct            316  0  316  250  64  314   -­‐      End   *      <<  Session    >>  16   -­‐      Begin                    sess  0  HTTP/1   -­‐      SessOpen              10.10.10.1  51762  :80  10.10.10.36  80  1402575535.812946  14   -­‐      Link                      req  17  rxreq   -­‐      SessClose            RX_TIMEOUT  5.021   -­‐      End Backend  
  70. VSL Query Expressions varnishlog  -­‐i  ReqURL  -­‐q  'VCL_Call  eq  "HIT"'

    varnishlog  -­‐i  ReqURL  -­‐q  'VCL_Call  eq  "MISS"' varnishlog  -­‐i  ReqURL  -­‐q  'RespStatus  >  400   and  RespStatus  <=  404' varnishlog  -­‐i  ReqURL  -­‐q  'Timestamp:Fetch[2]   >  2.0'
  71. Varnishtop Continuously updated list of incremental data

  72. VSL Query Expressions varnishtop  -­‐i  ReqURL  -­‐q  'VCL_Call  eq  "HIT"'

    varnishtop  -­‐i  ReqURL  -­‐q  'VCL_Call  eq  "MISS"' varnishtop  -­‐C  -­‐I  "ReqHeader:^User-­‐Agent" varnishtop  -­‐i  RespStatus varnishtop  -­‐i  ReqURL
  73. The flow

  74. None
  75. *      <<  Request    >>  17   -­‐

         Begin                    req  16  rxreq   -­‐      Timestamp            Start:  1402575535.812994  0.000000  0.000000   -­‐      Timestamp            Req:  1402575535.812994  0.000000  0.000000   -­‐      ReqStart              10.10.10.1  51762   -­‐      ReqMethod            GET   -­‐      ReqURL                  /   -­‐      ReqProtocol        HTTP/1.1   -­‐      ReqHeader            Host:  varnishv4.dev   -­‐      ReqHeader            User-­‐Agent:  Mozilla/5.0  (Macintosh;  Intel  Mac  OS  X  10.9;  rv:29.0)   Gecko/20100101  Firefox/29.0   -­‐      ReqHeader            Accept:  text/html,application/xhtml+xml,application/xml;q=0.9,*/ *;q=0.8   -­‐      ReqHeader            Accept-­‐Language:  en,nl;q=0.7,fr-­‐be;q=0.3   -­‐      ReqHeader            Accept-­‐Encoding:  gzip,  deflate   -­‐      ReqHeader            Connection:  keep-­‐alive   -­‐      ReqHeader            Cache-­‐Control:  max-­‐age=0   -­‐      ReqHeader            X-­‐Forwarded-­‐For:  10.10.10.1   -­‐      VCL_call              RECV   -­‐      VCL_return          hash   -­‐      ReqUnset              Accept-­‐Encoding:  gzip,  deflate   -­‐      ReqHeader            Accept-­‐Encoding:  gzip   -­‐      VCL_call              HASH   -­‐      VCL_return          lookup   -­‐      Hit                        2147516434   -­‐      VCL_call              HIT   -­‐      VCL_return          deliver   -­‐      Link                      bereq  18  bgfetch   -­‐      Timestamp            Fetch:  1402575535.813497  0.000503  0.000503   -­‐      Timestamp            Process:  1402575535.813508  0.000514  0.000011   Got it?
  76. Cache key

  77. Cache key sub  vcl_hash  {   hash_data(req.url);   if  (req.http.host)

     {   hash_data(req.http.host);   }  else  {   hash_data(server.ip);   }   return  (lookup);   }
  78. Cache key fastcgi_cache_key  "$scheme://$host$request_uri";   proxy_cache_key  "$scheme://$host$request_uri";

  79. Hashing cookies

  80. Hashing cookies sub  vcl_hash  {   if(req.http.Cookie  ~  "country"){  

    hash_data(regsub(req.http.Cookie,   ".*country=([^;]+);.*","\1"));      }   }
  81. Hashing cookies proxy_cache_key  “$scheme://$host$request_uri $cookie_country";   fastcgi_cache_key  "$scheme://$host$request_uri $cookie_country";

  82. Cache purging

  83. Purge config sub  vcl_recv  {          if

     (req.method  ==  "PURGE")  {                  return(purge);          }   }
  84. sub  vcl_recv  {              

       if  (req.method  ==  "PURGE")  {                          ban("req.http.host  ==  "  +  req.http.host  +   "  &&  req.url  ~  "  +  req.url);   return  (synth(200,  "Banned"));                  }   } sub  vcl_recv  {          if  (req.method  ==  "PURGE")  {                  ban("req.http.host  ==  "  +  req.http.host  +  "   &&  req.url  ==  "  +  req.url);                  return  (synth(200,  "Banned"));          }   } Ban config URL Pattern
  85. Purge/ban execution curl  -­‐X  PURGE  http://varnish.dev/your-­‐page $  varnishadm   varnish>

      varnish>  ban  req.url  ==  "/"   200 Or  via  telnet
  86. Purge grep  -­‐lr  'http://host.dev/test.php'  /tmp/cache/*  |  xargs   rm

  87. h&ps://github.com/FRiCKLE/ngx_cache_purge    location  /  {          

           index    index.php;                  error_page  477  =  @purge;                  if  ($request_method  =  PURGE)  {                                  return  477;                  }      }      location  @purge  {              access_log  /var/log/nginx/caching.purge.log;              fastcgi_cache_purge  fastcgi-­‐cache  "$scheme://$host $request_uri";      } Purge config
  88. h&ps://github.com/FRiCKLE/ngx_cache_purge    location  /  {          

           index    index.php;                  error_page  477  =  @purge;                  if  ($request_method  =  PURGE)  {                                  return  477;                  }      }      location  @purge  {              access_log  /var/log/nginx/caching.purge.log;              proxy_cache_purge  proxy-­‐cache  "$scheme://$host $request_uri";      } Purge config
  89. Purge execution curl  -­‐X  PURGE  http://varnish.dev/your-­‐page

  90. Loadbalancing

  91. probe healthcheck { .url = "/status.php"; .interval = 60s; .timeout

    = 0.3 s; .window = 8; .threshold = 3; .initial = 3; .expected_response = 200; } backend www { .host = "www.example.com"; .port = "http"; .probe = healthcheck; } Health probes
  92. server { ... location / { proxy_pass http://backend; health_check match=welcome;

    } } match welcome { status 200; header Content-Type = text/html; body ~ "Welcome to nginx!"; } Health probes
  93. ✓Round-robin ✓Random ✓Hash ✓Fallback Directors

  94. vcl  4.0;   backend  apache  {        

     .host  =  "127.0.0.1";          .port  =  “8080";   }   backend  nginx  {          .host  =  "127.0.0.1";          .port  =  "8081";     }   import  directors;   sub  vcl_init  {          new  vdir  =  directors.random();          vdir.add_backend(apache,10);          vdir.add_backend(nginx,5);   }   sub  vcl_recv  {          set  req.backend_hint  =  vdir.backend();   } Random
  95. …   vcl  4.0;   backend  apache  {    

         .host  =  "127.0.0.1";          .port  =  "8080";          .probe  =  healthcheck;           }   backend  nginx  {      .host  =  "127.0.0.1";      .port  =  "8081";      .probe  =  healthcheck;         }   import  directors;   sub  vcl_init  {          new  vdir  =  directors.fallback();          vdir.add_backend(apache);          vdir.add_backend(nginx);   }   sub  vcl_recv  {          set  req.backend_hint  =  vdir.backend();   } Fallback Picks  first   healthy   backend Order   matters
  96. vcl  4.0;   backend  apache  {        

     .host  =  "127.0.0.1";          .port  =  "8080";   }   backend  nginx  {          .host  =  "127.0.0.1";          .port  =  "8081";   }   import  directors;   sub  vcl_init  {          new  vdir  =  directors.hash();          vdir.add_backend(apache,1.0);          vdir.add_backend(nginx,1.0);   }   sub  vcl_recv  {          set  req.backend_hint  =   vdir.backend(client.identity);   } IP hash
  97. upstream backend { server backend1.example.com weight=5; server backend2.example.com:8080; server unix:/tmp/backend3;

    } server { location / { proxy_pass http://backend; } } Random
  98. upstream backend { server backend1.example.com; server backend2.example.com backup; } server

    { location / { proxy_pass http://backend; } } Fallback
  99. upstream backend { ip_hash; server backend1.example.com weight=2; server backend2.example.com; server

    backend3.example.com down; server backend4.example.com; } server { location / { proxy_pass http://backend; } } IP hash
  100. HIT/MISS marker

  101. sub  vcl_deliver  {      if  (obj.hits  >  0)  {

             set  resp.http.X-­‐Cache  =  "HIT";      }      else  {          set  resp.http.X-­‐Cache  =  "MISS";      }   } HIT/MISS marker
  102. HIT/MISS marker add_header  X-­‐Cache  $upstream_cache_status;  

  103. Set Time To Live

  104. Cache-­‐Control  “max-­‐age=10,  s-­‐maxage=5,   public,  must-­‐revalidate”

  105. Cache-­‐Control  “max-­‐age=10,  s-­‐maxage=5,   public,  must-­‐revalidate” 5  seconds TTL

  106. Cache-­‐Control  “max-­‐age=10,  s-­‐maxage=5,   public,  must-­‐revalidate” 10  seconds TTL

  107. Force TTL sub  vcl_backend_response  {          if(bereq.url

     ~  "^/bla")  {                  set  beresp.ttl  =  10s;          }  else  {                  set  beresp.ttl  =  3600s;          }   }
  108. location  /  {   proxy_pass    http://localhost:8080;   proxy_cache  proxy-­‐cache;

      proxy_cache_key  "$scheme://$host$request_uri";   proxy_cache_valid      200  302    1h;   }   location  ~  /bla  {   proxy_pass    http://localhost:8080;   proxy_cache  proxy-­‐cache;   proxy_cache_key  "$scheme://$host$request_uri";   proxy_cache_valid      200  302    10s;   } Force TTL
  109. Edge Side Includes

  110. header.php menu.php main.php footer.php TTL  5s No  caching TTL  10s

    TTL  2s
  111. <html> <body> <table> <tr> <td colspan="2" > <?php include('header.php') ?>

    </td> </tr> <tr> <td><?php include('menu.php') ?></td> <td><?php include('main.php') ?></td> </tr> <tr> <td colspan="2" > <?php include('footer.php') ?> </td> </tr> </table> </body> </html>
  112. <html> <body> <table> <tr> <td colspan="2" > <esi:include src="/header.php" />

    </td> </tr> <tr> <td><esi:include src="/menu.php" /></td> <td><esi:include src="/main.php" /></td> </tr> <tr> <td colspan="2" > <esi:include src="/footer.php" /> </td> </tr> </table> </body> </html>
  113. sub  vcl_recv  {      set  req.http.Surrogate-­‐Capability="key=ESI/1.0";   }  

    sub  vcl_backend_response  {      if(beresp.http.Surrogate-­‐Control~"ESI/1.0")  {          unset  beresp.http.Surrogate-­‐Control;      set  beresp.do_esi=true;          }   }  
  114. h&ps://github.com/taf2/nginx-­‐esi Not  official Haven’t   tested  it  yet Edge Side

    Includes
  115. Edge Side Includes Server Side Includes

  116. <html> <body> <table> <tr> <td colspan="2" > <!--# include virtual="/header.php"

    --> </td> </tr> <tr> <td> <!--# include virtual="/menu.php" --> </td> <td> <!--# include virtual="/main.php" --> </td> </tr> <tr> <td colspan="2" > <!--# include virtual="/footer.php" --> </td> </tr> </table> </body> </html> Highest  TTL   is  used
  117. server  {   …     ssi  on;   …

      }
  118. SSL support

  119. Varnish doesn’t support SSL

  120. Nginx supports SSL (& SPDY)

  121. server  {      listen  443;      ssl  on;

           ssl_certificate  /path/to/ssl.crt;      ssl_certificate_key    /path/to/ssl.key;      server_name    hostname.dev;      access_log    /var/log/nginx/access.log;      error_log    /var/log/nginx/error.log;      location  /  {              proxy_pass  http://localhost:80;     proxy_set_header    X-­‐Real-­‐IP    $remote_addr;     proxy_cache      proxy-­‐cache;     proxy_cache_key  "$scheme://$host$request_uri";     proxy_cache_valid      200  302    1h;      }   } SSL
  122. Who won the battle? Varnish Nginx

  123. And  on   that   bombshell  ...

  124. None