美文网首页
Nginx与Upstream之间产生大量TIME_WAIT连接的

Nginx与Upstream之间产生大量TIME_WAIT连接的

作者: 杨_同_学 | 来源:发表于2023-01-30 10:22 被阅读0次

    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个左右。。。

    相关文章

      网友评论

          本文标题:Nginx与Upstream之间产生大量TIME_WAIT连接的

          本文链接:https://www.haomeiwen.com/subject/pmdmhdtx.html