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

Hoe gebruikt u Varnish Cache om uw website te versnellen? - Combell partnerdag 2017

Ca901ddcea38854b9783781c91fc87c9?s=47 Thijs Feryn
October 12, 2017

Hoe gebruikt u Varnish Cache om uw website te versnellen? - Combell partnerdag 2017

Ca901ddcea38854b9783781c91fc87c9?s=128

Thijs Feryn

October 12, 2017
Tweet

Transcript

  1. Hoe gebruikt u Varnish Cache om uw website te versnellen?

    Door Thijs Feryn
  2. Trage websites sucken

  3. Web performance is een essentieel ondereel van de user experience

  4. Traag ~ down

  5. Concurrentie

  6. None
  7. None
  8. None
  9. None
  10. Zware last

  11. Mo money Mo servers

  12. Cache

  13. Herbereken niet als de data niet verandert

  14. 3 x 2 = ?

  15. None
  16. Normaal User Server

  17. Met Varnish User Varnish Server

  18. None
  19. Hallo, ik ben Thijs

  20. Ik ben @ThijsFeryn op Twitter

  21. Ik ben Evangelist bij

  22. Sinds 2004

  23. Support 2004-2007

  24. Ex-support lead 2007-2011

  25. Evangelist sinds 2011

  26. None
  27. Een beetje geschiedenis

  28. Waarom is het zo goed?

  29. Slimme kernel Trucs

  30. Slaat HTTP output op in memory*

  31. Respecteert HTTP best practices

  32. Varnish Configuration Language

  33. Websites met pieken

  34. Websites die van nature traag zijn

  35. Wat met TLS/SSL?

  36. TLS termineren User Varnish Server TLS HTTPS HTTP

  37. Cloud servers

  38. Shared hosting

  39. None
  40. None
  41. None
  42. None
  43. None
  44. None
  45. None
  46. None
  47. Varnish spreekt HTTP

  48. ✓Idempotence ✓State ✓Expiration ✓Conditional requests ✓Cache variaties Varnish spreekt HTTP

  49. ✓GET ✓HEAD -POST -PUT -PATCH -DELETE -TRACE -OPTIONS Idempotence Cache

    enkel GET & HEAD
  50. ✓Cachet niet wanneer er cookies meegegeven worden door de browser

    ✓Cachet niet wanneer er cookies aangemaakt worden door de backend ✓Cachet niet wanneer er Authorization headers meegeven worden State User-specific content Beïnvloedt hit rate
  51. Expiration Expires: Sat, 09 Sep 2017 14:30:00 GMT Cache-control: public,

    max-age=3600, s-maxage=86400 Cache-control: private, no-cache, no-store
  52. Expiration voorrang 1. beresp.ttl (VCL) 2. s-maxage 3. max-age 4.

    expires 5. 120 seconden standaard
  53. Conditional requests HTTP/1.1 200 OK Host: localhost Etag: 7c9d70604c6061da9bb9377d3f00eb27 Content-type:

    text/html; charset=UTF-8 Hello world output GET /if_none_match.php HTTP/1.1 Host: localhost User-Agent: curl/7.48.0
  54. Conditional requests HTTP/1.0 304 Not Modified Host: localhost Etag: 7c9d70604c6061da9bb9377d3f00eb27

    GET /if_none_match.php HTTP/1.1 Host: localhost User-Agent: curl/7.48.0 If-None-Match: 7c9d70604c6061da9bb9377d3f00eb27
  55. Conditional requests HTTP/1.1 200 OK Host: localhost Last-Modified: Fri, 22

    Jul 2016 10:11:16 GMT Content-type: text/html; charset=UTF-8 Hello world output GET /if_none_match.php HTTP/1.1 Host: localhost User-Agent: curl/7.48.0
  56. Conditional requests HTTP/1.0 304 Not Modified Host: localhost Last-Modified: Fri,

    22 Jul 2016 10:11:16 GMT GET /if_none_match.php HTTP/1.1 Host: localhost User-Agent: curl/7.48.0 If-Last-Modified: Fri, 22 Jul 2016 10:11:16 GMT
  57. ✓Hostname (of IP) ✓URL Cache variaties Identificeert objecten in de

    cache
  58. Cache variations GET / HTTP/1.1 Host: localhost Accept-Language: nl HTTP/1.1

    200 OK Host: localhost Vary: Accept-Language Hallo, deze pagina is in het Nederlands geschreven.
  59. Flow

  60. None
  61. None
  62. Built-in VCL cheat sheet

  63. sub vcl_recv { if (req.method == "PRI") { /* We

    do not support SPDY or HTTP/2.0 */ return (synth(405)); } if (req.method != "GET" && req.method != "HEAD" && req.method != "PUT" && req.method != "POST" && req.method != "TRACE" && req.method != "OPTIONS" && req.method != "DELETE") { /* Non-RFC2616 or CONNECT which is weird. */ return (pipe); } if (req.method != "GET" && req.method != "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 (hash); }
  64. sub vcl_pipe { # By default Connection: close is set

    on all piped requests, to stop # connection reuse from sending future requests directly to the # (potentially) wrong backend. If you do want this to happen, you can undo # it here. # unset bereq.http.connection; return (pipe); } sub vcl_pass { return (fetch); } sub vcl_hash { hash_data(req.url); if (req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); } return (lookup); }
  65. sub vcl_purge { return (synth(200, "Purged")); } sub vcl_hit {

    if (obj.ttl >= 0s) { // A pure unadultered hit, deliver it return (deliver); } if (obj.ttl + obj.grace > 0s) { // Object is in grace, deliver it // Automatically triggers a background fetch return (deliver); } // fetch & deliver once we get the result return (miss); } sub vcl_miss { return (fetch); } sub vcl_deliver { return (deliver); }
  66. sub vcl_backend_fetch { return (fetch); } sub vcl_backend_response { if

    (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Surrogate-control ~ "no-store" || (!beresp.http.Surrogate-Control && beresp.http.Cache-Control ~ "no-cache|no-store| private") || beresp.http.Vary == "*") { /* * Mark as "Hit-For-Pass" for the next 2 minutes */ set beresp.ttl = 120s; set beresp.uncacheable = true; } return (deliver); }
  67. In een ideale wereld

  68. De realiteit

  69. None
  70. None
  71. Cache-control ?

  72. Legacy

  73. VCL schrijven

  74. Normalizeren

  75. vcl 4.0; import std; sub vcl_recv { set req.http.Host =

    regsub(req.http.Host, ":[0-9]+", ""); set req.url = std.querysort(req.url); if (req.url ~ "\#") { set req.url = regsub(req.url, "\#.*$", ""); } if (req.url ~ "\?$") { set req.url = regsub(req.url, "\?$", ""); } if (req.restarts == 0) { if (req.http.Accept-Encoding) { if (req.http.User-Agent ~ "MSIE 6") { unset req.http.Accept-Encoding; } elsif (req.http.Accept-Encoding ~ "gzip") { set req.http.Accept-Encoding = "gzip"; } elsif (req.http.Accept-Encoding ~ "deflate") { set req.http.Accept-Encoding = "deflate"; } else { unset req.http.Accept-Encoding; } } } }
  76. sub vcl_recv { if (req.url ~ "^/status\.php$" || req.url ~

    "^/update\.php$" || req.url ~ "^/admin$" || req.url ~ "^/admin/.*$" || req.url ~ "^/user$" || req.url ~ "^/user/.*$" || req.url ~ "^/flag/.*$" || req.url ~ "^.*/ajax/.*$" || req.url ~ "^.*/ahah/.*$") { return (pass); } } URL blacklist
  77. sub vcl_recv { if (req.url ~ "^/products/?" return (hash); }

    } URL whitelist
  78. Cookies

  79. vcl 4.0; sub vcl_recv { set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(;

    )?", ""); set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", ""); set req.http.Cookie = regsuball(req.http.Cookie, "_ga=[^;]+(; )?", ""); set req.http.Cookie = regsuball(req.http.Cookie, "_gat=[^;]+(; )?", ""); set req.http.Cookie = regsuball(req.http.Cookie, "utmctr=[^;]+(; )?", ""); set req.http.Cookie = regsuball(req.http.Cookie, "utmcmd.=[^;]+(; )?", ""); set req.http.Cookie = regsuball(req.http.Cookie, "utmccn.=[^;]+(; )?", ""); set req.http.Cookie = regsuball(req.http.Cookie, "__gads=[^;]+(; )?", ""); set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", ""); set req.http.Cookie = regsuball(req.http.Cookie, "__atuv.=[^;]+(; )?", ""); set req.http.Cookie = regsuball(req.http.Cookie, "^;\s*", ""); if (req.http.cookie ~ "^\s*$") { unset req.http.cookie; } } Tracking cookies verwijderen
  80. vcl 4.0; sub vcl_recv { if (req.http.Cookie) { set req.http.Cookie

    = ";" + req.http.Cookie; set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";"); set req.http.Cookie = regsuball(req.http.Cookie, ";(PHPSESSID)=", "; \1="); set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", ""); set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", ""); if (req.http.cookie ~ "^\s*$") { unset req.http.cookie; } } } Enkel sessie cookies bewaren
  81. sub vcl_recv { if (req.http.Cookie) { set req.http.Cookie = ";"

    + req.http.Cookie; set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";"); set req.http.Cookie = regsuball(req.http.Cookie, ";(language)=", "; \1="); set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", ""); set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", ""); if (req.http.cookie ~ "^\s*$") { unset req.http.cookie; return(pass); } return(hash); } } sub vcl_hash { hash_data(regsub( req.http.Cookie, "^.*language=([^;]*);*.*$", "\1" )); } Language cookie cache variatie
  82. Alternatieve language cache variatie

  83. sub vcl_hash { hash_data(req.http.Accept-Language); } HTTP/1.1 200 OK Host: localhost

    Vary: Accept-Language Hash Accept-Language Of doe het gewoon zo:
  84. Cookie richtlijnen

  85. ✓Gooi niet alles in je sessievariabelen ✓Gebruik specifieke cookies ✓Verwijder

    tracking cookies in uw VCL ✓Make beslissingen op basis van cookies ✓Gebruik cookies voor cache variaties ✓Gebruik enkel de sessie cookie wanneer het echt nodig is Cookie richtlijnen
  86. Block caching

  87. None
  88. Code rendert één HTTP response

  89. Grootste gemene deler: Niet cachen

  90. <esi:include src="/header" /> Edge Side Includes ✓Placeholder ✓Wordt verwerkt door

    Varnish ✓Output is een compositie van blocks ✓State per block ✓TTL per block
  91. sub vcl_recv { set req.http.Surrogate-Capability = "key=ESI/1.0"; } sub vcl_backend_response

    { if (beresp.http.Surrogate-Control ~ "ESI/1.0") { unset beresp.http.Surrogate-Control; set beresp.do_esi = true; } } Edge Side Includes
  92. ESI vs AJAX

  93. Breaking news is niet aan het “breaken”

  94. Purging

  95. acl purge { "localhost"; "127.0.0.1"; "::1"; } sub vcl_recv {

    if (req.method == "PURGE") { if (!client.ip ~ purge) { return (synth(405, “Not allowed.”)); } return (purge); } } Purging
  96. acl purge { "localhost"; "127.0.0.1"; "::1"; } sub vcl_backend_response {

    set beresp.http.x-url = bereq.url; set beresp.http.x-host = bereq.http.host; } sub vcl_deliver { unset resp.http.x-url; unset resp.http.x-host; } sub vcl_recv { if (req.method == "PURGE") { if (!client.ip ~ purge) { return (synth(405, "Not allowed")); } if(req.http.x-purge-regex) { ban("obj.http.x-host == " + req.http.host + " && obj.http.x-url ~ " + req.http.x-purge-regex); } else { ban("obj.http.x-host == " + req.http.host + " && obj.http.x-url == " + req.url); } return (synth(200, "Purged")); } } Banning
  97. Banning curl -XPURGE "http://example.com/products" curl -XPURGE -H "x-purge-regex:/products" \ "http://example.com"

    varnishadm> ban obj.http.x-host == example.com && obj.http.x-url ~ ^/ product/[0-9]+/details
  98. Snelheid

  99. Stabiliteit

  100. Developer empowerment

  101. Cachen Cache-control: public, max-age=3600, s-maxage=86400 Cache-control: private, no-cache, no-store Niet

    cachen
  102. None
  103. None
  104. https://feryn.eu https://twitter.com/ThijsFeryn https://instagram.com/ThijsFeryn

  105. None