My task is to implement microcaching strategy using nginx, that is, cache responses of some POST endpoints for a few seconds.
In http
section of the nginx.conf
I have the following:
proxy_cache_path /tmp/cache keys_zone=cache:10m levels=1:2 inactive=600s max_size=100m;
Then I have location
in server
:
location /my-url/ {
root dir;
client_max_body_size 50k;
proxy_cache cache;
proxy_cache_valid 10s;
proxy_cache_methods POST;
proxy_cache_key "$request_uri|$request_body";
proxy_ignore_headers Vary;
add_header X-Cached $upstream_cache_status;
proxy_pass http://my-upstream;
}
The application located at my-upstream
outputs Cache-Control: max-age=10
which, if I understand correctly, should make the responses cacheable.
But when I make repetitive requests using curl in short time (less than 10 seconds)
curl -v --data "a=b&c=d" https://my-host/my-url/1573
all of them reach the backend (according to backend logs). Also, X-Cached
is always MISS
.
Request and response follow:
> POST /my-url/1573 HTTP/1.1
> Host: my-host
> User-Agent: curl/7.47.0
> Accept: */*
> Content-Length: 113
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 113 out of 113 bytes
< HTTP/1.1 200 OK
< Server: nginx
< Date: Tue, 08 May 2018 07:16:10 GMT
< Content-Type: text/html;charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Keep-Alive: timeout=60
< Vary: Accept-Encoding
< X-XSS-Protection: 1
< X-Content-Type-Options: nosniff
< Strict-Transport-Security: max-age=31536000
< Cache-Control: max-age=10
< Content-Language: en-US
< X-Cached: MISS
So the caching does not work.
It turned out that the following directive (which was defined globally) prevented caching from working:
proxy_buffering off;
When I override it under location
config with proxy_buffering on;
, caching starts working.
So, to make caching work with POST requests, we have to do the following:
Cache-Control: public, max-age=10
header on the serverproxy_cache_path
config and location
config in nginx (examples are given in the question text)proxy_buffering
is on
for the location on which we want to have caching enabled.