Larangan pernis ditambahkan tetapi objek lama dikembalikan
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 age
dalam 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' varnish
atau sebagai alternatifnya varnishadm
dan kemudian ban obj.http.url ~ 5/3/4.pbf
dan 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_recv
Penampilan 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_purge
darihttps://stackoverflow.com/a/61507014 tapi ini sepertinya tidak membantu untuk larangan (?).
Saya menggunakan X-Purge-Regex
tajuk untuk tidak khawatir harus keluar dari karakter khusus seperti dihttps://stackoverflow.com/a/38526921tapi larangan seperti obj.http.url ~ 0
itu 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
The obj.http.url ~ 5/3/4.pbf
larangan yang Anda mengeluarkan, adalah pencocokan url
respon 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.url
di 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.