Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

Hi   my  name   is  Thijs

Slide 3

Slide 3 text

I’m  from   Belgium

Slide 4

Slide 4 text

Atomium Brussels

Slide 5

Slide 5 text

Rozenhoedkaai Bruges

Slide 6

Slide 6 text

Graslei Ghent

Slide 7

Slide 7 text

I’m   an  evangelist  at

Slide 8

Slide 8 text

I’m   a  board  member   at

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

Varnish ?

Slide 13

Slide 13 text

Cache?

Slide 14

Slide 14 text

Reverse proxy?

Slide 15

Slide 15 text

Loadbalancer?

Slide 16

Slide 16 text

Loadbalancer? HTTP accelerator

Slide 17

Slide 17 text

In  front  of  the   webserver

Slide 18

Slide 18 text

Primary  purpose Caching

Slide 19

Slide 19 text

Reverse  caching   proxy

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

What can we cache?

Slide 25

Slide 25 text

✓Static files ✓Dynamic pages ✓Webservices

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

Browser cache is your friend

Slide 32

Slide 32 text

Confusion?!

Slide 33

Slide 33 text

Multiple standards

Slide 34

Slide 34 text

Can be ignored by the browser

Slide 35

Slide 35 text

Force refresh

Slide 36

Slide 36 text

Cache per client

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

Install & configure

Slide 39

Slide 39 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 40

Slide 40 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 41

Slide 41 text

Backend

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

Out of the box

Slide 45

Slide 45 text

No content

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

About cookies

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

Monitoring & Logging

Slide 53

Slide 53 text

Varnishstat ✓General stats ✓Realtime

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

✓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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

     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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

Varnishncsa ✓Access logs ✓Apache format ✓For analytics

Slide 63

Slide 63 text

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"

Slide 64

Slide 64 text

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.

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

READY FOR ACTION?

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

Out of the box

Slide 69

Slide 69 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 70

Slide 70 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 71

Slide 71 text

Construct your own vcl

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

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

Slide 90

Slide 90 text

More action?

Slide 91

Slide 91 text

Edge Side Includes

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

Slide 94

Slide 94 text

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

Slide 95

Slide 95 text

Slide 96

Slide 96 text

Slide 97

Slide 97 text

".PHP_EOL; } else { include($file); } } ESI  PHP  helper  funcfon

Slide 98

Slide 98 text

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

No content

Slide 101

Slide 101 text

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

Slide 102

Slide 102 text

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

Slide 103

Slide 103 text

Thanks

Slide 104

Slide 104 text

No content