Closed jonbev closed 5 years ago
Here's a little more detail:
A route is requested, which is tagged with 'crontask' and is served from the cache:
$ http GET localhost/v2/crontask 'Host:xxxx.api.tabs-software.co.uk' 'Authorization:Bearer XXXXX' -p hH
GET /v2/crontask HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Authorization: Bearer XXXXX
Connection: keep-alive
Host: xxxx.api.tabs-software.co.uk
User-Agent: HTTPie/0.9.8
HTTP/1.1 200 OK
Accept-Ranges: bytes
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: content-location, location
Connection: keep-alive
Content-Encoding: gzip
Content-Length: 7275
Content-Type: application/json
Date: Thu, 11 Apr 2019 09:30:40 GMT
Vary: Accept-Encoding, X-User-Context-Hash
X-Cache-Action: HIT
X-Cache-Age: 533894.992
X-Cache-Hits: 4504
X-Cache-Storage: storage.default
X-Cache-TTL: 70904.383
X-Cache-Tags: crontask
X-Controller-Name: crontask_list
A PURGEKEYS request is sent to invalidate anything tagged 'crontask'. Note that in this instance 0 objects get purged:
$ http PURGEKEYS localhost/ 'xkey-purge:crontask' -p hHb
PURGEKEYS / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 0
Host: xxxx.api.tabs-software.co.uk
User-Agent: HTTPie/0.9.8
xkey-purge: crontask
HTTP/1.1 200 Purged 0 objects, expired 0 objects
Accept-Ranges: bytes
Connection: keep-alive
Content-Length: 231
Date: Wed, 17 Apr 2019 13:46:57 GMT
X-Cache-Action: SYNTH
<!DOCTYPE html>
<html>
<head>
<title>200 Purged 0 objects, expired 0 objects</title>
</head>
<body>
<h1>Status: 200</h1>
<p>Purged 0 objects, expired 0 objects</p>
<hr>
<p>tabs 2 API</p>
</body>
</html>
Another request to the original route shows that the object hasn't been expired from the cache:
$ http GET localhost/v2/crontask 'Host:xxxx.api.tabs-software.co.uk' 'Authorization:Bearer XXXXX' -p hH
GET /v2/crontask HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Authorization: Bearer XXXXX
Connection: keep-alive
Host: xxxx.api.tabs-software.co.uk
User-Agent: HTTPie/0.9.8
HTTP/1.1 200 OK
Accept-Ranges: bytes
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: content-location, location
Connection: keep-alive
Content-Encoding: gzip
Content-Length: 7275
Content-Type: application/json
Date: Thu, 11 Apr 2019 09:30:40 GMT
Vary: Accept-Encoding, X-User-Context-Hash
X-Cache-Action: HIT
X-Cache-Age: 534117.553
X-Cache-Hits: 4508
X-Cache-Storage: storage.default
X-Cache-TTL: 70681.822
X-Cache-Tags: crontask
X-Controller-Name: crontask_list
The corresponding output from varnishlog:
* << Request >> 93915826
- Begin req 93915825 rxreq
- Timestamp Start: 1555507675.177348 0.000000 0.000000
- Timestamp Req: 1555507675.177348 0.000000 0.000000
- ReqStart 127.0.0.1 42800 a0
- ReqMethod PURGEKEYS
- ReqURL /
- ReqProtocol HTTP/1.1
- ReqHeader Host: localhost
- ReqHeader User-Agent: HTTPie/0.9.8
- ReqHeader Accept-Encoding: gzip, deflate
- ReqHeader Accept: */*
- ReqHeader Connection: keep-alive
- ReqHeader xkey-purge: crontask
- ReqHeader Content-Length: 0
- ReqHeader X-Forwarded-For: 127.0.0.1
- VCL_call RECV
- ReqUnset X-Forwarded-For: 127.0.0.1
- ReqHeader X-Forwarded-For: 127.0.0.1
- ReqHeader CloudFront-Forwarded-Proto: https
- VCL_acl MATCH invalidators "localhost"
- ReqHeader n-gone: 0
- ReqHeader n-softgone: 0
- ReqUnset n-gone: 0
- ReqHeader n-gone: 0
- VCL_return synth
- ReqUnset Accept-Encoding: gzip, deflate
- ReqHeader Accept-Encoding: gzip
- VCL_call HASH
- VCL_return lookup
- Timestamp Process: 1555507675.177391 0.000043 0.000043
- RespHeader Date: Wed, 17 Apr 2019 13:27:55 GMT
- RespHeader Server: Varnish
- RespHeader X-Varnish: 93915826
- RespProtocol HTTP/1.1
- RespStatus 200
- RespReason OK
- RespReason Purged 0 objects, expired 0 objects
- VCL_call SYNTH
- RespUnset Server: Varnish
- RespUnset X-Varnish: 93915826
- RespHeader X-Cache-Action: SYNTH
- VCL_return deliver
- RespHeader Content-Length: 231
- Storage malloc Transient
- RespHeader Accept-Ranges: bytes
- RespHeader Connection: keep-alive
- Timestamp Resp: 1555507675.177434 0.000087 0.000043
- ReqAcct 177 0 177 179 231 410
- End
The xkey part of the varnish config file:
sub fos_tags_xkey_recv {
if (req.method == "PURGEKEYS") {
if (!client.ip ~ invalidators) {
return (synth(405, "Not allowed"));
}
# If neither of the headers are provided we return 400 to simplify detecting wrong configuration
if (!req.http.xkey-purge && !req.http.xkey-softpurge) {
return (synth(400));
}
# Based on provided header invalidate (purge) and/or expire (softpurge) the tagged content
set req.http.n-gone = 0;
set req.http.n-softgone = 0;
if (req.http.xkey-purge) {
set req.http.n-gone = xkey.purge(req.http.xkey-purge);
}
if (req.http.xkey-softpurge) {
set req.http.n-softgone = xkey.softpurge(req.http.xkey-softpurge);
}
return (synth(200, "Purged "+req.http.n-gone+" objects, expired "+req.http.n-softgone+" objects"));
}
}
Versions:
Ubuntu 18.04.2
varnishd (varnish-6.0.3 revision 7d1ded3aa033a018317dbafc61587026ea2ef8a3)
xkey module compiled from the latest source on the 29th March
NB. We had previously been using varnish 5, but upgraded to 6 in an attempt to fix the problem, but without success.
I don't see enough because there are no logs and no VCL snippet from the backend side, but it looks like you expect vmod-xkey to pick up keys from X-Cache-Tags
headers.
See here: https://github.com/varnish/varnish-modules/blob/0.15.0/docs/vmod_xkey.rst#description
Hash keys are specified in the
xkey
response header.
So what you need to do in vcl_backend_response
is something like:
if (beresp.http.X-Cache-Tags) {
set beresp.http.XKey = beresp.http.X-Cache-Tags;
}
Hi @Dridi,
Good spot! We do normally use the xkey response header, but have found an edge case where a newly started instance would serve the wrong headers whilst it was being bootstrapped.
Thanks ever so much for your help!
Pete
@jonbev I think you can probably close this now.
Thanks
Looking at the logs I can see that the xkey-purge is purging objects - "RespReason Purged 27 objects, expired 0 objects" but we are still seeing cached responses that are tagged in this example this "property-235". It seems to work ok sometimes as we have two servers running the same ami on amazon and we see this issue with only one of the servers, also some objects with the same tag are correctly purged but others are not. If we replace the server it will work ok for a time and then fail again. I'm not sure how we can debug this as we can't reliably reproduce the problem. Both servers are receiving the invalidations and the cache age of the responses is high so it's not a backend issue.
Is there a way to list objects that have a certain tag?
Any suggestions on how to debug this?
There is a bit more detail on here - https://github.com/FriendsOfSymfony/FOSHttpCache/issues/448
<< Request >> 31474814 Begin req 31474813 rxreq Timestamp Start: 1554714883.640552 0.000000 0.000000 Timestamp Req: 1554714883.640552 0.000000 0.000000 ReqStart 10.100.1.50 38442 a0 ReqMethod PURGEKEYS ReqURL / ReqProtocol HTTP/1.1 ReqHeader Host: xxxx.api.tabs-software.co.uk ReqHeader User-Agent: GuzzleHttp/6.3.3 curl/7.47.0 PHP/7.1.27-1+ubuntu16.04.1+deb.sury.org+1 ReqHeader xkey-purge: property-235 property-235 property ReqHeader Connection: Close ReqHeader X-Forwarded-For: 10.100.1.50 VCL_call RECV ReqUnset X-Forwarded-For: 10.100.1.50 ReqHeader X-Forwarded-For: 10.100.1.50 ReqHeader CloudFront-Forwarded-Proto: https VCL_acl MATCH invalidators "10.100.1.0"/24 ReqHeader n-gone: 0 ReqHeader n-softgone: 0 ReqUnset n-gone: 0 ReqHeader n-gone: 27 VCL_return synth VCL_call HASH VCL_return lookup Timestamp Process: 1554714883.640706 0.000154 0.000154 RespHeader Date: Mon, 08 Apr 2019 09:14:43 GMT RespHeader Server: Varnish RespHeader X-Varnish: 31474814 RespProtocol HTTP/1.1 RespStatus 200 RespReason OK RespReason Purged 27 objects, expired 0 objects VCL_call SYNTH RespUnset Server: Varnish RespUnset X-Varnish: 31474814 RespHeader X-Cache-Action: SYNTH VCL_return deliver RespHeader Content-Length: 233 Storage malloc Transient RespHeader Accept-Ranges: bytes RespHeader Connection: close Timestamp Resp: 1554714883.640742 0.000190 0.000036 ReqAcct 212 0 212 175 233 408 End