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

Goaze geven met Varnish

Goaze geven met Varnish

Slides for my Varnish talk at the April 2017 meetup of PHP West-Vlaanderen. See https://talks.feryn.eu/talks/168/goaze-geven-met-varnish-php-west-vlaanderen-april-meetup-brugge for more details

Ca901ddcea38854b9783781c91fc87c9?s=128

Thijs Feryn

April 18, 2017
Tweet

Transcript

  1. Goaze geven Deur Thijs Feryn met Varnish

  2. Trage websites suckn

  3. De mensjn en gèren rappe sites User Experience

  4. No de kloten Trage ~ plat

  5. Yo gastjes, 't is ier Thijs

  6. 165

  7. 'k Zien @ThijsFeryn ip Twitter

  8. 'k Zien Evanhelist bie

  9. ’k Weunen in Diksmude

  10. Aan de Pluum’n

  11. Juuste niet bachten de Kupe

  12. None
  13. Mo money Mo servers Meer kluitn, meer servers

  14. Cache

  15. Nie herbereken ot niet veranderd is

  16. None
  17. Geweunlijk Gebruker Server

  18. With Varnish Gebruker Varnish Server

  19. None
  20. Worom is 't zo goed?

  21. Slimme kernel trucs

  22. Bewoart HTTP output in't heheuhn*

  23. Respecteert HTTP best practices

  24. Varnish Configuration Language

  25. Hoe scheid da met TLS/SSL?

  26. 't goat hier over Varnish 4 hé !

  27. Installeern & configureern

  28. apt-get install apt-transport-https curl https://repo.varnish-cache.org/GPG-key.txt | apt-key add - echo

    "deb https://repo.varnish-cache.org/debian/ jessie varnish-4.1"\ >> /etc/apt/sources.list.d/varnish-cache.list apt-get update apt-get install varnish Ip Debian Ubuntu & CentOS is ook meugelik
  29. -a :80 \ -a :81,PROXY \ -T localhost:6082 \ -f

    /etc/varnish/default.vcl \ -S /etc/varnish/secret \ -s malloc,3g Simpele configuroasje
  30. vcl 4.0; backend default { .host = "localhost"; .port =

    "8080"; } Minimale VCL
  31. Varnish klapt HTTP

  32. ✓Idempotensje ✓Toestand ✓Vervallen ✓Conditionele requests ✓Cache varioasjes Varnish klapt HTTP

  33. ✓GET ✓HEAD -POST -PUT -PATCH -DELETE -TRACE -OPTIONS Idempotencsje Ollene

    GET & HEAD
  34. ✓Cacht gin cookies ✓Cacht gin set-cookies ✓Cacht gin Authorization headers

    Toestand User- specific content wordt standoard niet gecachet Helpt je hit rate no de kloten
  35. Vervallen 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
  36. Voorrang 1. beresp.ttl (VCL) 2. s-maxage 3. max-age 4. expires

    5. 120 seconden
  37. Conditionele 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
  38. Conditionele 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
  39. Conditionele 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
  40. Conditionele 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-Modified-Since: Fri, 22 Jul 2016 10:11:16 GMT
  41. ✓Hostname (of IP) ✓URL Cache varioasjes Object identificeren in cache

  42. Cache varioasjes 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.
  43. Built-in VCL cheat sheet

  44. ✓Ollene GET & HEAD ✓Gin Cookie ✓Gin Authorization Built-in VCL

    (voorkant) Ipzoekn in cache Anders "pass" en nie cachen
  45. ✓Gin Set-Cookie ✓TTL > 0 ✓Gin "no-cache", "private", "no-store" Built-in

    VCL (achterkant) Ipsloan in cache Anders blacklist voe 120s
  46. D'echte VCL code

  47. 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); }
  48. 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); }
  49. 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); }
  50. 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); }
  51. De werkelijkheid suckt

  52. None
  53. None
  54. Cache-control ?

  55. Oede briel

  56. Schrieft VCL

  57. Normaliseren

  58. 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; } } } }
  59. 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
  60. sub vcl_recv { if (req.url ~ "^/products/?" return (hash); }

    } URL whitelist
  61. Koekn

  62. 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 wegdoen
  63. 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; } } } Ollene session cookie bewoaren
  64. 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" )); } Cache variaosje op language cookie
  65. Of gebruukt vmod_cookie

  66. Alternatieve taal cache varioasje

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

    Vary: Accept-Language Hash de tale Of gebruukt
  68. Wuk doej met koekn?

  69. ✓Nie olles in een session smietn ✓Gebruukt vaste cookies ✓Doe

    tracking cookies weg uut VCL ✓Gebruukt cookies in VCL voe beslissingen te pakn ✓Cache varioasjes met cookies ✓Gebruukt ollene mo session cookies ot echt nodig is ✓Gebruikt JWT voe session state client- side ip te sloan Wuk doej met koekn?
  70. Blokn cachen

  71. None
  72. Code spuugt één HTTP response uut

  73. Bie gevolg: nie cachen

  74. <esi:include src="/header" /> Edge Side Includes ✓Placeholder ✓Geparsed deur Varnish

    ✓Output is è compoziesje van blokn ✓Toestand per blok ✓TTL per blok
  75. 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
  76. ESI vergeleken met AJAX

  77. <esi:include src="/header" /> Peist goed, kiest verstandig <hx:include src="/header"></hx:include> ESI,

    geparsed duer Varnish HInclude, geparsed deur Javascript
  78. Druk ip de ketel

  79. ✓Varnishlog ✓Varnishtop ✓Varnishstat Druk ip de ketel

  80. Nieuws dat er niet deure komt

  81. Purge

  82. 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); } } Purge
  83. 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")); } } Ban
  84. Ban 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
  85. Minder VCL Betere code

  86. https://github.com/ThijsFeryn/ cacheable-site-silex/tree/v2

  87. None
  88. None
  89. https://twitter.com/thijsferyn https://instagram.com/thijsferyn https://blog.feryn.eu https://talks.feryn.eu https://book.feryn.eu https://youtube.com/thijsferyn https://soundcloud.com/thijsferyn http://itunes.feryn.eu