[Nginx] 如何击败response_status = 0

一篇来自“旁注”类别的文章。

TL:DR:

http2_max_field_size 8k; # всех спасет!

在其中一个项目中,在更改了后端的一些内部逻辑后,我开始在日志中观察到一个奇怪的response_code,即0。在日志中它看起来像这样:

{
  "timestamp": "2020-01-17T08:41:51+00:00",
  "remote_addr": "zzz.zzz.zzz.zzz",
  "request_time": 0,
  "upstream_response_time": "",
  "upstream_header_time": "",
  "http_accept_language": "-language",
  "response_status": 0,
  "request": "",
  "host": "example.com",
  "upstream_addr": "",
  "http_referrer": "",
  "request_length": 5854,
  "bytes_sent": 0,
  "http_user_agent": ""
}


阅读文档并在谷歌上搜索这个主题绝对没有任何结果 - 因为...... 据称,当客户端关闭连接而不传递标头时,会发生此行为。 好吧,还有 wsgi_ 缓冲区大小的各种奇特事物,在我们的例子中,它不适合“以任何方式”这个词。

总的来说,我们认为这个问题不是问题,因为考虑到我们的数量,这个问题根本不重要。

直到我对以下问题感到困惑:在某些情况下,链接可以通过 http 打开,没有任何问题,但完全拒绝通过 https 工作,产生奇妙的效果: 连接 #0 到主机 example.com 保持不变
curl: (52) 来自服务器的空回复

在日志中,我们只能通过 IP 来跟踪这个东西 - 没有请求或任何其他数据,如上面的示例所示。 只是臭名昭著的状态是0,但我知道我没有中断请求! 我开始思考可能出什么问题。 一切都变得非常简单:

听443 ssl http2 积压=8192;

好吧,如果你使用 http2 进行 ssl 连接,那么仅仅配置请求缓冲区是不够的,还必须在 ngx_http_v2_module 中配置它们,即:

Синтаксис:	http2_max_field_size размер;
Умолчание:	http2_max_field_size 4k;
Контекст:	http, server

限制使用 HPACK 压缩的请求标头的最大大小。 该约束同样适用于名称和值。 如果使用霍夫曼编码,解压后的名称和值字符串的实际大小可能会更大。 默认限制适用于大多数查询。

一般来说,就是这样。 为什么全部? 因为链接的长度很长——比那些相同的 4k 还要长。

例如,通过将其设置为 8kb(或可能足够的大小),我们可以解决问题。
这样的事情。

来源: habr.com

添加评论