我们有几个请求的 http 标头大小超过了我们的 tomcat 应用程序中默认接受的大小,即 maxHttpHeaderSize = 8192(https://tomcat.apache.org/tomcat-8.0-doc/config/http.html)
此外,nginx 对分配给大型客户端请求的缓冲区有默认限制,即 large_client_header_buffers size = 8K(http://nginx.org/en/docs/http/ngx_http_core_module.html#large_client_header_buffers)
但是,在不增加 nginx 端的 large_client_header_buffers 的情况下,仅增加 tomcat 中的 maxHttpHeaderSize 参数,请求仍然可以通过。
根据 nginx 文档,“缓冲区仅按需分配”。我不明白这一点。缓冲区不是为每个请求分配的吗?
答案1
nginx 默认值为:
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;
这意味着它可以并行处理最多 4 个最大 8kB 大小的请求。瓶颈是 tomcat,其标头大小值固定为 4kB,因此最多4并行请求大于1kB且小于8kB可以通过你的nginx,但是如果他的参数不变的话他们就会卡在tomcat上。
答案2
nginx 请求缓冲区由两部分组成:
client_header_buffer_size
large_client_header_buffers
这文档解释一下client_header_buffer_size
nginx 策略:
设置读取客户端请求标头的缓冲区大小。对于大多数请求,1K 字节的缓冲区就足够了。但是,如果请求包含较长的 cookie,或者来自 WAP 客户端,则可能无法容纳 1K。如果请求行或请求标头字段无法容纳此缓冲区,则会分配由 large_client_header_buffers 指令配置的更大缓冲区。
文档large_client_header_buffers
说明如下:
设置用于读取大型客户端请求标头的缓冲区的最大数量和大小。请求行不能超过一个缓冲区的大小,否则会向客户端返回 414(请求 URI 太大)错误。请求标头字段也不能超过一个缓冲区的大小,否则会向客户端返回 400(错误请求)错误。缓冲区仅按需分配。默认情况下,缓冲区大小等于 8K 字节。如果在请求处理结束后连接转换为保持活动状态,则释放这些缓冲区。
因此,默认情况下,nginx 会为请求标头分配 1k 内存。如果请求标头无法容纳在此空间中,则 nginx 会分配最多 N 个大小为 X 的块来存储额外的请求标头。N
并X
在指令中指定large_client_header_buffers
。
例如,如果有 4 kB 的请求头,nginx 将使用 1kB 的基本分配,然后为其余部分分配一个 8 kB 的块。
使用默认值,标头的总大小可以是 1 kB + 4 * 8 kB = 33 kB。但是,由于每个请求标头行都必须完全放入缓冲区,因此缓冲区无法得到充分利用。因此,标头的实际容量较小。
我不知道 Tomcat 标头限制如何工作,但我认为它的策略与 nginx 策略不同,并且值不能直接比较。