varnish throttle

This commit is contained in:
Mateusz Gruszczyński
2025-09-24 16:06:57 +02:00
parent 9a7660fdf7
commit 72b82ae40c

View File

@@ -8,10 +8,11 @@ backend app {
.port = "${APP_PORT}"; .port = "${APP_PORT}";
} }
acl purge { "localhost"; "127.0.0.1"; } /* unikamy duplikatu; dodajemy IPv6 */
acl purge { "127.0.0.1"; "::1"; }
sub vcl_recv { sub vcl_recv {
# RATE LIMIT: 100 żądań / 10s, po przekroczeniu blokada na 60s # RATE LIMIT: 100 żądań / 10s, blokada 60s
if (vsthrottle.is_denied(client.identity, 100, 10s, 60s)) { if (vsthrottle.is_denied(client.identity, 100, 10s, 60s)) {
return (synth(429, "Too Many Requests")); return (synth(429, "Too Many Requests"));
} }
@@ -41,50 +42,48 @@ sub vcl_backend_response {
if (beresp.http.Cache-Control ~ "(?i)no-store|private") { if (beresp.http.Cache-Control ~ "(?i)no-store|private") {
set beresp.uncacheable = true; set beresp.uncacheable = true;
set beresp.ttl = 0s; set beresp.ttl = 0s;
return; return (deliver);
} }
# Preferuj s-maxage (cache współdzielony), potem max-age # Preferuj s-maxage, potem max-age
if (beresp.http.Cache-Control ~ "(?i)s-maxage=([0-9]+)") { if (beresp.http.Cache-Control ~ "(?i)s-maxage=([0-9]+)") {
set beresp.ttl = std.duration(regsub(beresp.http.Cache-Control, ".*(?i)s-maxage=([0-9]+).*", "\1") + "s", 0s); set beresp.ttl = std.duration(regsub(beresp.http.Cache-Control, "(?i).*s-maxage=([0-9]+).*", "\1") + "s", 0s);
} else if (beresp.http.Cache-Control ~ "(?i)max-age=([0-9]+)") { } else if (beresp.http.Cache-Control ~ "(?i)max-age=([0-9]+)") {
set beresp.ttl = std.duration(regsub(beresp.http.Cache-Control, ".*(?i)max-age=([0-9]+).*", "\1") + "s", 0s); set beresp.ttl = std.duration(regsub(beresp.http.Cache-Control, "(?i).*max-age=([0-9]+).*", "\1") + "s", 0s);
} else if (beresp.http.Expires) { } else if (beresp.http.Expires) {
# fallback na Expires # fallback na Expires
set beresp.ttl = std.duration(std.timestamp2s(beresp.http.Expires) - std.now(), 0s); set beresp.ttl = std.time(beresp.http.Expires, now, 0s) - now;
} else { } else {
# ostateczny fallback # ostateczny fallback
set beresp.ttl = 60s; set beresp.ttl = 60s;
} }
# Jeśli immutable zwiększ grace (serwuj „stale” dłużej przy problemach z backendem) # Jeśli immutable zwiększ grace/keep
if (beresp.http.Cache-Control ~ "(?i)immutable") { if (beresp.http.Cache-Control ~ "(?i)immutable") {
set beresp.grace = 1h; # dostosuj wg potrzeb set beresp.grace = 1h;
set beresp.keep = 24h; # dłuższe trzymanie w storage na trafienia „stale-if-error” set beresp.keep = 24h;
} }
# (opcjonalnie) statykom daj minimalne TTL, gdy backend NIE ustawił CC # statykom daj minimalne TTL, gdy backend NIE ustawił CC
if ((bereq.url ~ "^/static/" || bereq.url ~ "\.(css|js|png|jpg|svg|ico|woff2?)$") if ((bereq.url ~ "^/static/" || bereq.url ~ "\.(css|js|png|jpg|svg|ico|woff2?)$")
&& !(beresp.http.Cache-Control ~ "(?i)(s-maxage|max-age)")) { && !(beresp.http.Cache-Control ~ "(?i)(s-maxage|max-age)")) {
set beresp.ttl = 24h; set beresp.ttl = 24h;
} }
} }
sub vcl_deliver { sub vcl_deliver {
if (obj.hits > 0) { if (obj.hits > 0) {
set resp.http.X-Cache = "HIT"; set resp.http.X-Cache = "HIT";
# ukryhe niepotrzebny nagłówek z MISS # ukryj niepotrzebny nagłówek z MISS
#} else { #} else {
# set resp.http.X-Cache = "MISS"; # set resp.http.X-Cache = "MISS";
} }
# Nagłówki rate limit MUSZĄ używać tej samej czwórki parametrów co is_denied() # Nagłówki rate limit MUSZĄ używać tej samej czwórki parametrów co is_denied()
#set resp.http.X-RateLimit-Limit = "10"; #set resp.http.X-RateLimit-Limit = "100";
#set resp.http.X-RateLimit-Window = "10s"; #set resp.http.X-RateLimit-Window = "10s";
#set resp.http.X-RateLimit-Remaining = vsthrottle.remaining(client.identity, 10, 10s, 30s); #set resp.http.X-RateLimit-Remaining = vsthrottle.remaining(client.identity, 100, 10s, 60s);
#set resp.http.Retry-After = vsthrottle.blocked(client.identity, 10, 10s, 30s); #set resp.http.Retry-After = vsthrottle.blocked(client.identity, 100, 10s, 60s);
unset resp.http.Via; unset resp.http.Via;
unset resp.http.X-Varnish; unset resp.http.X-Varnish;