我需要在工作中缓存POST响应。所以我有下一个位置:
location /api {
client_max_body_size 1m;
client_body_buffer_size 1m;
proxy_buffers 16 128k;
proxy_busy_buffers_size 256k;
proxy_pass http://127.0.0.1:8080;
proxy_cache api;
proxy_cache_methods POST;
proxy_cache_key "$request_uri|$request_body";
add_header X-Cache-Status $upstream_cache_status;
}
我的nginx版本是1.8.0
当我发送大型主体的POST请求时,我在nginx error.log中收到此消息:
proxy_buffer_size 4096 is not enough for cache key, it should be increased to at least 129024
Nginx文档有下一个描述:
proxy_buffer_size 设置用于读取从代理服务器接收的响应的第一部分的缓冲区的大小。 此部分通常包含一个小响应标头。 默认情况下,缓冲区大小等于一个内存页面。这是4K或8K,具体取决于平台。然而,它可以做得更小。
proxy_buffer_size 与缓存密钥之间的关系是什么?在这种情况下如何缓存响应?
答案 0 :(得分:2)
首先,我建议使用GET而不是POST,因此您可以使用location /api {
client_max_body_size 12m;
server_names_hash_bucket_size 255;
proxy_buffers 8 2m;
proxy_buffer_size 12m;
proxy_busy_buffers_size 12m;
client_body_buffer_size 12m;
proxy_pass http://127.0.0.1:8080;
proxy_cache api;
proxy_cache_methods POST;
proxy_cache_key "$request_uri|$request_body";
add_header X-Cache-Status $upstream_cache_status;
}
,因此无需调整缓冲区即可使用。
此外,虽然增加缓冲区可能会起作用,但它会增加很多开销,因为您将整个请求主体包含在缓存键中。与REDIS,Memcache和其他类似,缓存键应该是唯一且短的(并且你使它太大)。
如果您必须使用POST,则需要将其调整为几兆字节,如下所示:
$content_length > client_body_buffer_size
拥有一个大缓冲区不会耗尽所有内存,但根据$PATH “如果允许攻击者打开许多连接但它不能用作DoS向量让他们全部分配client_body_buffer_size缓冲区“。
似乎根据这个答案:http://mailman.nginx.org/pipermail/nginx/2013-September/040447.html
当$request_body == ""
时,请求正文被写入文件和变量$request_body
...所以这是另一件需要考虑的事情,因为你的{{1}}可能是空的,你会得到colisions在你的缓存上。
话虽如此,我强烈建议您从POST更改为GET,添加COOKIE或找到其他方式来识别您的请求/用户。 如果您有大量的大POST请求,那么很多请求都无法很好地扩展。
答案 1 :(得分:0)
如果要在缓存键中使用<div id=container>
<div id=big>
<div id=white></div>
</div>
<div id=small><h1>FOCUS</h1></div>
</div>
,则应将$request_body
设置为大于和的值proxy_buffer_size
client_body_buffer_size
和resoponse标题大小。