Nginx proxy_buffer_size不适用于缓存密钥

时间:2016-03-04 09:23:12

标签: caching nginx

我需要在工作中缓存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 缓存密钥之间的关系是什么?在这种情况下如何缓存响应?

2 个答案:

答案 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标题大小。

请参阅:http://nginx.2469901.n2.nabble.com/upstream-sent-too-big-header-while-reading-response-header-from-upstream-td7588354.html