Larangan pernis ditambahkan tetapi objek lama dikembalikan

Jan 08 2021

Saya menggunakan pernis di depan server ubin untuk menyimpan ubin kotak peta. Untuk menghapus ubin lama, saya bermaksud menggunakan larangan untuk secara efektif menghapus sejumlah besar ubin yang di-cache. Masalah saya adalah bahwa pernis masih menggunakan objek yang di-cache (setidaknya agedalam respons menunjukkan ini) dan tidak menghubungi backend.

Saya pertama-tama meminta http: //varnish/5/3/4.pbf, kemudian menambahkan larangan dengan curl -X BAN -H 'X-Purge-Regex: 5/3/4.pbf' varnishatau sebagai alternatifnya varnishadmdan kemudian ban obj.http.url ~ 5/3/4.pbfdan kemudian meminta http: //varnish/5/3/4.pbf lagi.

Pada awalnya daftar larangan saya kosong:

Present bans:
1610117471.434488     1 C

Larangan berhasil ditambahkan dengan 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>

dan muncul di daftar larangan

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

Setelah meminta http: //varnish/5/3/4.pbf lagi, daftar larangan menunjukkan bahwa larangan tersebut digunakan

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

tetapi usia responsnya bukan 0, karena ini masih objek dari permintaan pertama.

Setelah beberapa saat, larangan tersebut akan dihapus:

Present bans:
1610117471.434488     1 C  

vcl_recvPenampilan saya seperti ini tetapi kesalahannya mungkin ada di tempat lain karena itu juga tidak berfungsi dengan 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);
                }
        }
}

Saya juga mencoba menggunakan vcl_purgedarihttps://stackoverflow.com/a/61507014 tapi ini sepertinya tidak membantu untuk larangan (?).

Saya menggunakan X-Purge-Regextajuk untuk tidak khawatir harus keluar dari karakter khusus seperti dihttps://stackoverflow.com/a/38526921tapi larangan seperti obj.http.url ~ 0itu tidak akan berhasil.

Saya menggunakan varnish 6.5 dengan vcl 4.0.

Permintaan larangan

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

DAPATKAN setelah menambahkan larangan

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

Mereproduksi masalah

Untuk mereproduksi bug:

  • git clone https://github.com/Baschdl/varnish-ban-setup.git && cd varnish-ban-setup
  • docker-compose up
  • Buka http: // localhost: 8092/5/3 / 1.pbf
  • docker-compose exec varnish varnishadm ban obj.http.url ~ pbf
  • Buka http: // localhost: 8092/5/3 / 1.pbf lagi dan Anda akan mendapatkan objek lama

Jawaban

2 ThijsFeryn Jan 09 2021 at 00:23

The obj.http.url ~ 5/3/4.pbflarangan yang Anda mengeluarkan, adalah pencocokan urlrespon header.

Ingat: URL adalah header permintaan, bukan header respons. Tidak ada alasan untuk panik, apa yang Anda lakukan masuk akal, dan terkait dengan ruang lingkup yang disebut larangan lurker .

Larang lurker

The larangan lurker adalah benang yang asynchronous memproses larangan pada daftar larangan dan pertandingan objek untuk larangan untuk menghilangkan pola obyek dari cache.

Larangan lurker tidak beroperasi dalam lingkup permintaan, tetapi hanya mengetahui ruang lingkup objek.

Agar berhasil mencocokkan informasi permintaan, konteks permintaan dapat ditambahkan sebagai header respons. Dan itulah yang Anda lakukan melaluiobj.http.url

Jadi mengapa larangan itu tidak berhasil?

Alasan mengapa larangan Anda tidak berfungsi, adalah karena Anda tidak mengaturnya obj.http.urldi file VCL Anda. Akibatnya, lurker larangan tidak dapat mencocokkan objek apa pun dengannya.

Cara memperbaiki masalah tersebut

Solusinya sederhana: setel header yang hilang dalam konteks respons backend, seperti yang diilustrasikan di bawah ini:

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

Saat backend merespons, dan tepat sebelum objek disimpan dalam cache, kita dapat menyetel header yang hilang.

Setelah itu, lurker larangan akan dapat mencocokkan ekspresi larangan ke objek yang tepat, dan menghapusnya dari cache.

Jangan lupa bahwa objek tidak langsung dicocokkan: mereka hanya dihapus ketika mencapai ban_lurker_age, yang diatur ke 1 menit secara default.