我们在 Java Web 服务器前面级联了两个 NginX 反向代理。
第一个代理在 FreeBSD (11.1-RELEASE-p10) 负载均衡器上运行,并将所有互联网流量代理到内部网络。有两个这样的负载均衡器。它们具有相同的配置:
location / {
proxy_pass http://app_servers;
proxy_set_header X-Request-ID $request_id;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
第二个代理在 CentOS 应用服务器上运行,并将请求代理到同一主机上的不同应用程序。有两个应用服务器,也具有相同的配置:
location / {
proxy_pass http://java_app;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $http_x_real_ip;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
因此,管道看起来像这样:
LB - AS - Java
Internet ---| X
LB - AS - Java
Java Web 服务器有一个返回 HTTP 1.1 分块响应的请求路径。每个响应大约需要 2 毫秒:
HTTP/1.1 200 OK
Connection: keep-alive
Transfer-Encoding: chunked
Content-Type: application/json;charset=UTF-8
Date: Tue, 06 Nov 2018 10:51:08 GMT
42
{..........JSON..........}
0
第二个代理(在应用服务器上)也在大约 2 毫秒内返回它们。那里没有问题。
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 07 Nov 2018 10:34:29 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
42
{..........JSON..........}
0
但第一个代理(在负载均衡器上)每次返回给客户端大约需要 102 毫秒。这会导致持续 100 毫秒的延迟。这就是问题所在。
同一 Java 服务器有另一条请求路径,该路径返回带有标头的正常(非分块)响应Content-Length
。两个代理都在 2 毫秒内返回这些响应,没有任何问题。它们经过 NginX 中完全相同的位置。
这不应该是网络问题,因为两个应用服务器和两个网关上都存在这个问题。
这让我认为分块编码在某种程度上导致了 100 毫秒的延迟。但我不明白为什么,也不知道如何修复它。
任何线索都将受到感谢。
答案1
如果你使用的是 nginx >= 1.8,你可以使用:
proxy_request_buffering off