Skip to content

Instantly share code, notes, and snippets.

@nbeguier
Last active March 19, 2018 11:09
Show Gist options
  • Save nbeguier/f6d8f911089274cdc0cf1eb3ea8421fe to your computer and use it in GitHub Desktop.
Save nbeguier/f6d8f911089274cdc0cf1eb3ea8421fe to your computer and use it in GitHub Desktop.
Varnish cache static
vcl 4.0;
import directors;
import dynamic;
# Probe for sharding node
probe health_check_probe {
.url = "/health";
.interval = 5s;
.timeout = 1s;
.window = 5;
.threshold = 3;
.initial = 3;
}
# Probe for backend api server
probe api_probe {
.expected_response = 400;
.interval = 5s;
.timeout = 1s;
.window = 5;
.threshold = 3;
.initial = 3;
}
# You can add multiple sharding node
backend node01 {
.host = "node01.domain.lan";
.port = "6081";
.probe = health_check_probe;
}
backend node02 {
.host = "node02.domain.lan";
.port = "6081";
.probe = health_check_probe;
}
acl ipv4_only { "0.0.0.0"/0; }
sub vcl_init {
new cluster = directors.hash();
cluster.add_backend(node01, 1);
cluster.add_backend(node02, 1);
new api_1 = dynamic.director(
port = "80",
probe = api_probe,
ttl = 2m,
whitelist = ipv4_only
);
new api_2 = dynamic.director(
port = "80",
probe = api_probe,
ttl = 2m,
whitelist = ipv4_only
);
}
sub vcl_recv {
# Happens before we check if we have this in cache already.
# Typically you clean up the request here, removing cookies you
# don't need, rewriting the request, etc.
if (req.url ~ "^/health") {
return(synth(750));
}
# SHARDING
set req.backend_hint = cluster.backend(req.url);
set req.http.X-shard = req.backend_hint;
if (
req.http.X-shard == server.identity
) {
if ( req.url ~ "^/path_1" && req.method == "GET" ) {
# Strip the cookies
unset req.http.cookie;
set req.backend_hint = api_1.backend("api1.domain.com");
return(hash);
} elif ( req.url ~ "^/path_2" && req.method == "GET" ) {
# Strip the cookies
unset req.http.cookie;
set req.backend_hint = api_2.backend("api2.domain.com");
return(hash);
} else {
# Return a 404 if varnish don't fetch it
return(synth(404));
}
} else {
set req.http.X-Varnish-Cache = "pass";
return(pass);
}
}
#################
# Backend Fetch #
#################
sub vcl_backend_fetch {
# Add Host header
if ( bereq.url ~ "^/path_1" && bereq.method == "GET" ) {
set bereq.http.host = "api1.domain.com";
} elif ( bereq.url ~ "^/path_2" && bereq.method == "GET" ) {
set bereq.http.host = "api2.domain.com";
}
return (fetch);
}
sub vcl_backend_response {
# Happens after we have read the response headers from the backend.
# Here you clean the response headers, removing silly Set-Cookie
# headers and other mistakes your backend does.
if (
bereq.url ~ "^/path_1" ||
bereq.url ~ "^/path_2"
){
# time-to-live 30 days
set beresp.ttl = 30d;
unset beresp.http.set-cookie;
unset beresp.http.Pragma;
unset beresp.http.Expires;
}
# don’t cache redirects and errors
if (beresp.status >= 300) {
set beresp.uncacheable = true;
set beresp.ttl = 30s;
return (deliver);
}
return (deliver);
}
#################
# Delivery #
#################
sub vcl_deliver {
# Happens when we have all the pieces we need, and are about to send the
# response to the client.
# You can do accounting or modifying the final object here.
unset resp.http.Server;
unset resp.http.Via;
unset resp.http.X-Varnish;
unset resp.http.X-Served-By;
unset resp.http.ETag;
unset resp.http.Age;
unset resp.http.X-NLP-IRT;
return(deliver);
}
sub vcl_synth {
if (resp.status == 750) {
# Set a status the client will understand
set resp.status = 200;
# Create our synthetic response
synthetic("OK");
return(deliver);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment