A proibição de verniz foi adicionada, mas o objeto antigo foi retornado
Estou usando verniz na frente de um servidor de blocos para armazenar os blocos do mapbox. Para remover blocos antigos, eu pretendia usar proibições para remover efetivamente um grande número de blocos em cache. Meu problema é que o verniz ainda usa os objetos em cache (pelo menos o age
na resposta indica isso) e não entra em contato com o backend.
Primeiro estou solicitando http: //varnish/5/3/4.pbf, depois adicionando um ban com curl -X BAN -H 'X-Purge-Regex: 5/3/4.pbf' varnish
ou alternativamente varnishadm
e, em ban obj.http.url ~ 5/3/4.pbf
seguida, solicitando http: //varnish/5/3/4.pbf novamente.
No início, minha lista de banimentos está vazia:
Present bans:
1610117471.434488 1 C
O ban foi adicionado com sucesso com curl -X BAN -H 'X-Purge-Regex: 5/3/4.pbf' varnish
<!DOCTYPE html>
<html>
<head>
<title>200 Ban added</title>
</head>
<body>
<h1>Error 200 Ban added</h1>
<p>Ban added</p>
<h3>Guru Meditation:</h3>
<p>XID: 8</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
e aparece na lista de banidos
Present bans:
1610117369.028870 0 - obj.http.url ~ 5/3/4.pbf
1610117307.220739 1 C
Depois de solicitar http: //varnish/5/3/4.pbf novamente, a lista de banimento indica que o banimento foi usado
Present bans:
1610117471.434488 1 - obj.http.url ~ 5/3/4.pbf
mas a idade da resposta não é 0, porque ainda é o objeto da primeira solicitação.
Após um curto período de tempo, o banimento é removido:
Present bans:
1610117471.434488 1 C
Minha vcl_recv
aparência é assim, mas provavelmente o erro está em outro lugar, pois também não funciona com varnishadm
:
sub vcl_recv {
unset req.http.cookie;
# Allowing PURGE from localhost
if (req.method == "BAN"||req.method == "PURGE") {
if (!client.ip ~ purge) {
return(synth(405,"Not allowed."));
}
if (req.method == "BAN") {
ban("obj.http.url ~ " + req.http.X-Purge-Regex);
# Throw a synthetic page so the
# request won't go to the backend.
return(synth(200, "Ban added"));
}
if (req.method == "PURGE") {
return (purge);
}
}
}
Eu também tentei usar o vcl_purge
dehttps://stackoverflow.com/a/61507014 mas isso não parece ajudar nas proibições (?).
Estou usando o X-Purge-Regex
cabeçalho para não me preocupar em ter que escapar caracteres especiais como emhttps://stackoverflow.com/a/38526921mas apenas uma proibição como obj.http.url ~ 0
não funciona.
Estou usando verniz 6.5 com vcl 4.0.
Pedido de banimento
* << Request >> 54
- Begin req 53 rxreq
- Timestamp Start: 1610121483.345437 0.000000 0.000000
- Timestamp Req: 1610121483.345437 0.000000 0.000000
- VCL_use boot
- ReqStart 192.168.48.2 50882 http
- ReqMethod BAN
- ReqURL /
- ReqProtocol HTTP/1.1
- ReqHeader Host: varnish-volatile
- ReqHeader User-Agent: curl/7.64.0
- ReqHeader Accept: */*
- ReqHeader X-Purge-Regex: 0
- ReqHeader X-Forwarded-For: 192.168.48.2
- VCL_call RECV
- VCL_acl MATCH purge "importer"
- VCL_return synth
- VCL_call HASH
- VCL_return lookup
- RespProtocol HTTP/1.1
- RespStatus 200
- RespReason Ban added
- RespHeader Date: Fri, 08 Jan 2021 15:58:03 GMT
- RespHeader Server: Varnish
- RespHeader X-Varnish: 54
- VCL_call SYNTH
- RespHeader Content-Type: text/html; charset=utf-8
- RespHeader Retry-After: 5
- VCL_return deliver
- Timestamp Process: 1610121483.347281 0.001844 0.001844
- RespHeader Content-Length: 246
- Storage malloc Transient
- Filters
- RespHeader Accept-Ranges: bytes
- RespHeader Connection: keep-alive
- Timestamp Resp: 1610121483.347557 0.002120 0.000276
- ReqAcct 98 0 98 218 246 464
- End
OBTER após adicionar proibição
* << Request >> 32806
- Begin req 32805 rxreq
- Timestamp Start: 1610121552.733872 0.000000 0.000000
- Timestamp Req: 1610121552.733872 0.000000 0.000000
- VCL_use boot
- ReqStart 192.168.48.1 55176 http
- ReqMethod GET
- ReqURL /public.snow_db/0/0/0.pbf
- ReqProtocol HTTP/1.1
- ReqHeader Host: localhost:8090
- ReqHeader User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:84.0) Gecko/20100101 Firefox/84.0
- ReqHeader Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
- ReqHeader Accept-Language: en-US,en;q=0.5
- ReqHeader Accept-Encoding: gzip, deflate
- ReqHeader DNT: 1
- ReqHeader Connection: keep-alive
- ReqHeader Upgrade-Insecure-Requests: 1
- ReqHeader Pragma: no-cache
- ReqHeader Cache-Control: no-cache
- ReqHeader X-Forwarded-For: 192.168.48.1
- VCL_call RECV
- ReqUnset Host: localhost:8090
- ReqHeader host: localhost:8090
- VCL_return hash
- ReqUnset Accept-Encoding: gzip, deflate
- ReqHeader Accept-Encoding: gzip
- VCL_call HASH
- VCL_return lookup
- Hit 28 601789.331504 10.000000 0.000000
- VCL_call HIT
- VCL_return deliver
- RespProtocol HTTP/1.1
- RespStatus 200
- RespReason OK
- RespHeader content-encoding: gzip
- RespHeader content-type: application/x-protobuf
- RespHeader date: Fri, 08 Jan 2021 15:09:02 GMT
- RespHeader Vary: Accept-Encoding
- RespHeader X-Varnish: 32806 28
- RespHeader Age: 3010
- RespHeader Via: 1.1 varnish (Varnish/6.5)
- VCL_call DELIVER
- VCL_return deliver
- Timestamp Process: 1610121552.734070 0.000197 0.000197
- Filters
- RespHeader Accept-Ranges: bytes
- RespHeader Content-Length: 295
- RespHeader Connection: keep-alive
- Timestamp Resp: 1610121552.734217 0.000345 0.000147
- ReqAcct 414 0 414 272 295 567
- End
Reproduzindo o problema
Para reproduzir o bug:
git clone https://github.com/Baschdl/varnish-ban-setup.git && cd varnish-ban-setup
docker-compose up
- Abra http: // localhost: 8092/5/3 / 1.pbf
docker-compose exec varnish varnishadm ban obj.http.url ~ pbf
- Abra http: // localhost: 8092/5/3 / 1.pbf novamente e você obterá o objeto antigo
Respostas
O obj.http.url ~ 5/3/4.pbf
banimento que você está emitindo corresponde a um url
cabeçalho de resposta.
Lembre-se: o URL é um cabeçalho de solicitação, não um cabeçalho de resposta. Não há motivo para pânico, o que você está fazendo faz todo o sentido e está relacionado ao escopo do chamado ban lurker .
Banir espreitador
O ban lurker é um thread que processa de forma assíncrona os banimentos na lista de banimentos e associa objetos aos banimentos para remover padrões de objetos do cache.
O ban lurker não opera dentro de um escopo de solicitação, mas apenas está ciente do escopo do objeto.
Para corresponder as informações da solicitação com êxito, o contexto da solicitação pode ser adicionado como um cabeçalho de resposta. E é isso que você está fazendo viaobj.http.url
Então, por que a proibição não funciona?
A razão pela qual seu ban não está funcionando é porque você não configurou obj.http.url
em seu arquivo VCL. Como resultado, o ban lurker não pode combinar nenhum objeto com ele.
Como consertar o problema
A solução é simples: defina os cabeçalhos ausentes no contexto de resposta de back-end, conforme ilustrado abaixo:
sub vcl_backend_response {
set beresp.http.url = bereq.url;
set beresp.http.host = bereq.http.host;
}
Quando o back-end responde, e logo antes de o objeto ser armazenado no cache, podemos definir os cabeçalhos ausentes.
Depois disso, o ban lurker será capaz de combinar a expressão de ban com os objetos certos e removê-los do cache.
Não se esqueça de que os objetos não são correspondidos imediatamente: eles só são removidos quando alcançam o ban_lurker_age, que é definido como 1 minuto por padrão.