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

Varnish In Action

Thijs Feryn
September 13, 2012

Varnish In Action

Slides for the Varnish In Action talk at the Belgian Drupal User Group.

Thijs Feryn

September 13, 2012
Tweet

More Decks by Thijs Feryn

Other Decks in Technology

Transcript

  1. Hi  
    my  name  
    is  Thijs

    View full-size slide

  2. I’m  
    an  evangelist  at

    View full-size slide

  3. I’m  
    a  board  member  
    at

    View full-size slide

  4. h"p://joind.in/7048
    Please  
    give  me  
    feedback

    View full-size slide

  5. Reverse proxy?

    View full-size slide

  6. Loadbalancer?

    View full-size slide

  7. Loadbalancer?
    HTTP accelerator

    View full-size slide

  8. In  front  of  the  
    webserver

    View full-size slide

  9. Primary  purpose
    Caching

    View full-size slide

  10. Reverse  caching  
    proxy

    View full-size slide

  11. GET  /  HTTP/1.1
    Host:  www.drupal.be
    Connection:  close]
    User-­‐Agent:  Mozilla/5.0  (Macintosh;  U;  Intel  Mac  OS  X  
    10_6_4;  de-­‐de)  AppleWebKit/533.16  (KHTML,  like  Gecko)  
    Version/5.0  Safari/533.16
    Accept-­‐Encoding:  gzip
    Accept-­‐Charset:  ISO-­‐8859-­‐1,UTF-­‐8;q=0.7,*;q=0.7
    Cache-­‐Control:  no-­‐cache
    Accept-­‐Language:  de,en;q=0.7,en-­‐us;q=0.3
    HTTP request

    View full-size slide

  12. Status:  HTTP/1.1  200  OK
    Date:  Mon,  03  Sep  2012  12:56:26  GMT
    Server:  Apache/2.2.9  (Debian)
    X-­‐Powered-­‐By:PHP/5.2.6-­‐1+lenny16
    X-­‐Drupal-­‐Cache:  HIT
    Etag:"1346675891-­‐1"
    X-­‐Generator:  Drupal  7  (http://drupal.org)
    Cache-­‐Control:  public,  max-­‐age=0
    Vary:  Cookie,Accept-­‐Encoding
    Content-­‐Encoding:  gzip
    Last-­‐Modified:  Mon,  03  Sep  2012  12:38:11  GMT
    Connection:  close
    Transfer-­‐Encoding:  chunked
    Content-­‐Type:  text/html;  charset=utf-­‐8
    HTTP response

    View full-size slide

  13. What can we cache?

    View full-size slide

  14. ✓Static files
    ✓Dynamic pages
    ✓Webservices

    View full-size slide

  15. Expires:  Sun,  25  Jun  2006  14:57:12  
    Cache-­‐Control:  max-­‐age=86400,  
    must-­‐revalidate
    Expira6on

    View full-size slide

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

    View full-size slide

  17. 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
    Invalida6on

    View full-size slide

  18. Browser cache is your friend

    View full-size slide

  19. Multiple
    standards

    View full-size slide

  20. Can be
    ignored by the
    browser

    View full-size slide

  21. Force
    refresh

    View full-size slide

  22. Cache per
    client

    View full-size slide

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

    View full-size slide

  24. Install &
    configure

    View full-size slide

  25. 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 full-size slide

  26. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

  29. Out of the box

    View full-size slide

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

    View full-size slide

  31. About cookies

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  35. Monitoring
    &
    Logging

    View full-size slide

  36. Varnishstat
    ✓General stats
    ✓Realtime

    View full-size slide

  37. 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 full-size slide

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

    View full-size slide

  39. ✓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

    View full-size slide

  40. 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 full-size slide

  41.      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 full-size slide

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

    View full-size slide

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

    View full-size slide

  44. 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 full-size slide

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

    View full-size slide

  46. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

  49. READY FOR
    ACTION?

    View full-size slide

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

    View full-size slide

  51. Out of the box

    View full-size slide

  52. #  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 full-size slide

  53. #  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 full-size slide

  54. Construct your own vcl

    View full-size slide

  55. Cache  sta6c  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 full-size slide

  56. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  60. 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 full-size slide

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

    View full-size slide

  62. 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 full-size slide

  63. 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 full-size slide

  64. 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 full-size slide

  65. 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 full-size slide

  66. 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 full-size slide

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

    View full-size slide

  68. 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 full-size slide

  69. 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  hcp://yoursite.com/yourpage

    View full-size slide

  70. More action?

    View full-size slide

  71. Edge Side Includes

    View full-size slide

  72. header.php
    menu.php main.php
    footer.php

    View full-size slide

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

    View full-size slide

  74. 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  funcdon

    View full-size slide

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




















    View full-size slide

  76. 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 full-size slide

  77. In Drupal
    ✓Varnish module
    ➡Supports purging
    ✓Esi module

    View full-size slide

  78. h"p://joind.in/7048
    Please  
    give  me  
    feedback

    View full-size slide