Tomcat 各种网络异常场景解决方案及优化,基础 + 底层 + 算法 + 数据库
可以用
netstat –an
查看端口被谁占用了,换个空闲端口即可。
java.net.ConnectException: Connection refused: connect
连接被拒绝。
当客户端调用
new Socket(ip, port)
或 Socket.connect 函数
原因是:
未找到指定 IP 的机器
机器存在,但该机器上没有开启指定监听端口
解决方案
从客户端机器 ping 一下服务端 IP:
ping 不通,看看 IP 是不是写错了?
ping 通,需要确认服务端的服务是不是挂了?
java.net.SocketException: Socket is closed
连接已关闭。
通信的一方主动关闭了 Socket 连接(调用了 Socket 的 close 方法),接着又对 Socket 连接进行了读写操作,这时 os 会报“Socket 连接已关闭”。
java.net.SocketException: Connection reset/Connect reset by peer: Socket write error
连接被重置。
通信的一方已将 Socket 关闭,可能是主动关闭或是因为异常退出,这时如果通信的另一方还在写数据,就会触发这个异常(Connect reset by peer)
若对方还在尝试从 TCP 连接中读数据,则会抛出 Connection reset 异常。
为了避免这些异常发生,在编写网络通信程序时要确保:
程序退出前要主动关闭所有的网络连接
检测通信的另一方的关闭连接操作,当发现另一方关闭连接后自己也要关闭该连接。
java.net.SocketException: Broken pipe
通信管道已坏。
发生这个异常的场景是,通信的一方在收到“Connect reset by peer: Socket write error”后,如果再继续写数据则会抛出 Broken pipe 异常,解决方法同上。
java.net.SocketException: Too many open files
进程打开文件句柄数超过限制。
触发场景
当并发用户数比较大时。
因为每创建一个 Socket 连接就需一个文件句柄,而且服务端程序在处理请求时可能也需要打开一些文件。
可通过
lsof -p pid
查看进程打开了哪些文件,是否有资源泄露,即进程打开的这些文件本应该被关闭,但由于程序的 Bug 而没有被关闭。
若无资源泄露,可通过设置增加最大文件句柄数:通过
ulimit -a
查看系统目前资源限制,通过
ulimit -n 10240
修改最大文件数。
=========================================================================
maxConnections
acceptCount
客户端向服务端发送 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
设置过大
请求等待时间会比较长
设置过小
高并发情况下,客户端会立即触发 Connection reset 异常
评论