1 | | Hello guys, |
2 | | |
3 | | I'm having a hard time to understand if I'm having a bug in my configuration or if I hit a bug in NGINX. |
4 | | |
5 | | My configuration so far: |
6 | | |
7 | | {{{ |
8 | | proxy_cache_valid 200 15s; |
9 | | proxy_cache_valid 301 15s; |
10 | | proxy_cache_valid 404 15s; |
11 | | proxy_cache stage_proxy-cache; |
12 | | proxy_cache_lock on; |
13 | | proxy_cache_use_stale updating error timeout http_404 http_500 http_502 http_503 http_504; |
14 | | proxy_cache_background_update on; |
15 | | proxy_cache_revalidate on; |
16 | | }}} |
17 | | |
18 | | Our application, a Magnolia CMS, is defining the Cache-Control header via max-age and therfor controling how long an asset has to be kept in cache before it becomes STALE. |
19 | | |
20 | | Now I'm experiencing a "strange" behavior which I don't understand. The behavior is as following: |
21 | | |
22 | | - I'm curling for an object like a HTML 3 times: |
23 | | |
24 | | {{{ |
25 | | → curl -I https://invaliddomain-com.stage.invaliddomain.info/en/products/formwork/concrete-maturity-computer.html |
26 | | HTTP/2 200 |
27 | | server: nginx |
28 | | date: Mon, 20 Aug 2018 09:41:29 GMT |
29 | | content-type: text/html;charset=UTF-8 |
30 | | content-length: 72937 |
31 | | x-magnolia-registration: Registered |
32 | | access-control-allow-origin: http://tools.live.invaliddomain.info |
33 | | access-control-allow-methods: GET, OPTIONS, HEAD |
34 | | access-control-allow-headers: X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept |
35 | | cache-control: max-age=60, public |
36 | | expires: Mon, 20 Aug 2018 09:42:29 GMT |
37 | | last-modified: Mon, 20 Aug 2018 09:37:28 GMT |
38 | | x-upstream: 10.6.198.15:8080 |
39 | | content-security-policy: default-src 'self' http: https:;img-src http: https: data:;font-src http: https: data:;script-src 'unsafe-inline' 'unsafe-eval' 'self' http: https:;style-src 'unsafe-inline' http: https:; frame-ancestors http://*.stage.invaliddomain.info https://*.stage.invaliddomain.info http://*.live.invaliddomain.info https://*.live.invaliddomain.info |
40 | | x-content-type-options: nosniff |
41 | | x-xss-protection: 1; mode=block |
42 | | x-cache: MISS |
43 | | |
44 | | → curl -I https://invaliddomain-com.stage.invaliddomain.info/en/products/formwork/concrete-maturity-computer.html |
45 | | HTTP/2 200 |
46 | | server: nginx |
47 | | date: Mon, 20 Aug 2018 09:41:32 GMT |
48 | | content-type: text/html;charset=UTF-8 |
49 | | content-length: 72937 |
50 | | x-magnolia-registration: Registered |
51 | | access-control-allow-origin: http://tools.live.invaliddomain.info |
52 | | access-control-allow-methods: GET, OPTIONS, HEAD |
53 | | access-control-allow-headers: X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept |
54 | | cache-control: max-age=60, public |
55 | | expires: Mon, 20 Aug 2018 09:42:29 GMT |
56 | | last-modified: Mon, 20 Aug 2018 09:37:28 GMT |
57 | | content-security-policy: default-src 'self' http: https:;img-src http: https: data:;font-src http: https: data:;script-src 'unsafe-inline' 'unsafe-eval' 'self' http: https:;style-src 'unsafe-inline' http: https:; frame-ancestors http://*.stage.invaliddomain.info https://*.stage.invaliddomain.info http://*.live.invaliddomain.info https://*.live.invaliddomain.info |
58 | | x-content-type-options: nosniff |
59 | | x-xss-protection: 1; mode=block |
60 | | x-cache: HIT |
61 | | |
62 | | ... after more then 60 seconds (cache-control: max-age) |
63 | | |
64 | | HTTP/1.1 200 |
65 | | Server: nginx |
66 | | Date: Mon, 20 Aug 2018 09:45:07 GMT |
67 | | Content-Type: text/html;charset=UTF-8 |
68 | | Content-Length: 72937 |
69 | | Connection: keep-alive |
70 | | Keep-Alive: timeout=5 |
71 | | X-Magnolia-Registration: Registered |
72 | | Access-Control-Allow-Origin: http://tools.live.invaliddomain.info |
73 | | Access-Control-Allow-Methods: GET, OPTIONS, HEAD |
74 | | Access-Control-Allow-Headers: X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept |
75 | | Cache-Control: max-age=60, public |
76 | | Expires: Mon, 20 Aug 2018 09:44:47 GMT |
77 | | Last-Modified: Mon, 20 Aug 2018 09:37:28 GMT |
78 | | Content-Security-Policy: default-src 'self' http: https:;img-src http: https: data:;font-src http: https: data:;script-src 'unsafe-inline' 'unsafe-eval' 'self' http: https:;style-src 'unsafe-inline' http: https:; frame-ancestors http://*.stage.invaliddomain.info https://*.stage.invaliddomain.info http://*.live.invaliddomain.info https://*.live.invaliddomain.info |
79 | | X-Content-Type-Options: nosniff |
80 | | X-XSS-Protection: 1; mode=block |
81 | | X-CACHE: STALE |
82 | | }}} |
83 | | |
84 | | Since the object hasn't been in the cache yet, first I receive a MISS, with the second request within 60 seconds I receive a X-CACHE: HIT and after more then 60 seconds of not requesting the object I receive a STALE and with the next curl again a HIT. Fine for me, everything works as expected for existing objects. |
85 | | |
86 | | - Now I'm doing this for a page which actually doesn't exists like following: |
87 | | |
88 | | {{{ |
89 | | curl -I https://invaliddomain-com.stage.invaliddomain.info/en/testpage.html |
90 | | HTTP/1.1 404 |
91 | | Server: nginx |
92 | | Date: Mon, 20 Aug 2018 09:56:18 GMT |
93 | | Content-Type: text/html;charset=UTF-8 |
94 | | Connection: keep-alive |
95 | | Keep-Alive: timeout=5 |
96 | | X-Magnolia-Registration: Registered |
97 | | Access-Control-Allow-Origin: http://tools.live.invaliddomain.info |
98 | | Access-Control-Allow-Methods: GET, OPTIONS, HEAD |
99 | | Access-Control-Allow-Headers: X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept |
100 | | Cache-Control: max-age=60 |
101 | | Expires: Mon, 20 Aug 2018 09:57:05 GMT |
102 | | }}} |
103 | | |
104 | | First thing I realize is that there is no X-CACHE status comming back, but according to the NGINX access log I've "hit" somthing: |
105 | | |
106 | | {{{ |
107 | | [20/Aug/2018:11:58:53 +0200] Cache: MISS 10.6.198.15:8080 0.573 404 458 37.xx.6.6 invaliddomain-com.stage.invaliddomain.info /en/testpage.html |
108 | | [20/Aug/2018:11:58:54 +0200] Cache: HIT - - 404 458 37.xx.6.6 invaliddomain-com.stage.invaliddomain.info /en/testpage.html |
109 | | }}} |
110 | | |
111 | | According to the Cache-Control header I should receive a STALE after 60 seconds and I do: |
112 | | |
113 | | {{{ |
114 | | [20/Aug/2018:11:59:55 +0200] Cache: STALE - - 404 458 37.xx.6.6 invaliddomain-com.stage.invaliddomain.info /en/testpage.html |
115 | | }}} |
116 | | |
117 | | But I'm not leaving this status anymore until I purge the NGINX proxy cache: |
118 | | |
119 | | {{{ |
120 | | ... |
121 | | [20/Aug/2018:12:00:13 +0200] Cache: STALE - - 404 458 37.xx.6.6 invaliddomain-com.stage.invaliddomain.info /en/testpage.html |
122 | | [20/Aug/2018:12:00:14 +0200] Cache: STALE - - 404 458 37.xx.6.6 invaliddomain-com.stage.invaliddomain.info /en/testpage.html |
123 | | [20/Aug/2018:12:00:15 +0200] Cache: STALE - - 404 458 37.xx.6.6 invaliddomain-com.stage.invaliddomain.info /en/testpage.html |
124 | | [20/Aug/2018:12:00:16 +0200] Cache: STALE - - 404 458 37.xx.6.6 invaliddomain-com.stage.invaliddomain.info /en/testpage.html |
125 | | ... |
126 | | }}} |
127 | | |
128 | | Now I'm having a tricky situation. Let's say I'm removing an object from my backend by disabling it (404) for remake or whatever (new CSS etc.). The object is not available and I'm receiving a STALE 404 after while from cache. After finished remake of my object I'm enabling it again to be available, but I'm still receiving an 404 STALE object from cache, and therefor my new object won't be available until I purge the proxy cache. |
129 | | |
130 | | My questions are: |
131 | | |
132 | | - Do I have a configuration error? |
133 | | - Do I misunderstand the proxy cache concept? |
134 | | - Is this behavior expected? |
135 | | - Are there any solutions for my problem? |