Tomcat 两个比较关键的参数:maxConnections 和 acceptCount。在解释这个参数之前,先简单回顾下 TCP 连接的建立过程:客户端向服务端发送 SYN 包,服务端回复 SYN+ACK,同时将这个处于 SYN_RECV 状态的连接保存到半连接队列。客户端返回 ACK 包完成三次握手,服务端将 ESTABLISHED 状态的连接移入accept 队列,等待应用程序(Tomcat)调用 accept 方法将连接取走。这里涉及两个队列:
半连接队列:保存 SYN_RECV 状态的连接。队列长度由net.ipv4.tcp_max_syn_backlog设置。
全连接(accept)队列:保存 ESTABLISHED 状态的连接。队列长度为min(net.core.somaxconn,backlog)。其中 backlog 是我们创建 ServerSocket 时指定的参数,最终会传递给 listen 方法:int listen(int sockfd, int backlog);
如果我们设置的 backlog 大于net.core.somaxconn,accept 队列的长度将被设置为net.core.somaxconn,而这个 backlog 参数就是 Tomcat 中的acceptCount参数,默认值是 100,但请注意net.core.somaxconn的默认值是 128。你可以想象在高并发情况下当 Tomcat 来不及处理新的连接时,这些连接都被堆积在 accept 队列中,而acceptCount参数可以控制 accept 队列的长度,超过这个长度时,内核会向客户端发送 RST,这样客户端会触发上文提到的“Connection reset”异常。
而 Tomcat 中的maxConnections是指 Tomcat 在任意时刻接收和处理的最大连接数。当 Tomcat 接收的连接数达到 maxConnections 时,Acceptor 线程不会再从 accept 队列中取走连接,这时 accept 队列中的连接会越积越多。maxConnections 的默认值与连接器类型有关:NIO 的默认值是 10000,APR 默认是 8192。所以你会发现 Tomcat 的最大并发连接数等于maxConnections + acceptCount。如果 acceptCount 设置得过大,请求等待时间会比较长;如果 acceptCount 设置过小,高并发情况下,客户端会立即触发 Connection reset 异常。
查看服务器连接数
netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
网友评论