为什么 nginx proxy_pass 会关闭我的连接?

问题描述 投票:0回答:3

文档说明如下

设置代理的 HTTP 协议版本。默认使用1.0版本。建议将版本 1.1 用于 keepalive 连接和 NTLM 身份验证。

在我的 nginx 配置中

    location / {
        proxy_http_version 1.1;
        proxy_pass http://127.0.0.1:1980;
    }

直接执行http://127.0.0.1:1980,我可以看到我的应用程序在一个连接上收到许多请求(当我刷新时)。这是我发送的回复

HTTP/1.1 200 好 内容类型:text/html 内容长度:14 连接:保持活动状态 你好世界!

但是 nginx 发出一个请求并关闭它。啥?我可以看到 nginx 发送了“Connection: keep-alive”标头。我可以看到它添加了服务器和日期标头。我尝试添加

proxy_set_header Connection "keep-alive";
但这没有帮助。

如何让 nginx 不关闭每个线程的连接?

http nginx proxypass
3个回答
39
投票

为了让 Nginx 保持连接,需要进行以下配置:

  • 配置适当的标头(HTTP 1.1和Connection标头不包含“Close”值,实际值并不重要,Keep-alive或只是一个空值)

  • 使用带有 keepalive 指令的上游块,仅 proxy_pass url 不起作用

  • 源服务器应启用保持活动状态

因此,以下 Nginx 配置使 keepalive 为您工作:

upstream keepalive-upstream {
  server 127.0.0.1:1980;
  keepalive 64;
}

server { 
  location / { 
    proxy_pass http://keepalive-upstream;
    proxy_set_header Connection "";
    proxy_http_version 1.1;
  } 
}

根据 RFC-793 第 3.5 节,确保您的源服务器未完成连接:

TCP 连接可能以两种方式终止: (1) 正常 TCP 关闭 使用 FIN 握手的序列,以及 (2) “中止”,其中一个或 发送更多 RST 段并且连接状态立即 被丢弃。如果 TCP 连接被远程站点关闭,则本地 必须告知应用程序它是正常关闭还是被关闭 已中止。

更多详细信息可以在 Stackoverflow 上的另一个答案中找到。


12
投票

keepalive 应该在上游块中启用,而不是直接 proxy_pass http://ip:port

对于 HTTP,proxy_http_version 指令应设置为“1.1”,并且应清除“Connection”标头字段

像这样:

upstream keepalive-upstream {
    server 127.0.0.1:1980;
    keepalive 23;
}

 location / {
    proxy_http_version 1.1;
    proxy_set_header Connection ""; 
    proxy_pass http://keepalive-upstream;
}

0
投票

如果您希望 DNS 重新解析与上游 keepalive 池一起工作,那么:

从 nginx 版本 1.27.3 开始,非企业版本也可以在上游块内的服务器上使用 resolve 参数来重新解析域名。

resolver 8.8.8.8 upstream http_backend { zone upstream_dynamic 64k; server custom.domain.tld:443 resolve; keepalive 16; } server { ... location /http/ { proxy_pass https://http_backend; proxy_http_version 1.1; proxy_set_header Connection ""; ... } }
为了使此参数起作用,必须在 http 块或相应的上游块中指定解析器指令。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.