Lackverbot wird hinzugefügt, aber altes Objekt wird zurückgegeben

Jan 08 2021

Ich verwende Lack vor einem Kachelserver, um Mapbox-Kacheln zwischenzuspeichern. Um alte Kacheln zu entfernen, wollte ich Verbote verwenden, um eine große Anzahl von zwischengespeicherten Kacheln effektiv zu entfernen. Mein Problem ist, dass der Lack immer noch die zwischengespeicherten Objekte verwendet (zumindest das agein der Antwort zeigt dies an) und das Backend nicht kontaktiert.

Ich fordere zuerst http: //varnish/5/3/4.pbf an, füge dann ein Verbot mit curl -X BAN -H 'X-Purge-Regex: 5/3/4.pbf' varnishoder alternativ hinzu varnishadmund ban obj.http.url ~ 5/3/4.pbffordere dann und danach erneut http: //varnish/5/3/4.pbf an.

Am Anfang ist meine Verbotsliste leer:

Present bans:
1610117471.434488     1 C

Das Verbot wird erfolgreich mit hinzugefügt 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>

und erscheint in der Verbotsliste

Present bans:
1610117369.028870     0 -  obj.http.url ~ 5/3/4.pbf
1610117307.220739     1 C  

Nach erneuter Anforderung von http: //varnish/5/3/4.pbf zeigt die Verbotsliste an, dass das Verbot verwendet wurde

Present bans:
1610117471.434488     1 -  obj.http.url ~ 5/3/4.pbf

Das Alter der Antwort ist jedoch nicht 0, da es immer noch das Objekt der ersten Anforderung ist.

Nach kurzer Zeit wird das Verbot aufgehoben:

Present bans:
1610117471.434488     1 C  

Mein vcl_recvsieht so aus, aber der Fehler ist wahrscheinlich woanders, da es auch nicht funktioniert mit 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);
                }
        }
}

Ich habe auch versucht, das vcl_purgevon zu verwendenhttps://stackoverflow.com/a/61507014 aber dies scheint nicht für Verbote zu helfen (?).

Ich benutze den X-Purge-RegexHeader, um mir keine Sorgen darüber zu machen, dass ich Sonderzeichen wie in entkommen musshttps://stackoverflow.com/a/38526921aber nur ein Verbot wie obj.http.url ~ 0funktioniert nicht.

Ich benutze Lack 6.5 mit vcl 4.0.

Verbotsanfrage

*   << 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            

GET nach dem Hinzufügen von Verbot

*   << 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  

Das Problem reproduzieren

So reproduzieren Sie den Fehler:

  • git clone https://github.com/Baschdl/varnish-ban-setup.git && cd varnish-ban-setup
  • docker-compose up
  • Öffnen Sie http: // localhost: 8092/5/3 / 1.pbf
  • docker-compose exec varnish varnishadm ban obj.http.url ~ pbf
  • Öffnen Sie http: // localhost: 8092/5/3 / 1.pbf erneut und Sie erhalten das alte Objekt

Antworten

2 ThijsFeryn Jan 09 2021 at 00:23

Das von obj.http.url ~ 5/3/4.pbfIhnen ausgestellte Verbot entspricht einem urlAntwortheader.

Denken Sie daran: Die URL ist ein Anforderungsheader, kein Antwortheader. Kein Grund zur Panik, was Sie tun, macht durchaus Sinn und hängt mit dem Umfang des sogenannten Ban Lurker zusammen .

Ban Lurker

Der Ban Lurker ist ein Thread, der Verbote in der Ban-Liste asynchron verarbeitet und Objekte mit den Bans vergleicht, um Muster von Objekten aus dem Cache zu entfernen.

Der Ban Lurker arbeitet nicht innerhalb eines Anforderungsbereichs, sondern kennt nur den Objektbereich.

Um Anforderungsinformationen erfolgreich abzugleichen, kann der Anforderungskontext als Antwortheader hinzugefügt werden. Und das machen Sie überobj.http.url

Warum funktioniert das Verbot nicht?

Der Grund, warum Ihr Verbot nicht funktioniert, liegt darin, dass Sie es nicht obj.http.urlin Ihrer VCL-Datei festgelegt haben. Infolgedessen kann der Ban Lurker keine Objekte zuordnen.

So beheben Sie das Problem

Die Lösung ist einfach: Legen Sie die fehlenden Header im Backend-Antwortkontext fest, wie unten dargestellt:

sub vcl_backend_response {
    set beresp.http.url = bereq.url;
    set beresp.http.host = bereq.http.host;
}

Wenn das Backend antwortet und kurz bevor das Objekt im Cache gespeichert wird, können wir die fehlenden Header festlegen.

Danach kann der Ban-Lurker den Ban-Ausdruck den richtigen Objekten zuordnen und sie aus dem Cache entfernen.

Vergessen Sie nicht, dass die Objekte nicht sofort übereinstimmen: Sie werden erst entfernt, wenn sie die erreichen ban_lurker_age, die standardmäßig auf 1 Minute eingestellt ist.