生产环境的Tomcat在Full GC时,部分客户端请求会有connect timeout报错,然而我们客户端设置的连接超时是10s,FullGC最长不过2s,一番搜索后发现是backlog的锅,在此记录一下backlog的工作原理
How TCP backlog works in Linux
两个队列管理backlog
SYN queue
管理三次握手过程中的连接,使用如下参数控制长度,系统级别/proc/sys/net/ipv4/tcp_max_syn_backlogaccept queue
管理ESTABLISHED状态的连接,这个Q中的连接可以被accpet(2)处理,Q长度在listen(2)调用时传入,同时最大值受如下参数限制,应用级别net.core.somaxconn
查看accept queue大小
ss -lt(查询结果的Send-Q列)如果accept queue空间耗尽
服务器默认会忽略三次握手最后的ACK包,可以通过将如下参数设置为1将忽略变为发送RST包net.ipv4.tcp_abort_on_overflow此时服务器仍然处于
SYN RECEIVED状态,而客户端已经是ESTABLISHED状态
服务器会继续向客户端发送SYN/ACK包,重试间隔从3s开始,重试次数由如下参数控制net.ipv4.tcp_synack_retries = 5当客户端收到重发的
SYN/ACK包,会重发ACK包,如果queue有空间,即进入ESTABLISHED状态,反之服务端继续忽略ACK包
当重试次数耗尽,queue仍然没有空间,服务器会发送RST包,终止连接从客户端角度来看,发送
ACK后连接已经建立,此时客户端如果发送数据,会导致数据重传,由于TCP Slow-start,重传的数据量会受到限制,如果客户端等待服务器发送数据,即会出现half-open connection问题SYN queue限流
accept queue空间耗尽时,系统会对SYN queue进行限流,即使SYN queue没满,部分SYN包仍然会被丢弃,由客户端负责重试net.ipv4.tcp_syn_retries = 5可以通过
netstat -s查看丢弃的包960 times the listen queue of a socket overflowed
960 SYNs to LISTEN sockets ignored或者
nstat -aTcpExtListenOverflows 960
TcpExtListenDrops 960分为两个队列的优势
应用根据处理能力管理accept queue的大小
系统管理员根据流量特征管理SYN queue的大小合理设置accept queue大小
设置过大会导致请求堆积,使请求响应变慢
设置过小会导致并发高时部分请求被丢弃,引发不合理的connect timeout错误
|
|
Tomcat
The HTTP ConnectoracceptCount 控制accept queue长度,默认值为100maxThreads 最大处理线程数,默认值为200maxConnections 最大连接数,NIO下默认值为10000,BIO(8.5版本废弃)下同maxThreads
Tuning Tomcat For A High Throughput, Fail Fast System
计算实际处理能力,当超出处理能力时尽量fail fast,防止影响全局性能