Se agrega la prohibición de barniz pero se devuelve el objeto antiguo
Estoy usando barniz frente a un servidor de mosaicos para almacenar en caché los mosaicos de mapbox. Para eliminar mosaicos antiguos, tenía la intención de usar prohibiciones para eliminar de manera efectiva una gran cantidad de mosaicos almacenados en caché. Mi problema es que el barniz todavía usa los objetos en caché (al menos age
en la respuesta lo indica) y no contacta con el backend.
Primero solicito http: //varnish/5/3/4.pbf, luego agrego una prohibición con curl -X BAN -H 'X-Purge-Regex: 5/3/4.pbf' varnish
o alternativamente varnishadm
y luego ban obj.http.url ~ 5/3/4.pbf
y luego solicito http: //varnish/5/3/4.pbf nuevamente.
Al principio, mi lista de prohibiciones está vacía:
Present bans:
1610117471.434488 1 C
La prohibición se agrega con éxito con 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>
y aparece en la lista de prohibiciones
Present bans:
1610117369.028870 0 - obj.http.url ~ 5/3/4.pbf
1610117307.220739 1 C
Después de solicitar http: //varnish/5/3/4.pbf nuevamente, la lista de prohibiciones indica que se utilizó la prohibición.
Present bans:
1610117471.434488 1 - obj.http.url ~ 5/3/4.pbf
pero la edad de la respuesta no es 0, porque sigue siendo el objeto de la primera solicitud.
Después de un breve período de tiempo, se elimina la prohibición:
Present bans:
1610117471.434488 1 C
Mi vcl_recv
aspecto es así, pero el error probablemente esté en otro lugar, ya que tampoco funciona con 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);
}
}
}
También intenté usar el vcl_purge
fromhttps://stackoverflow.com/a/61507014 pero esto no parece ayudar con las prohibiciones (?).
Estoy usando el X-Purge-Regex
encabezado para no preocuparme por tener que escapar de caracteres especiales como enhttps://stackoverflow.com/a/38526921pero simplemente una prohibición como obj.http.url ~ 0
no funciona.
Estoy usando barniz 6.5 con vcl 4.0.
Solicitud de prohibición
* << 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
OBTENER después de agregar la prohibición
* << 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
Reproduciendo el problema
Para reproducir el error:
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 nuevamente y obtendrá el objeto anterior
Respuestas
La obj.http.url ~ 5/3/4.pbf
prohibición que está emitiendo coincide con un url
encabezado de respuesta.
Recuerde: la URL es un encabezado de solicitud, no un encabezado de respuesta. No hay razón para entrar en pánico, lo que estás haciendo tiene mucho sentido y está relacionado con el alcance del llamado acechador de la prohibición .
Ban merodeador
El acechador ban es un hilo que procesa asincrónicamente prohibiciones en la lista de prohibiciones y hace coincidir objetos con las prohibiciones para eliminar patrones de objetos de la caché.
El acechador ban no opera dentro del alcance de una solicitud, pero solo es consciente del alcance del objeto.
Para hacer coincidir correctamente la información de la solicitud, el contexto de la solicitud se puede agregar como un encabezado de respuesta. Y eso es lo que estás haciendo a través deobj.http.url
Entonces, ¿por qué no funciona la prohibición?
La razón por la que su prohibición no funciona es porque no lo configuró obj.http.url
en su archivo VCL. Como resultado, el acechador de la prohibición no puede igualar ningún objeto con él.
Cómo solucionar el problema
La solución es simple: configure los encabezados que faltan en el contexto de respuesta del backend, como se ilustra a continuación:
sub vcl_backend_response {
set beresp.http.url = bereq.url;
set beresp.http.host = bereq.http.host;
}
Cuando el backend responde, y justo antes de que el objeto se almacene en la caché, podemos configurar los encabezados que faltan.
Después de eso, el merodeador de prohibición podrá hacer coincidir la expresión de prohibición con los objetos correctos y eliminarlos de la caché.
No olvide que los objetos no se emparejan de inmediato: solo se eliminan cuando alcanzan el ban_lurker_agevalor predeterminado de 1 minuto.