Nginx做前端Proxy时TIME_WAIT过多的问题

  • FROM http://rtbdev.com/2014/03/nginx-proxy-time_wait/

  • 我们的DSP系统目前基本非凌晨时段的QPS都在10W以上,我们使用Golang来处理这些HTTP请求,Web服务器的前端用Nginx来做负载均衡,通过Nginxproxy_pass来与Golang交互。

    由于nginx代理使用了短链接的方式和后端交互的原因,使得系统TIME_WAITtcp连接很多:

     

    1

    2

    3

    4

    5

    6

    shell>netstat -n|awk'/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'

    TIME_WAIT 250263

    CLOSE_WAIT 57

    FIN_WAIT23

    ESTABLISHED2463

    SYN_RECV 8

    ss 比 netstat 要快,所以也可以用下面的命令来查看:

     

    1

    shell> ss-ant|awk'NR>1 {++s[$1]} END {for(k in s) print k,s[k]}'

    这会占用系统过多的端口,还浪费了系统资源,所以我们必须想办法减少TIME_WAIT

    TIME_WAIT导致占用过多端口的一个影响是会占用我们需要使用到的端口,例如我们有个服务监听的端口为8012,重启的时候经常会提示端口被占用。
    通过查看/proc/sys/net/ipv4/ip_local_port_range可以知道设置的Linux内核自动分配端口的端口范围:

     

    1

    2

    shell>cat/proc/sys/net/ipv4/ip_local_port_range

    1025 65535

    对于这个设置系统就会从1025~65535这个范围内随机分配端口来用于连接,而我们服务的8012端口刚好在这个范围之内,所以如果8012刚好被系统分配出去使用了,则启动我们服务的时候,就会提示端口被占用。

    所以我们需要设置/proc/sys/net/ipv4/ip_local_reserved_ports来告诉系统给我们预留哪些端口,不可以用于自动分配。

     

    1

    2

    3

    4

    shell> vim/etc/sysctl.conf

    net.ipv4.ip_local_reserved_ports = 8012,11211-11220

     

    shell>sysctl -p

    关于预留端口的更具体信息可以参考:

    · 网络端口预留

    · 预留端口避免占用ip_local_reserved_ports

    上面我们解决了端口占用问题,但是我们还是需要解决TIME_WAIT过多的问题。
    Nginx 1.1以上版本的upstream已经支持keep-alive的,所以我们可以开启Nginx proxykeep-alive来减少tcp连接:

     

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    upstream http_backend{

        server127.0.0.1:8080;

     

        keepalive 16;

    }

     

    server{

        ...

     

        location /http/ {

            proxy_pass http://http_backend;

            proxy_http_version1.1;

            proxy_set_header Connection"";

            ...

        }

    }

    具体参考Nginx的官方文档: http://nginx.org/cn/docs/http/ngx_http_upstream_module.html#keepalive

    开了keep-alive之后,TIME_WAIT明显减少:

     

    1

    2

    3

    4

    5

    6

    7

    shell>netstat-|awk'/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'

    TIME_WAIT12612

    CLOSE_WAIT11

    FIN_WAIT1 4

    FIN_WAIT21

    ESTABLISHED7667

    SYN_RECV3

    另外不少文章提到可以修改系统的/etc/sysctl.conf配置来减少TIME_WAITtcp连接:

     

    1

    2

    net.ipv4.tcp_tw_reuse =1

    net.ipv4.tcp_tw_recycle = 1

    参见: http://blog.s135.com/post/271/

    不过开启tcp_tw_recycle可能会带来一些不稳定的网络问题,请参考:

    · 记一次TIME_WAIT网络故障

    · 再叙TIME_WAIT

    关于sysctl相关配置的说明,请参考:
    https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt

     

    参考文章:

    · 部分网络内核参数说明

    · http://performancewiki.com/linux-tuning.html

    · tcp协议timestamp字段导致问题分析

    · http://www.lognormal.com/blog/2012/09/27/linux-tcpip-tuning/

     


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值