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

Varnish beyond basic web acceleration - DAHO.AM 2019

Varnish beyond basic web acceleration - DAHO.AM 2019

Slides for my "advanced Varnish" talk at the DAHO.AM 2019 developer conference in Munich (Germany).

More information about this presentation can be found on https://feryn.eu/speaking/varnish-beyond-basic-web-acceleration-dahoam2019/

Thijs Feryn

May 28, 2019
Tweet

More Decks by Thijs Feryn

Other Decks in Technology

Transcript

  1. WHY IS VARNISH SO POWERFUL? ✓ EXTREMELY LOW RESOURCE ✓

    EXTREMELY STABLE ✓ 100 GBIT PER SERVER ✓ NO DISK ACCESS AT RUNTIME ✓ REQUEST COALESCING ✓ VARNISH CONFIGURATION LANGUAGE ✓ VMODS ✓ COMPLIES TO HTTP BEST PRACTICES ✓ ENTERPRISE FEATURES*
  2. HTTP CACHING MECHANISMS 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
  3. CONDITIONAL REQUESTS HTTP/1.1 200 OK Host: localhost Etag: 7c9d70604c6061da9bb9377d3f00eb27 Content-type:

    text/html; charset=UTF-8 Hello world output GET / HTTP/1.1 Host: localhost
  4. CONDITIONAL REQUESTS HTTP/1.1 304 Not Modified Host: localhost Etag: 7c9d70604c6061da9bb9377d3f00eb27

    GET / HTTP/1.1 Host: localhost If-None-Match: 7c9d70604c6061da9bb9377d3f00eb27
  5. ✓STATELESS ✓WELL-DEFINED TTL ✓CACHE / NO-CACHE PER RESOURCE ✓CACHE VARIATIONS

    ✓CONDITIONAL REQUESTS ✓PLACEHOLDERS FOR NON-CACHEABLE CONTENT IN AN IDEAL WORLD
  6. INFLUENCE CACHING BEHAVIOR ✓ WHAT TO CACHE ✓ WHAT NOT

    TO CACHE ✓ HOW LONG TO CACHE ✓ HOW TO CACHE ✓ HOW TO EMPTY THE CACHE ✓ CHANGE REQUEST/RESPONSE/PAYLOAD
  7. sub vcl_recv { if (req.url ~ "^/status\.php$" || req.url ~

    "^/update\.php$" || req.url ~ "^/admin$" || req.url ~ "^/admin/.*$" || req.url ~ "^/flag/.*$" || req.url ~ "^.*/ajax/.*$" || req.url ~ "^.*/ahah/.*$") { return (pass); } } URL blacklist example
  8. 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, ";(SESS[a-z0-9]+|SSESS[a-z0-9]+|NO_CACHE)=", "; \1="); set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", ""); set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", ""); if (req.http.Cookie == "") { unset req.http.Cookie; } else { return (pass); } } } Cookie example
  9. 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" )); } Cookie cache variation
  10. #EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:6 #EXT-X-MEDIA-SEQUENCE:0 #EXT-X-PLAYLIST-TYPE:VOD #EXTINF:6.000000, stream_00.ts #EXTINF:6.000000, stream_01.ts #EXTINF:6.000000,

    stream_02.ts #EXTINF:6.000000, stream_03.ts #EXTINF:6.000000, stream_04.ts #EXTINF:6.000000, stream_05.ts #EXTINF:6.000000, stream_06.ts #EXTINF:6.000000, stream_07.ts #EXTINF:6.000000, stream_08.ts #EXTINF:6.000000, stream_09.ts #EXTINF:5.280000, stream_010.ts #EXT-X-ENDLIST STREAM.M3U8
  11. <html> <head> <link href="https://vjs.zencdn.net/7.5.4/video-js.css" rel="stylesheet"> </head> <body> <video id='my-video' class='video-js'

    controls preload='auto' height='640' data- setup='{}'> <source src="/live/stream.m3u8" type="application/vnd.apple.mpegurl"> </video> <script src='https://vjs.zencdn.net/7.5.4/video.js'></script> </body> </html>
  12. LIVE ✓ LOW LATENCY ✓ CONSTANT PLAYLIST UPDATES ✓ LOW

    TTL ON PLAYLISTS ✓ ONLY THE LAST X SEGMENTS ARE REQUIRED ✓ SEGMENT SIZE TRADEOFF
  13. VOD ✓ NO PLAYLIST UPDATES ✓ HIGH TTL ON PLAYLISTS

    ✓ ALL SEGMENTS ARE REQUIRED ✓ STORAGE REQUIREMENTS ✓ PRE-FETCHING POSSIBLE
  14. MORE VIDEO FEATURES ✓ GEOIP ✓ DIGITAL RIGHTS MANAGEMENT ✓

    AUTHENTIATION ✓ THROTTLING & RATE LIMITING ✓ ADAPTIVE BITRATE FILTERING ✓ NO MORE ORIGIN
  15. vcl 4.1; import http; import std; backend default { .host

    = "origin"; .port = "80"; } sub vcl_recv { if (req.url ~ "^/vod/.+\.ts$") { http.init(0); http.req_set_max_loops(0,1); http.req_copy_headers(0); http.req_set_method(0, "HEAD"); set req.http.x-next-url = http.prefetch_next_url(); std.log("Prefetching " + req.http.x-next-url); http.req_set_url(0, req.http.x-next-url); http.req_send_and_finish(0); } }
  16. vcl 4.1; import file; sub vcl_init { new root =

    file.init("/var/www/html/"); } sub vcl_backend_fetch { set bereq.backend = root.backend(); } sub vcl_backend_response { if(bereq.url ~ "^/live/stream_[0-9]+\.m3u8$" || bereq.url == "/live/master.m3u8") { set beresp.grace = 0s; set beresp.ttl = 1s; } }
  17. sub vcl_backend_response { if (bereq.uncacheable) { return (deliver); } else

    if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Surrogate-control ~ "(?i)no-store" || (!beresp.http.Surrogate-Control && beresp.http.Cache-Control ~ "(?i:no-cache|no-store|private)") || beresp.http.Vary == "*") { # Mark as "Hit-For-Miss" for the next 2 minutes set beresp.ttl = 120s; set beresp.uncacheable = true; } return (deliver); }
  18. ORIGIN VARNISH SESSION STORE EXPOSE TEMPLATE PARSE & CACHE TEMPLATE

    FETCH DATA FROM SESION STORE RETURN PERSONALIZED OUTPUT
  19. vcl 4.1; import cookieplus; import memcached; import edgestash; backend default

    { .host = "origin"; .port = "80"; } sub vcl_init { memcached.servers("--SERVER=memcached:11211"); } sub vcl_recv { if(cookieplus.get("PHPSESSID") !~ "[a-z0-9]+") { return(pass); } return(hash); } sub vcl_backend_response { if (req.url == "/") { edgestash.parse_response(); } if(cookieplus.setcookie_get("PHPSESSID") ~ "[a-z0-9]+") { set beresp.http.x-session-id = cookieplus.setcookie_get("PHPSESSID"); cookieplus.setcookie_delete("PHPSESSID"); } }
  20. sub vcl_deliver { if (edgestash.is_edgestash() && req.url == "/") {

    set resp.http.x-session-raw = memcached.get("sf2s" + cookieplus.get("PHPSESSID", "")); set resp.http.x-session-base = regsuball(resp.http.x-session-raw,"_sf2_attributes\|a:[0-9]+:\{",""); set resp.http.x-session-base = regsuball(resp.http.x-session-base,";}_sf2_meta\|a:.+",""); set resp.http.x-name = regsuball(resp.http.x-session-base,"^([^;]+;)*s:4:\x22name\x22;s:[0-9]+: \x22([^\x22]+)\x22.+$","\2"); set resp.http.x-shopping-cart-items = regsuball(resp.http.x-session-base,"^([^;]+;)*s:19:\x22shopping-cart- items\x22;i:([0-9]+).*$","\2"); edgestash.add_json({" { "name": ""} + resp.http.x-name + {"", "shopping-cart-items": ""} + resp.http.x-shopping-cart-items + {"" } "}); edgestash.execute(); unset resp.http.x-session-raw; unset resp.http.x-session-base; unset resp.http.x-name; unset resp.http.x-shopping-cart-items; if(resp.http.x-session-id ~ "[a-z0-9]+") { cookieplus.setcookie_add("PHPSESSID", resp.http.x-session-id, 30d, req.http.Host, "/"); cookieplus.setcookie_write(); unset resp.http.x-session-id; } } }
  21. import redis; sub vcl_init { new db = redis.db( location="redis:6379",

    type=master, connection_timeout=500, shared_connections=false, max_connections=1); } sub vcl_deliver { db.command("GET"); db.push("sf_s" + cookieplus.get("PHPSESSID")); db.execute(); set resp.http.x-session-raw = db.get_reply(); set resp.http.x-session-base = regsuball(resp.http.x-session-raw,"_sf2_attributes\|a: [0-9]+:\{",""); set resp.http.x-session-base = regsuball(resp.http.x-session-base,";}_sf2_meta\|a:. +",""); .... }
  22. vcl 4.0; import http; sub vcl_recv { // Store Varnish's

    local address for later use set req.http.X-prefetch = http.varnish_url("/"); } sub vcl_backend_response { if (beresp.http.Link ~ "<.+>.*(prefetch|next)") { // Pull out the Link URL set bereq.http.X-link = regsub(beresp.http.Link, "^.*<([^>]*)>.*$", "\1"); set bereq.http.X-prefetch = regsub(bereq.http.X-prefetch, "/$", bereq.http.X-link); // Prefetch the Link URL back thru Varnish http.init(0); http.req_copy_headers(0); http.req_set_url(0, bereq.http.X-prefetch); http.req_send_and_finish(0); } }
  23. •Accept •Akamai connector •Body access & transformation •Cookieplus •Device atlas

    •Edgestash •File •Geolocation •HTTP communication •JSON parser •Key-value store •Synthetic backends •Encryption •Rate limiting •Throttling •Xkey •Abtest •Authentication •Cookie •Digest •DNS •I18n •LDAP •LUA •Memcached •Redis •OTP •SOAP •UUID
  24. VARNISH ENTERPRISE ✓ CLIENT SSL TERMINATION ✓ BACKEND SSL CONNECTIONS

    ✓ PARALLEL ESI ✓ MASSIVE STORAGE ENGINE ✓ ENCRYPTION ✓ THROTTLING ✓ RATE LIMITING ✓ PREFETCHING ✓ GEOLOCATION ✓ AUTHENTICATION ✓ EDGESTASH ✓ CUSTOM STATISTICS ✓ ADMIN MODULE ✓ SUPPORT ✓ HIGH AVAILABILITY ✓ MOBILE APP