Slide 1

Slide 1 text

Reverse caching proxies Varnish or Nginx? By Thijs Feryn

Slide 2

Slide 2 text

Hi, I’m Thijs

Slide 3

Slide 3 text

I’m @ThijsFeryn on Twitter

Slide 4

Slide 4 text

I’m an at Evangelist

Slide 5

Slide 5 text

I’m a at board member

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

What’s a reverse proxy?

Slide 8

Slide 8 text

Why?

Slide 9

Slide 9 text

Why? ✓ Hide origin server ✓ SSL termination ✓ Load balancing ✓ Caching ✓ Compression

Slide 10

Slide 10 text

✓ Hide origin server ✓ SSL termination ✓ Load balancing ✓ Caching ✓ Compression Why?

Slide 11

Slide 11 text

Protecting your backend server

Slide 12

Slide 12 text

Kevin & Whitney

Slide 13

Slide 13 text

Proxy Webserver PHP runtime Client Webserver   thinks  it’s  a  browser Browser  things   it’s  a  webserver

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

Cache-control Cache-­‐Control  “max-­‐age=3600,  s-­‐ maxage=1000,  public,  must-­‐revalidate”

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

What’s not cacheable ✓HTTP POST, PUT, DELETE ✓ Cookie & Set-Cookie headers ✓ Authorization ✓ TTL == 0

Slide 20

Slide 20 text

Meet the contenders Varnish Nginx

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

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)

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

Install

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

Configure

Slide 30

Slide 30 text

DAEMON_OPTS="-­‐a  :80  \   -­‐T  localhost:6082  \   -­‐f  /etc/varnish/default.vcl  \   -­‐S  /etc/varnish/secret  \   -­‐s  malloc,256m" In  “/etc/default/varnish”

Slide 31

Slide 31 text

backend  default  {              .host  =  "127.0.0.1";              .port  =  "8080";   } In  “/etc/varnish/default.vcl”

Slide 32

Slide 32 text

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”

Slide 33

Slide 33 text

proxy_cache_path  /tmp/  levels=1:2   keys_zone=proxy-­‐cache:10m  inactive=5m   max_size=1024; Add  to   “/etc/nginx/nginx.conf”

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

✓mod_php ✓mod_fcgid & php-cgi ✓mod_proxy_fcgi & php-fpm ✓Behind Varnish & Nginx

Slide 37

Slide 37 text

✓Native fastcgi proxying for php-fpm ✓Cacheable

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

Nginx PHP-FPM Client Webserver     &     caching  proxy

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

What about ?

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

;  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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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.

Slide 46

Slide 46 text

What about ?

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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;          }   }

Slide 49

Slide 49 text

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);   }

Slide 50

Slide 50 text

$>  ./node_modules/wscat/bin/wscat  -­‐-­‐connect  ws://localhost   connected  (press  CTRL+C  to  quit)   >  test      <  Server  received  from  client:  test Websocket  client

Slide 51

Slide 51 text

Out of the box

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

✓POST, DELETE & PUT ✓“no-cache", "no-store", "private” ✓set-cookie headers ✓cache ttl <= 0 ✓X-Accel-Expires: 0 Nginx wil not cache

Slide 55

Slide 55 text

About cookies

Slide 56

Slide 56 text

About cookies HTTP cookie request header via browser HTTP set-cookie response header via webserver

Slide 57

Slide 57 text

set  $bypass  0;   if  ($http_cookie)  {   set  $bypass  1;   }   fastcgi_cache_bypass  $bypass;   fastcgi_no_cache  $bypass; Nginx caches cookies by default

Slide 58

Slide 58 text

Monitoring & Logging

Slide 59

Slide 59 text

access_log error_log

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

✓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

Slide 62

Slide 62 text

varnishstat varnishlog varnishtop

Slide 63

Slide 63 text

Varnishstat Continuously updated state of the server

Slide 64

Slide 64 text

No content

Slide 65

Slide 65 text

Varnishlog In memory activity log

Slide 66

Slide 66 text

*      <<  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  

Slide 67

Slide 67 text

-­‐      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  

Slide 68

Slide 68 text

*      <<  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  

Slide 69

Slide 69 text

-­‐      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  

Slide 70

Slide 70 text

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'

Slide 71

Slide 71 text

Varnishtop Continuously updated list of incremental data

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

The flow

Slide 74

Slide 74 text

No content

Slide 75

Slide 75 text

*      <<  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?

Slide 76

Slide 76 text

Cache key

Slide 77

Slide 77 text

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);   }

Slide 78

Slide 78 text

Cache key fastcgi_cache_key  "$scheme://$host$request_uri";   proxy_cache_key  "$scheme://$host$request_uri";

Slide 79

Slide 79 text

Hashing cookies

Slide 80

Slide 80 text

Hashing cookies sub  vcl_hash  {   if(req.http.Cookie  ~  "country"){   hash_data(regsub(req.http.Cookie,   ".*country=([^;]+);.*","\1"));      }   }

Slide 81

Slide 81 text

Hashing cookies proxy_cache_key  “$scheme://$host$request_uri $cookie_country";   fastcgi_cache_key  "$scheme://$host$request_uri $cookie_country";

Slide 82

Slide 82 text

Cache purging

Slide 83

Slide 83 text

Purge config sub  vcl_recv  {          if  (req.method  ==  "PURGE")  {                  return(purge);          }   }

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

Purge/ban execution curl  -­‐X  PURGE  http://varnish.dev/your-­‐page $  varnishadm   varnish>   varnish>  ban  req.url  ==  "/"   200 Or  via  telnet

Slide 86

Slide 86 text

Purge grep  -­‐lr  'http://host.dev/test.php'  /tmp/cache/*  |  xargs   rm

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

Purge execution curl  -­‐X  PURGE  http://varnish.dev/your-­‐page

Slide 90

Slide 90 text

Loadbalancing

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

✓Round-robin ✓Random ✓Hash ✓Fallback Directors

Slide 94

Slide 94 text

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

Slide 95

Slide 95 text

…   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

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

upstream backend { server backend1.example.com weight=5; server backend2.example.com:8080; server unix:/tmp/backend3; } server { location / { proxy_pass http://backend; } } Random

Slide 98

Slide 98 text

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

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

HIT/MISS marker

Slide 101

Slide 101 text

sub  vcl_deliver  {      if  (obj.hits  >  0)  {          set  resp.http.X-­‐Cache  =  "HIT";      }      else  {          set  resp.http.X-­‐Cache  =  "MISS";      }   } HIT/MISS marker

Slide 102

Slide 102 text

HIT/MISS marker add_header  X-­‐Cache  $upstream_cache_status;  

Slide 103

Slide 103 text

Set Time To Live

Slide 104

Slide 104 text

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

Slide 105

Slide 105 text

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

Slide 106

Slide 106 text

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

Slide 107

Slide 107 text

Force TTL sub  vcl_backend_response  {          if(bereq.url  ~  "^/bla")  {                  set  beresp.ttl  =  10s;          }  else  {                  set  beresp.ttl  =  3600s;          }   }

Slide 108

Slide 108 text

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

Slide 109

Slide 109 text

Edge Side Includes

Slide 110

Slide 110 text

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

Slide 111

Slide 111 text

Slide 112

Slide 112 text

Slide 113

Slide 113 text

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;          }   }  

Slide 114

Slide 114 text

h&ps://github.com/taf2/nginx-­‐esi Not  official Haven’t   tested  it  yet Edge Side Includes

Slide 115

Slide 115 text

Edge Side Includes Server Side Includes

Slide 116

Slide 116 text

Highest  TTL   is  used

Slide 117

Slide 117 text

server  {   …     ssi  on;   …   }

Slide 118

Slide 118 text

SSL support

Slide 119

Slide 119 text

Varnish doesn’t support SSL

Slide 120

Slide 120 text

Nginx supports SSL (& SPDY)

Slide 121

Slide 121 text

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

Slide 122

Slide 122 text

Who won the battle? Varnish Nginx

Slide 123

Slide 123 text

And  on   that   bombshell  ...

Slide 124

Slide 124 text

No content