Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Reverse caching proxies: Varnish or Nginx? - ph...

Thijs Feryn
February 19, 2015

Reverse caching proxies: Varnish or Nginx? - phpuk15

Slides for my Varnish vs Nginx talk at PHPUK conference 2015

Thijs Feryn

February 19, 2015
Tweet

More Decks by Thijs Feryn

Other Decks in Technology

Transcript

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

    balancing ✓ Caching ✓ Compression
  2. Proxy Webserver PHP runtime Client Webserver   thinks  it’s  a

     browser Browser  things   it’s  a  webserver
  3. What’s not cacheable ✓HTTP POST, PUT, DELETE ✓ Cookie &

    Set-Cookie headers ✓ Authorization ✓ TTL == 0
  4. 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)
  5. 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
  6. 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
  7. 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
  8. DAEMON_OPTS="-­‐a  :80  \   -­‐T  localhost:6082  \   -­‐f  /etc/varnish/default.vcl

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

     =  "127.0.0.1";              .port  =  "8080";   } In  “/etc/varnish/default.vcl”
  10. 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”
  11. 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
  12. 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
  13. ;  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
  14. 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
  15. 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.
  16. 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
  17. 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;          }   }
  18. 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);   }
  19. $>  ./node_modules/wscat/bin/wscat  -­‐-­‐connect  ws://localhost   connected  (press  CTRL+C  to  quit)

      >  test      <  Server  received  from  client:  test Websocket  client
  20. ✓POST, DELETE & PUT ✓cookies & auth headers ✓set-cookie headers

    ✓“no-cache", "no-store", „private” in v4 Varnish wil not cache
  21. set  $bypass  0;   if  ($http_cookie)  {   set  $bypass

     1;   }   fastcgi_cache_bypass  $bypass;   fastcgi_no_cache  $bypass; Nginx caches cookies by default
  22. 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
  23. ✓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
  24. *      <<  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  
  25. -­‐      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  
  26. *      <<  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  
  27. -­‐      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  
  28. 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'
  29. 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
  30. *      <<  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?
  31. 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);   }
  32. Hashing cookies sub  vcl_hash  {   if(req.http.Cookie  ~  "country"){  

    hash_data(regsub(req.http.Cookie,   ".*country=([^;]+);.*","\1"));      }   }
  33. Purge config sub  vcl_recv  {          if

     (req.method  ==  "PURGE")  {                  return(purge);          }   }
  34. 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
  35. 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
  36. 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
  37. 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
  38. 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
  39. 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
  40. …   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
  41. 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
  42. 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
  43. sub  vcl_deliver  {      if  (obj.hits  >  0)  {

             set  resp.http.X-­‐Cache  =  "HIT";      }      else  {          set  resp.http.X-­‐Cache  =  "MISS";      }   } HIT/MISS marker
  44. Force TTL sub  vcl_backend_response  {          if(bereq.url

     ~  "^/bla")  {                  set  beresp.ttl  =  10s;          }  else  {                  set  beresp.ttl  =  3600s;          }   }
  45. 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
  46. <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>
  47. <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>
  48. 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;          }   }  
  49. <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
  50. 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