RTB Dev tcp 状态统计

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

Posted on 14 三月, 2014 in Linux, 高性能Web服务

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

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


shell> netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'
TIME_WAIT 250263
CLOSE_WAIT 57
FIN_WAIT2 3
ESTABLISHED 2463
SYN_RECV 8



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

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内核自动分配端口的端口范围:


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

1025 65535

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

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

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 proxy的keep-alive来减少tcp连接:

upstream http_backend {
    server 127.0.0.1:8080;

    keepalive 16;
}

server {
    ...

    location /http/ {
        proxy_pass http://http_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        ...
    }
}

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

Posted on 14 三月, 2014 in Linux, 高性能Web服务

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

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

shell> netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}' TIME_WAIT 250263 CLOSE_WAIT 57 FIN_WAIT2 3 ESTABLISHED 2463 SYN_RECV 8

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_WAIT2 3

ESTABLISHED 2463

SYN_RECV 8

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

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

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内核自动分配端口的端口范围:

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

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来告诉系统给我们预留哪些端口,不可以用于自动分配。

shell> vim /etc/sysctl.conf net.ipv4.ip_local_reserved_ports = 8012,11211-11220 shell> sysctl -p

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 proxy的keep-alive来减少tcp连接:

upstream http_backend {    server 127.0.0.1:8080;    keepalive 16; } server {    ...    location /http/ {        proxy_pass http://http_backend;        proxy_http_version 1.1;        proxy_set_header Connection "";        ...    } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

upstream http_backend {

    server 127.0.0.1:8080;

 

    keepalive 16;

}

 

server {

    ...

 

    location /http/ {

        proxy_pass http://http_backend;

        proxy_http_version 1.1;

        proxy_set_header Connection "";

        ...

    }

}

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

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

shell> netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'
TIME_WAIT 12612
CLOSE_WAIT 11
FIN_WAIT1 4
FIN_WAIT2 1
ESTABLISHED 7667
SYN_RECV 3


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

net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1

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



你可能感兴趣的:(RTB Dev tcp 状态统计)