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

Transcript

  1. 1.
  2. 9.
  3. 11.
  4. 12.
  5. 13.
  6. 20.
  7. 21.
  8. 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
  9. 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
  10. 26.
  11. 27.
  12. 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
  13. 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
  14. 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
  15. 41.
  16. 43.

    backend  default  {            .host  =

     "127.0.0.1";            .port  =  "8080"; } In  “/etc/varnish/default.vcl” Backend
  17. 45.
  18. 46.

    Only get & HEAD No cookie & auth headers No

    set-cookie headers cache ttl > 0 No vary “*” When will varnish cache?
  19. 49.

    based on host/ip + urL hash By default in Memory

    Optionally on disk how will varnish cache?
  20. 51.
  21. 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
  22. 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
  23. 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
  24. 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
  25. 60.

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

     -­‐i  RxHeader  -­‐I  \^Host varnishtop  -­‐i  RxHeader  -­‐I  Cookie
  26. 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;)
  27. 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"
  28. 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.
  29. 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); #  }
  30. 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); #  }
  31. 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);    } }
  32. 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";    } }
  33. 74.

    Set  TTL sub  vcl_fetch  {        if(req.url  ~

     "^/bla")  {                set  beresp.ttl  =  10s;        }  else  {                set  beresp.ttl  =  3600s;        } }
  34. 76.

    Remove  client  cookies sub  vcl_recv  {        unset

     req.http.cookie; } Remove  server  cookies sub  vcl_fetch  {        unset  beresp.http.set-­‐cookie; }
  35. 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;        } }
  36. 78.

    Ignore  cookies sub  vcl_recv  {      if  (req.request  ==

     "GET"  ||  req.request  ==   "HEAD")  {          return  (lookup);      } } Ignores  default  behaviour
  37. 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
  38. 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"));    } }
  39. 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;        } }
  40. 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;        } }
  41. 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); }
  42. 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
  43. 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
  44. 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); }
  45. 88.

    Purge  &  vcl_hash Doesn’t  work  with  custom  vcl_hash sub  vcl_hash

     {    if(req.http.Cookie  ~  "country"){                    hash_data(req.http.Cookie);    } }
  46. 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.";    } }
  47. 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>
  48. 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>
  49. 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>
  50. 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
  51. 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>
  52. 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;        } }  
  53. 100.
  54. 103.
  55. 104.