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

Varnish In Action

Varnish In Action

Slides for my Varnish talk at PHP North West 2012

Thijs Feryn

October 06, 2012
Tweet

More Decks by Thijs Feryn

Other Decks in Technology

Transcript

  1. View Slide

  2. Hi  
    my  name  
    is  Thijs

    View Slide

  3. I’m  
    an  evangelist  at

    View Slide

  4. I’m  
    a  board  member  
    at

    View Slide

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

    View Slide

  6. View Slide

  7. h"p://joind.in/6949
    Please  
    give  me  
    feedback

    View Slide

  8. View Slide

  9. Varnish ?

    View Slide

  10. Cache?

    View Slide

  11. Reverse proxy?

    View Slide

  12. Loadbalancer?

    View Slide

  13. Loadbalancer?
    HTTP accelerator

    View Slide

  14. In  front  of  the  
    webserver

    View Slide

  15. Primary  purpose
    Caching

    View Slide

  16. Reverse  caching  
    proxy

    View Slide

  17. View Slide

  18. View Slide

  19. What can we cache?

    View Slide

  20. ✓Static files
    ✓Dynamic pages
    ✓Webservices

    View Slide

  21. View Slide

  22. View Slide

  23. Expires:  Sun,  25  Jun  2006  14:57:12  
    Cache-­‐Control:  max-­‐age=86400,  
    must-­‐revalidate
    Expira>on

    View Slide

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

    View Slide

  25. 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

    View Slide

  26. Browser cache is your friend

    View Slide

  27. Confusion?!

    View Slide

  28. Multiple
    standards

    View Slide

  29. Can be
    ignored by the
    browser

    View Slide

  30. Force
    refresh

    View Slide

  31. Cache per
    client

    View Slide

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

    View Slide

  33. Install &
    configure

    View Slide

  34. 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

    View Slide

  35. 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

    View Slide

  36. Backend

    View Slide

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

    View Slide

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

    View Slide

  39. Out of the box

    View Slide

  40. View Slide

  41. Only get & HEAD
    No cookie & auth headers
    No set-cookie headers
    cache ttl > 0
    No vary “*”
    When will varnish cache?

    View Slide

  42. About cookies

    View Slide

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

    View Slide

  44. based on host/ip + urL hash
    By default in Memory
    Optionally on disk
    how will varnish cache?

    View Slide

  45. Request vcl_recv
    In cache?
    vcl_hash Cacheable?
    vcl_hit() vcl_miss()
    vcl_deliver()
    vcl_fetch()
    No
    Yes
    No
    Yes
    Response

    View Slide

  46. View Slide

  47. Monitoring
    &
    Logging

    View Slide

  48. Varnishstat
    ✓General stats
    ✓Realtime

    View Slide

  49. 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

    View Slide

  50. Varnishlog
    ✓In-memory logs of
    Varnish activity
    ✓Tag based

    View Slide

  51.      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

    View Slide

  52. 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

    View Slide

  53. Varnishtop
    ✓Incremental
    ✓Continuously updated
    ✓In-memory
    ✓Tag based

    View Slide

  54. 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;)

    View Slide

  55. Examples
    varnishtop  -­‐i  RxHeader  -­‐I  \^User-­‐Agent
    varnishtop  -­‐i  RxRequest
    varnishtop  -­‐i  RxHeader  -­‐I  \^Host
    varnishtop  -­‐i  RxHeader  -­‐I  Cookie

    View Slide

  56. Varnishncsa
    ✓Access logs
    ✓Apache format
    ✓For analytics

    View Slide

  57. 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"

    View Slide

  58. Telnet  management
    [email protected]:/#  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.

    View Slide

  59. Telnet  management
    vcl.load    
    vcl.use  
    vcl.discard  
    vcl.list
    vcl.show

    View Slide

  60. READY FOR
    ACTION?

    View Slide

  61. Request vcl_recv
    In cache?
    vcl_hash Cacheable?
    vcl_hit() vcl_miss()
    vcl_deliver()
    vcl_fetch()
    No
    Yes
    No
    Yes
    Response

    View Slide

  62. Out of the box

    View Slide

  63. #  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);
    #  }

    View Slide

  64. #  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);
    #  }

    View Slide

  65. Construct your own vcl

    View Slide

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

    View Slide

  67. 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";
       }
    }

    View Slide

  68. Set  TTL
    sub  vcl_fetch  {
           if(req.url  ~  "^/bla")  {
                   set  beresp.ttl  =  10s;
           }  else  {
                   set  beresp.ttl  =  3600s;
           }
    }

    View Slide

  69. Expiration
    1.Vcl (beresp.ttl)
    2.Cache-control s-maxage
    3.Cache-control max-age
    4.Expires

    View Slide

  70. Remove  client  cookies
    sub  vcl_recv  {
           unset  req.http.cookie;
    }
    Remove  server  cookies
    sub  vcl_fetch  {
           unset  beresp.http.set-­‐cookie;
    }

    View Slide

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

    View Slide

  72. Ignore  cookies
    sub  vcl_recv  {
         if  (req.request  ==  "GET"  ||  req.request  ==  
    "HEAD")  {
             return  (lookup);
         }
    }
    Ignores  default  behaviour

    View Slide

  73. 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

    View Slide

  74. 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"));
       }
    }

    View Slide

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

    View Slide

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

    View Slide

  77. Director  for  load  balancing
    director  back  random  {
       {.backend  =  default;  .weight=1;}
       {.backend  =  other;  .weight=2;}
    }
    sub  vcl_recv  {
       set  req.backend  =  back;
       return(pass);
    }

    View Slide

  78. Directors
    ✓Round-robin
    ✓Random
    ✓Hash
    ✓Dns
    ✓Client
    ✓Fallback

    View Slide

  79. 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

    View Slide

  80. 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  h]p://yoursite.com/yourpage

    View Slide

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

    View Slide

  82. Purge  &  vcl_hash
    Doesn’t  work  with  custom  vcl_hash
    sub  vcl_hash  {
       if(req.http.Cookie  ~  "country"){
                       hash_data(req.http.Cookie);
       }
    }

    View Slide

  83. 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.";
       }
    }

    View Slide

  84. Vary header
    Vary:  Cookie
    Tells the proxy what extra fields
    to use for caching
    Remove  
    unnecessary  cookies  in  
    vcl_recv
    Watch  
    out  for  browser  
    cache

    View Slide

  85. Vary header
    Vary:  X-­‐Cookie
    Don’t vary the cookie or
    Internet Explorer will go nuts
    Vary  on  
    custom  header

    View Slide

  86. Vary header
    sub  vcl_recv  {
         set  req.http.X-­‐Cookie  =  req.http.cookie
    }

    View Slide

  87. More action?

    View Slide

  88. Edge Side Includes

    View Slide

  89. header.php
    menu.php main.php
    footer.php

    View Slide





















  90. View Slide

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

    View Slide




















  92. View Slide




















  93. View Slide

  94. 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 "".PHP_EOL;
    } else {
    include($file);
    }
    }
    ESI  PHP  helper  funcXon

    View Slide

  95. include('esi.php');
    ?>




















    View Slide

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

    View Slide

  97. View Slide

  98. h"p://joind.in/6949
    Please  
    give  me  
    feedback

    View Slide

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

    View Slide

  100. Thanks

    View Slide

  101. View Slide