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

Varnish In Action

Ca901ddcea38854b9783781c91fc87c9?s=47 Thijs Feryn
September 29, 2012

Varnish In Action

Slides for my Varnish talk at PHPCon Poland 2012

Ca901ddcea38854b9783781c91fc87c9?s=128

Thijs Feryn

September 29, 2012
Tweet

More Decks by Thijs Feryn

Other Decks in Technology

Transcript

  1. None
  2. Hi   my  name   is  Thijs

  3. I’m  from   Belgium

  4. Atomium Brussels

  5. Rozenhoedkaai Bruges

  6. Graslei Ghent

  7. I’m   an  evangelist  at

  8. I’m   a  board  member   at

  9. None
  10. h"p://joind.in/7186 Please   give  me   feedback

  11. None
  12. Varnish ?

  13. Cache?

  14. Reverse proxy?

  15. Loadbalancer?

  16. Loadbalancer? HTTP accelerator

  17. In  front  of  the   webserver

  18. Primary  purpose Caching

  19. Reverse  caching   proxy

  20. None
  21. None
  22. GET  /2012/pl/  HTTP/1.1 Host:  phpcon.pl User-­‐Agent:  Mozilla/5.0  (Macintosh;  Intel  Mac

     OS  X  10.8;   rv:15.0)  Gecko/20100101  Firefox/15.0.1 Accept:  text/html,application/xhtml+xml,application/ xml;q=0.9,*/*;q=0.8 Accept-­‐Language:  nl,en;q=0.7,fr-­‐be;q=0.3 Accept-­‐Encoding:  gzip,  deflate Connection:  keep-­‐alive Cookie:  sid=b4f70ee35d6ccc20c455ead826f7a7f716801000 Cache-­‐Control:  max-­‐age=0 HTTP request
  23. HTTP/1.1  200  OK Date:  Thu,  27  Sep  2012  08:21:47  GMT

    Server:  Apache Set-­‐Cookie:   sid=b4f70ee35d6ccc20c455ead826f7a7f716801000;   expires=Thu,  27-­‐Sep-­‐2012  09:21:47  GMT;  path=/;   domain=phpcon.pl Expires:  Thu,  19  Nov  1981  08:52:00  GMT Cache-­‐Control:  no-­‐store,  no-­‐cache,  must-­‐revalidate,   post-­‐check=0,  pre-­‐check=0 Pragma:  no-­‐cache Keep-­‐Alive:  timeout=5,  max=100 Connection:  Keep-­‐Alive Transfer-­‐Encoding:  chunked Content-­‐Type:  text/html;  charset=utf-­‐8 HTTP response
  24. What can we cache?

  25. ✓Static files ✓Dynamic pages ✓Webservices

  26. None
  27. None
  28. Expires:  Sun,  25  Jun  2006  14:57:12   Cache-­‐Control:  max-­‐age=86400,  

    must-­‐revalidate Expira>on
  29. Last-­‐Modified:  Sun,  25  Jun  2006  14:57:12  GMT ETag:  “686897696a7c876b7e” Invalida>on

  30. Last-­‐Modified:  Sun,  25  Jun  2006  14:57:12  GMT ETag:  “686897696a7c876b7e” Compared

     with  the  “If-­‐None-­‐ Match”  header.  Throws  “HTTP/1.0  304   Not  Modified”  accordingly Invalida>on
  31. Browser cache is your friend

  32. Confusion?!

  33. Multiple standards

  34. Can be ignored by the browser

  35. Force refresh

  36. Cache per client

  37. Choose Varnish http:// www.varnish-­‐ cache.org

  38. Install & configure

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

     "deb  http://repo.varnish-­‐cache.org/ debian/  squeeze  varnish-­‐3.0"  >>  /etc/apt/ sources.list apt-­‐get  install  varnish
  40. DAEMON_OPTS="-­‐a  :80  \ -­‐T  localhost:6082  \ -­‐f  /etc/varnish/default.vcl  \ -­‐S

     /etc/varnish/secret  \ -­‐s  malloc,256m" In  “/etc/default/varnish” Install & configure
  41. Backend

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

  43. backend  default  {            .host  =

     "127.0.0.1";            .port  =  "8080"; } In  “/etc/varnish/default.vcl” Backend
  44. Out of the box

  45. None
  46. Only get & HEAD No cookie & auth headers No

    set-cookie headers cache ttl > 0 No vary “*” When will varnish cache?
  47. About cookies

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

    response header via webserver
  49. based on host/ip + urL hash By default in Memory

    Optionally on disk how will varnish cache?
  50. Request vcl_recv In cache? vcl_hash Cacheable? vcl_hit() vcl_miss() vcl_deliver() vcl_fetch()

    No Yes No Yes Response
  51. None
  52. Monitoring & Logging

  53. Varnishstat ✓General stats ✓Realtime

  54. 4+05:26:25 Hitrate  ratio:              10

               100            254 Hitrate  avg:          0.8486      0.7619      0.7285          1760818                  6.99                  4.82  client_conn  -­‐  Client  connections  accepted        11088687                25.96                30.36  client_req  -­‐  Client  requests  received          8042715                11.98                22.02  cache_hit  -­‐  Cache  hits          2609561                11.98                  7.15  cache_miss  -­‐  Cache  misses              47104                  1.00                  0.13  backend_conn  -­‐  Backend  conn.  success                  610                  0.00                  0.00  backend_fail  -­‐  Backend  conn.  failures          2998265                12.98                  8.21  backend_reuse  -­‐  Backend  conn.  reuses              12081                  0.00                  0.03  backend_toolate  -­‐  Backend  conn.  was  closed          3010356                13.98                  8.24  backend_recycle  -­‐  Backend  conn.  recycles                    13                  0.00                  0.00  backend_retry  -­‐  Backend  conn.  retry                  520                  0.00                  0.00  fetch_head  -­‐  Fetch  head          2857965                11.98                  7.83  fetch_length  -­‐  Fetch  with  Length            151309                  2.00                  0.41  fetch_chunked  -­‐  Fetch  chunked                4404                  0.00                  0.01  fetch_close  -­‐  Fetch  wanted  close                  676                  0.00                  0.00  fetch_failed  -­‐  Fetch  failed              31164                  0.00                  0.09  fetch_304  -­‐  Fetch  no  body  (304)                  220                    .                        .      n_sess_mem  -­‐  N  struct  sess_mem                    53                    .                        .      n_sess  -­‐  N  struct  sess              29540                    .                        .      n_object  -­‐  N  struct  object              29561                    .                        .      n_objectcore  -­‐  N  struct  objectcore                5058                    .                        .      n_objecthead  -­‐  N  struct  objecthead                2613                    .                        .      n_waitinglist  -­‐  N  struct  waitinglist                      3                    .                        .      n_vbc  -­‐  N  struct  vbc                    22                    .                        .      n_wrk  -­‐  N  worker  threads                1789                  0.00                  0.00  n_wrk_create  -­‐  N  worker  threads  created
  55. Varnishlog ✓In-memory logs of Varnish activity ✓Tag based

  56. ✓RxHeader ✓RxLostHeader ✓RxProtocol ✓RxRequest ✓RxResponse ✓RxStatus ✓RxURL ✓TxHeader ✓TxLostHeader ✓TxProtocol

    ✓TxRequest ✓TxResponse ✓TxStatus ✓TxURL ✓ReqEnd ✓ReqStart ✓Hit ✓Error ✓VCL_call ✓VCL_return ✓VCL_acl Notable tags
  57. Examples varnishlog  -­‐c  -­‐m"VCL_call:hit"  |  grep  RxURL varnishlog  -­‐c  -­‐m"VCL_call:miss"

     |  grep  RxURL varnishlog  -­‐a  -­‐w  /tmp/varnish.log varnishlog  -­‐r  /tmp/varnish.log varnishlog  -­‐i  RxHeader  -­‐I  Cookie
  58.      12  SessionOpen    c  172.16.26.1  50396  :8080  

       12  ReqStart          c  172.16.26.1  50396  668213522      12  RxRequest        c  GET      12  RxURL                c  /test.php      12  RxProtocol      c  HTTP/1.1      12  RxHeader          c  Host:  varnish.dev:8080      12  RxHeader          c  User-­‐Agent:  Mozilla/5.0  (Macintosh;  U;  Intel  Mac  OS  X  10.6;  nl;   rv:1.9.2.10)  Gecko/20100914  Firefox/3.6.10      12  RxHeader          c  Accept:  text/html,application/xhtml+xml,application/xml;q=0.9,*/ *;q=0.8      12  RxHeader          c  Accept-­‐Language:  nl,en-­‐us;q=0.7,en;q=0.3      12  RxHeader          c  Accept-­‐Encoding:  gzip,deflate      12  RxHeader          c  Accept-­‐Charset:  ISO-­‐8859-­‐1,utf-­‐8;q=0.7,*;q=0.7      12  RxHeader          c  Keep-­‐Alive:  115      12  RxHeader          c  Connection:  keep-­‐alive      12  RxHeader          c  Cookie:  PHPSESSID=2n2pkit81qdgk6k4trf1crft16      12  VCL_call          c  recv      12  VCL_return      c  pass      12  VCL_call          c  hash      12  VCL_return      c  hash      12  VCL_call          c  pass      12  VCL_return      c  pass      14  BackendClose  -­‐  default      14  BackendOpen    b  default  127.0.0.1  34267  127.0.0.1  80      12  Backend            c  14  default  default
  59. Varnishtop ✓Incremental ✓Continuously updated ✓In-memory ✓Tag based

  60. Examples varnishtop  -­‐i  RxHeader  -­‐I  \^User-­‐Agent varnishtop  -­‐i  RxRequest varnishtop

     -­‐i  RxHeader  -­‐I  \^Host varnishtop  -­‐i  RxHeader  -­‐I  Cookie
  61. list  length  20      107.57  RxHeader      

           User-­‐Agent:  Mozilla/5.0  (Windows  NT  6.1;  W      101.96  RxHeader              User-­‐Agent:  Mozilla/5.0  (Windows  NT  6.1;  W        82.49  RxHeader              User-­‐Agent:  Mozilla/4.0  (compatible;  MSIE          69.90  RxHeader              User-­‐Agent:  Mozilla/5.0  (compatible;  MSIE          64.04  RxHeader              User-­‐Agent:  Mozilla/5.0  (Windows  NT  6.1;  W        43.74  RxHeader              User-­‐Agent:  Mozilla/4.0  (compatible;  MSIE          22.01  RxHeader              User-­‐Agent:  Mozilla/5.0  (iPod;  U;  CPU  iPho        21.43  RxHeader              User-­‐Agent:  Mozilla/4.0  (compatible;  MSIE          19.86  RxHeader              User-­‐Agent:  Mozilla/5.0  (X11;  Linux  x86_64        15.47  RxHeader              User-­‐Agent:  Mozilla/5.0  (Windows  NT  6.1;  W        12.96  RxHeader              User-­‐Agent:  Mozilla/5.0  (Windows  NT  6.1;  W          4.87  RxHeader              User-­‐Agent:  Mozilla/4.0  (compatible;  MSIE            2.97  RxHeader              User-­‐Agent:  Mozilla/5.0  (compatible;  MSIE            2.75  RxHeader              User-­‐Agent:  Mozilla/5.0  (Windows  NT  6.1;  W          2.56  RxHeader              User-­‐Agent:  Mozilla/5.0  (Windows  NT  6.1;  r          0.97  RxHeader              User-­‐Agent:  Mozilla/5.0  (Windows;  U;  Windo          0.86  RxHeader              User-­‐Agent:  Mozilla/5.0  (iPhone;  CPU  iPhon          0.83  RxHeader              User-­‐Agent:  Mozilla/5.0  (Windows;  U;  Windo          0.53  RxHeader              User-­‐Agent:  Mozilla/5.0  (compatible;  Googl          0.44  RxHeader              User-­‐Agent:  Mozilla/4.0  (compatible;)
  62. Varnishncsa ✓Access logs ✓Apache format ✓For analytics

  63. Example varnishncsa  -­‐D  -­‐a  -­‐w  /var/log/some.log 172.16.26.1  -­‐  -­‐  [19/Oct/2010:16:08:02

      +0200]  "GET  http://varnish.dev:8080/   HTTP/1.1"  200  97  "-­‐"  "Mozilla/5.0   (Macintosh;  U;  Intel  Mac  OS  X  10.6;  nl;   rv:1.9.2.10)  Gecko/20100914  Firefox/ 3.6.10"
  64. Telnet  management root@dev:/#  telnet  localhost  6082 Trying  ::1... Connected  to

     localhost. Escape  character  is  '^]'. 200  154           -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ Varnish  HTTP  accelerator  CLI. -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ Type  'help'  for  command  list. Type  'quit'  to  close  CLI  session.
  65. Telnet  management vcl.load  <configname>  <filename> vcl.use  <configname> vcl.discard  <configname> vcl.list

    vcl.show
  66. READY FOR ACTION?

  67. Request vcl_recv In cache? vcl_hash Cacheable? vcl_hit() vcl_miss() vcl_deliver() vcl_fetch()

    No Yes No Yes Response
  68. Out of the box

  69. #  sub  vcl_recv  { #          if

     (req.restarts  ==  0)  { #              if  (req.http.x-­‐forwarded-­‐for)  { #                      set  req.http.X-­‐Forwarded-­‐For  = #                              req.http.X-­‐Forwarded-­‐For  +  ",  "  +  client.ip; #              }  else  { #                      set  req.http.X-­‐Forwarded-­‐For  =  client.ip; #              } #          } #          if  (req.request  !=  "GET"  && #              req.request  !=  "HEAD"  && #              req.request  !=  "PUT"  && #              req.request  !=  "POST"  && #              req.request  !=  "TRACE"  && #              req.request  !=  "OPTIONS"  && #              req.request  !=  "DELETE")  { #                  /*  Non-­‐RFC2616  or  CONNECT  which  is  weird.  */ #                  return  (pipe); #          } #          if  (req.request  !=  "GET"  &&  req.request  !=  "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  (lookup); #  }
  70. #  sub  vcl_hash  { #          hash_data(req.url);

    #          if  (req.http.host)  { #                  hash_data(req.http.host); #          }  else  { #                  hash_data(server.ip); #          } #          return  (hash); #  } #  sub  vcl_fetch  { #          if  (beresp.ttl  <=  0s  || #                  beresp.http.Set-­‐Cookie  || #                  beresp.http.Vary  ==  "*")  { #                              /* #                                *  Mark  as  "Hit-­‐For-­‐Pass"  for  the  next  2  minutes #                                */ #                              set  beresp.ttl  =  120  s; #                              return  (hit_for_pass); #          } #          return  (deliver); #  }
  71. Construct your own vcl

  72. Cache  sta>c  files sub  vcl_recv{    if((req.request  ==  "GET"  ||

      req.request  ==  "HEAD")  &&  req.url  ~  "\. (png|gif|jpe?g|swf|css|js|html?|sstm) $"  ){            return(lookup);    }  else  {            return(pass);    } }
  73. Custom  hit/miss  marker sub  vcl_deliver  {    if  (obj.hits  >

     0)  {        set  resp.http.X-­‐Varnish-­‐Cache  =  "HIT";    }    else  {        set  resp.http.X-­‐Varnish-­‐Cache  =  "MISS";    } }
  74. Set  TTL sub  vcl_fetch  {        if(req.url  ~

     "^/bla")  {                set  beresp.ttl  =  10s;        }  else  {                set  beresp.ttl  =  3600s;        } }
  75. Expiration 1.Vcl (beresp.ttl) 2.Cache-control s-maxage 3.Cache-control max-age 4.Expires

  76. Remove  client  cookies sub  vcl_recv  {        unset

     req.http.cookie; } Remove  server  cookies sub  vcl_fetch  {        unset  beresp.http.set-­‐cookie; }
  77. Remove  GA  cookies sub  vcl_recv  { if  (req.http.Cookie)  {  

         set  req.http.Cookie  =   regsuball(req.http.Cookie,"(^|;  )  *__utm.=[^;]+;?   *","\1");          if  (req.http.Cookie  ==  "")  {                remove  req.http.Cookie;        } }
  78. Ignore  cookies sub  vcl_recv  {      if  (req.request  ==

     "GET"  ||  req.request  ==   "HEAD")  {          return  (lookup);      } } Ignores  default  behaviour
  79. Add  cookies  to  hash sub  vcl_recv  {      if

     (req.request  ==  "GET"  ||  req.request  ==  "HEAD")  {          return  (lookup);      } } sub  vcl_hash  {        hash_data(req.http.cookie); } All  cookies
  80. Add  a  specific  cookie  to  hash sub  vcl_recv  {  

       if  (!req.http.Cookie  ~  "country")  {              return(pass);      } } sub  vcl_hash  {    if(req.http.Cookie  ~  "country"){                    hash_data(regsuball(req.http.Cookie,  "^.+;?  ? country=([a-­‐zA-­‐Z0-­‐9]+)(  |;|  ;).*$","\1"));    } }
  81. Choose  a  backend backend  default  {        .host

     =  "default.server.com";        .port  =  "80"; } backend  other  {        .host  =  "other.server.com";        .port  =  "80"; } sub  vcl_recv  {        if(req.http.host  ~    "^www\."){                set  req.backend=  default;        }  else  {                set  req.backend  =  other;        } }
  82. Load  balancing backend  default  {        .host  =

     "default.server.com";        .port  =  "80";        .probe  =  {                .url  =  "/";                .timeout  =  50  ms;                .interval  =  1s;                .window  =  2;                .threshold  =  2;        } } backend  other  {        .host  =  "other.server.com";        .port  =  "80";        .probe  =  {                .url  =  "/";                .timeout  =  50  ms;                .interval  =  1s;                .window  =  2;                .threshold  =  2;        } }
  83. Director  for  load  balancing director  back  random  {    {.backend

     =  default;  .weight=1;}    {.backend  =  other;  .weight=2;} } sub  vcl_recv  {    set  req.backend  =  back;    return(pass); }
  84. Directors ✓Round-robin ✓Random ✓Hash ✓Dns ✓Client ✓Fallback

  85. Grace  mode sub  vcl_recv  {        if  (req.backend.healthy)

     {                set  req.grace  =  1s;        }  else  {                set  req.grace  =  10s;        } } Keep  reading  from   cache,  even  when  expired
  86. ACL  &  purge acl  purge  {    "localhost";    "192.0.2.1"/24;

    } sub  vcl_recv  {    if  (req.request  ==  "PURGE")  {        if  (!client.ip  ~  purge)  {            error  405  "Not  allowed.";        }        return(lookup);    } } sub  vcl_hit  {    if  (req.request  ==  "PURGE")  {        purge;        error  200  "Purged.";    } } sub  vcl_miss  {    if  (req.request  ==  "PURGE")  {        purge;        error  200  "Purged.";    } } Or  404 curl  -­‐X  PURGE  hdp://yoursite.com/yourpage
  87. Purge  &  vcl_hash Purge  only  works  with  the  standard  

    vcl_hash  implementa>on sub  vcl_hash  {        hash_data(req.url);        if  (req.http.host)  {                hash_data(req.http.host);        }  else  {                hash_data(server.ip);        }        return  (hash); }
  88. Purge  &  vcl_hash Doesn’t  work  with  custom  vcl_hash sub  vcl_hash

     {    if(req.http.Cookie  ~  "country"){                    hash_data(req.http.Cookie);    } }
  89. Ban sub  vcl_hit  {    if  (req.request  ==  "PURGE")  {

           ban("req.url  ~  "  +  req.url  +  "  &&  req.http.host  ==  "  +  req.http.host);        error  200  "Purged.";    } } sub  vcl_miss  {    if  (req.request  ==  "PURGE")  {      ban("req.url  ~  "  +  req.url  +  "  &&  req.http.host  ==  "  +  req.http.host);        error  200  "Purged.";    } }
  90. More action?

  91. Edge Side Includes

  92. header.php menu.php main.php footer.php

  93. <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>
  94. header.php menu.php main.php footer.php TTL  5s No  caching TTL  10s

    TTL  2s
  95. <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>
  96. <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>
  97. <?php function esi($file){ if(isset($_SERVER['Surrogate-Capability']) && preg_match('/^(.+)="ESI/1.0$/',$_SERVER['Surrogate-Capability'])){ header("Surrogate-Control: content='ESI/1.0'"); $url =

    'http://'. $_SERVER['HTTP_HOST'].substr($_SERVER['SCRIPT_NAME'], 0,1+strrpos($_SERVER['SCRIPT_NAME'],'/')).$file; echo "<esi:include src=\"$url\" />".PHP_EOL; } else { include($file); } } ESI  PHP  helper  funcfon
  98. <?php include('esi.php'); ?> <html> <body> <table> <tr> <td colspan="2" >

    <?php echo esi('header.php'); ?> </td> </tr> <tr> <td><?php echo esi('menu.php'); ?></td> <td><?php echo esi('main.php'); ?></td> </tr> <tr> <td colspan="2" > <?php echo esi('footer.php'); ?> </td> </tr> </table> </body> </html>
  99. ESI  VCL sub  vcl_recv  {        set  req.http.Surrogate-­‐Capability="key=ESI/1.0";

    } sub  vcl_fetch  {   if(beresp.http.Surrogate-­‐Control~"ESI/1.0")  {                  unset  beresp.http.Surrogate-­‐Control;          set  beresp.do_esi=true;        } }  
  100. None
  101. h"p://joind.in/7186 Please   give  me   feedback

  102. January 25th & 26th 2013 @phpbenelux http://phpcon.eu Antwerpen, Belgium

  103. Thanks

  104. None