背景

当并发请求高的时候会出现 connection reset by peer 这样的错误,也就是 服务端主动关闭了socket但是客户端依然再用

 

分析

正常的tcp 建立连接的时候

  1. tcp connect 请求进来的时候 服务端 会加入 SYN队列
  2. 当三次握手成功之后,会从 SYN队列移动到ACCEPT队列
  3. 然后应用层通过accept 方法接受新的socket

 

结论

  1. 如果是dial tcp的过程中出错 ,很可能就是 accept队列满了,并且在参数 net.ipv4.tcp_abort_on_overflow  =1 的情况下  会立马发送RST信号给client
  2. 当然也有很多别的原因会导致connection reset by peer, 比如 mysql的wait_timeout过低,mysql服务端会主动关闭连接等等

可以通过以下命令来查看,第一种情况的问题

sysctl -a |grep tcp_max_syn_backlog
sysctl -a |grep somaxconn
sysctl -a |grep tcp_abort
netstat -s | grep -i listen

[root@iZ23w6heibjZ ~]# sysctl -a |grep tcp_max_syn_backlog

net.ipv4.tcp_max_syn_backlog = 1024

[root@iZ23w6heibjZ ~]#  sysctl -a |grep somaxconn

net.core.somaxconn = 128

[root@iZ23w6heibjZ ~]#  sysctl -a |grep tcp_abort

net.ipv4.tcp_abort_on_overflow = 0

[root@iZ23w6heibjZ ~]#  netstat -s | grep -i  listen

    21361 times the listen queue of a socket overflowed  

    21361 SYNs to LISTEN sockets ignored

[root@iZ23w6heibjZ ~]#

accept队列默认是128,当并发较高的情况下,服务端来不及处理新的连接就会出现问题

 

解决办法

  1. 增加连接池
  2. 增加长连接的生命周期,比如mysql client端的 maxLifetime,可以缓解瞬间批量重连的问题
Logo

更多推荐