Nginx与Upstream之间产生大量TIME_WAIT连接的解决办法

1. 现象

Nginx反向代理了一个Java服务,QPS大概是200,问题发生时的Nginx配置:

location / {
    proxy_pass http://192.168.3.4:18600;
}

在上游Java服务器上可以观察到大量(约2000个)的TIME_WAIT状态的网络连接
image.png

从Nginx的error日志中还发现与Java服务器建立连接偶发失败的情况:


 [error] 9208#0: *32907 connect() failed (111: Connection refused) while connecting to upstream, client: **.**.**.**, server: localhost, request: "POST /api HTTP/1.1", upstream: "http://**.**.**.**:18600/api", host: "**.**.**.**:8080"

2. 原因

由于QPS较高,Nginx与上游Java服务器建立的都是Http短连接,需要不停的创建和关闭TCP连接。而主动关闭TCP连接的一方需要等2MSL之后才会真正释放TCP连接,在2MSL之前连接的状态都是TIME_WAIT。

参考:TIME_WAIT状态产生的原因、过多的危害_爱吃芝麻球的博客-CSDN博客_time_wait连接过多的原因

由于每次上游Java服务在发送完响应报文后主动关闭了连接,所以作为主动关闭连接的一方,当并发量较高时就会产生大量的TIME_WAIT状态的连接。

3. 解决办法

解决的办法就是让Nginx与上游Java服务器之间通过Http 1.1的 Keepalive协议重用TCP连接,减少TCP连接数量
第一步: 修改location模块,添加http 1.1 协议头

location / {
    proxy_pass http://192.168.3.4:18600;
    
    # 添加http 1.1 协议头,这样上游Java服务就会启用keepalive,不会主动关闭TCP连接了
   proxy_http_version 1.1;
   proxy_set_header Connection "";
}

修改nginx配置重新生效后,发现上游Java服务器上的TIME_WAIT连接少了,但是Nginx服务器到上游Java服务器的TIME_WAIT连接却变多了。

原因在于Nginx自身没有复用到上游Java服务器的TCP连接,每次收到完整的响应报文之后就关闭连接了。

而这一次Nginx服务作为主动关闭TCP连接的一方,所以从Nginx服务器上TIME_WAIT的连接变多了。

第二步: 让Nginx主动重用TCP连接
Nginx的upstream模块中也有一个keepalive参数,但是这个参数与http协议中的keepalive参数的意义完全不同,upstream中的keepalive参数表示与上游服务建立的连接可以空闲的最大数量。

即如果在upstream模块中配置了keepalive参数,那么Nginx与上游服务之间建立的TCP连接就有了一个缓冲的池子,不再是用完立即释放了,而是可以有一个缓冲的池子可以放进去。keepalive参数的含义就是这个缓冲池子的最大值
参考:长连接 · Nginx 学习笔记 (gitbooks.io)

所以单独提取出一个upstream模块,并设置keepalive参数

upstream java_server {
    server 192.168.3.4:18600;
    
    # 设置可复用的tcp连接的空闲数量的最大值
    keepalive 50;
}

location / {
    proxy_pass http://java_server;
    
    # 添加http 1.1 协议头,这样上游Java服务就会启用keepalive,不会主动关闭TCP连接了
   proxy_http_version 1.1;
   proxy_set_header Connection "";
}

经过以上两步操作之后,Nginx与上游服务器之间的连接数就降下来了,直接降到了20个左右。。。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值