Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

Hi   my  name   is  Thijs

Slide 3

Slide 3 text

I’m   an  evangelist  at

Slide 4

Slide 4 text

I’m   a  board  member   at

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

We all know Varnish Right?

Slide 8

Slide 8 text

Install it We know how to Right?

Slide 9

Slide 9 text

Configure it We know how to Right?

Slide 10

Slide 10 text

Work with vcl We know how to Right?

Slide 11

Slide 11 text

WTF?

Slide 12

Slide 12 text

Quick reminder!

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

Backend

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

The rules ✓Use  appropriate  cache-­‐control  headers ✓Use  s-­‐maxage  for  expira/on ✓Use  Surrogate-­‐Capability  &  Surrogate-­‐ Control  headers  for  ESI  based  block  caching ✓Avoid  using  cookies  for  cached  pages ✓Use  vary  headers  to  extend  the  hash ✓Only  cache  GET  or  HEAD ✓Use  consistent  URL’s

Slide 22

Slide 22 text

No  clue

Slide 23

Slide 23 text

Don’t give a sh*t

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

I  work  in  the Hosting Industry

Slide 26

Slide 26 text

We  don’t  get  to  choose the  code we  work   with

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

Things I learned the hard way

Slide 29

Slide 29 text

Things I’ve learned ✓Varnish  default  behaviour  is  bypassed  with   “return” ➡set-­‐cookie,  cookie,  max-­‐age,  post,  ... ✓beresp.Dl  >  cache-­‐control:  max-­‐age ✓No  cache  headers  are  ignored  (except  max-­‐ age=0) ✓Purge  doesn’t  work  with  custom  vcl_hash ✓Vary  is  supported ✓There’s  a  hit  for  pass  cache

Slide 30

Slide 30 text

Out of the box

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

Custom code

Slide 37

Slide 37 text

State is our enemy

Slide 38

Slide 38 text

Cookies

Slide 39

Slide 39 text

Cookies HTTP cookie request header via browser HTTP set-cookie response header via webserver

Slide 40

Slide 40 text

We use cookies for ✓Sessions ✓Google  Analy/cs ✓Language   preferences

Slide 41

Slide 41 text

What do we do?

Slide 42

Slide 42 text

Nothing!

Slide 43

Slide 43 text

Remove cookies

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

Remove  some  cookies sub  vcl_recv  { if  (req.http.Cookie)  { set  req.http.Cookie  =   regsuball(req.http.Cookie,  "(^|;\s*)(__[a-­‐z]+| has_js)=[^;]*",  "");*","\1");          if  (req.http.Cookie  ==  "")  {                remove  req.http.Cookie;        } }

Slide 46

Slide 46 text

Ignore cookies

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

Add cookie to hash

Slide 49

Slide 49 text

Add  a  specific  cookie  to  hash sub  vcl_recv  {      if  (!req.http.Cookie  ~  "lang")  {              return(pass);      } } sub  vcl_hash  {    if(req.http.Cookie  ~  "lang"){                    hash_data(regsuball(req.http.Cookie,  "^.+;?  ? lang=([a-­‐zA-­‐Z0-­‐9]+)(  |;|  ;).*$","\1"));    } }

Slide 50

Slide 50 text

To the drawing board Because there’s always something custom

Slide 51

Slide 51 text

  #CACHE  STATIC  FILES       if  (req.url  ~  "\.(gif|jpg|jpeg|swf|flv|mp3|mp4|pdf|ico|png|gz| tgz|bz2)(\?.*|)$")  {             unset  req.http.cookie;             set  req.url  =  regsub(req.url,  "\?.*$",  "");             return  (lookup);       }   #DON'T  CACHE  THESE   if(req.url  ~  "^/(nl|fr)/(product|contest)([0-­‐9]*)-­‐mail"){     return(pass);   }   if(req.url  ~  "^/sales"){     return(pass);   }   if(req.url  ~  "^/redeem-­‐voucher"){     return(pass);   }       if  (req.url  ~  "^/wp-­‐(login|admin|signup)"  ||  req.url  ~   "preview=true"  ||  req.url  ~  "^/xmlrpc.php"  ||  req.url  ~  "^/admin-­‐ ajax.php")  {       return(pass);   }       #DON'T  CACHE  AUTH          if  (req.http.Authorization)  {                   return  (pass);           } vcl_recv

Slide 52

Slide 52 text

  #KEEP  LANGUAGE  COOKIE   if(req.http.Cookie  ~  "lang"){     set  req.http.Cookie  =  ";"  +  req.http.Cookie;     set  req.http.Cookie  =  regsuball(req.http.Cookie,  ";  +",   ";");             set  req.http.Cookie  =  regsuball(req.http.Cookie,  "; (lang)=",  ";  \1=");             set  req.http.Cookie  =  regsuball(req.http.Cookie,  ";[^  ] [^;]*",  "");             set  req.http.Cookie  =  regsuball(req.http.Cookie,  "^[;  ]+| [;  ]+$",  "");   }     #GET  FROM  CACHE           return  (lookup); vcl_recv

Slide 53

Slide 53 text

  #IF  LANG  COOKIE  IS  SET,  ADD  IT  TO  THE  HASH          if(req.http.Cookie  ~  "lang"){                   hash_data(regsuball(req.http.Cookie,  "^. +;?  ?(lang=[a-­‐zA-­‐Z0-­‐9]+)(  |;|  ;).*$","\1"));          } vcl_hash

Slide 54

Slide 54 text

Or just use the vary header

Slide 55

Slide 55 text

  #PUT  THESE  ON  THE  HIT  FOR  PASS  BLACKLIST   if  (req.url  ~  "^/wp-­‐(login|admin|signup)"  ||   req.url  ~  "preview=true"  ||  req.url  ~  "^/ xmlrpc.php"  ||  req.url  ~  "^/admin-­‐ajax.php")  {           return  (hit_for_pass);   }     #DEFINE  TIME  TO  LIVE   if(req.url  ~  "^/(nl|fr)/(sendlist|orders)? ordercode=(.+)"){     set  beresp.ttl  =  600s;   }  else  {     set  beresp.ttl  =  3600s;   } vcl_fetch

Slide 56

Slide 56 text

No content

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

Devolution

Slide 60

Slide 60 text

Devolution ✓BeDer  frameworks ✓CMS  framework  adop/on ✓Smarter  developers ✓DevOps  evangeliza/on

Slide 61

Slide 61 text

Page cache Already using a

Slide 62

Slide 62 text

Stale data They know about

Slide 63

Slide 63 text

They use

Slide 64

Slide 64 text

Or esi

Slide 65

Slide 65 text

Surrogate Capability Surrogate Control

Slide 66

Slide 66 text

CDN Replacing a

Slide 67

Slide 67 text

No content

Slide 68

Slide 68 text

No content

Slide 69

Slide 69 text

Thanks