java常见的网络异常

1. java.net.SocketTimeoutException

这个异常比较常见,socket超时错误,超时分为连接超时和读取超时。一般有 2 个地方会抛出这个

  • 一个是在调用Socket.connect方法的时候,这个超时参数由connect(SocketAddress endpoint,int timeout) 中的后者来决定
  • 还有就是在调用Socket.read方法的时候,setSoTimeout(int timeout),这个是设定读取的超时时间。它们设置成 0 均表示无限大。

连接超时往往是由于网络不稳定造成的,但是读取超时不一定是网络延迟造成的,很有可能是下游服务的响应时间过长。

2. java.net.ConnectException: Connection refused: connect

该异常发生在客户端进行 new Socket(ip, port)或者 socket.connect(address,timeout)操作时,原因:指定 ip 地址的机器不能找到(也就是说从当前机器不存在到指定 ip 路由),或者是该 ip 存在,但找不到指定的端口进行监听。

应该首先检查客户端的 ip 和 port是否写错了,假如正确则从客户端 ping 一下服务器看是否能 ping 通,假如能 ping 通(服务服务器端把 ping 禁掉则需要另外的办法),则看在服务器端的监听指定端口的程序是否启动。

3. java.net.SocketException: Socket is closed

该异常在客户端和服务器均可能发生。异常的原因是己方主动关闭了连接后(调用了 Socket 的 close 方法)再对网络连接进行读写操作。

4. java.net.SocketException:

Connection reset或者Connect reset by peer:Socket write error

  • connection reset by peer在调用write或者read的时候都会出现。按照glibc的说法,是such as by the remote machine rebooting or an unrecoverable protocol violation。从字面意义上来看,是表示远端机器重启或者发生不可恢复的错误。

  • 从我的测试来看,目前只出现在对端直接kill掉进程的情况。

    • 对比tcpdump的截包图来看,直接kill掉远端进程的话,远端并没有发送FIN序号,来告诉对方,我已经关闭管道,而是直接发送了RST序号。

      比如:server(tomcat)在向客户端client发送数据的过程中,client被kill掉了,发送RST数据包,中断了TCP连接,会出现这个异常,异常如下:

      org.apache.catalina.connector.ClientAbortException: java.io.IOException: Connection reset by peer

  • 而远端如果调用close或者shutdown的话,是会发送FIN序号的。按照TCP的四次挥手来看,是需要FIN这个序号的。

    个人猜测,如果在本端没有收到对方的FIN序号而直接收到了RST序号的话,表明对端出现了machine rebooting or an unrecoverable protocol violation,这时候对这个管道的IO操作,就会出现connection reset by peer错误

该异常在客户端和服务器端均有可能发生,引起该异常的原因有两个。

  • 第一个就是假如一端的 Socket 被关闭(或主动关闭或者因为异常退出而引起的关闭), 另一端仍发送数据,发送的第一个数据包引发该异常(Connect reset by peer)。

  • 另一个是一端退出,但退出时并未关闭该连接,另一端假如再从连接中读数据则抛出该异常(Connection reset)。

5. java.net.SocketException: Broken pipe

指通信管道已坏。发生这个异常的场景是,通信的一方在收到“Connect reset by peer: Socket write
error”后,如果再继续写数据则会抛出 Broken pipe 异常

生产情况下发生此错误的场景:

一个java服务作为websocket client启动一个定时任务线程向远端websocket server发送请求,结果这个socket已经关闭了,于是会发生Connect reset by peer

之后这个线程30秒后继续向websocket server发送请求,则会抛出broken pipe

使用prometheus通过actuator监控spring boot服务。prometheus读取超时了,断开了连接。而这时候management tomcat还在处理请求,它并不知道prometheus已经断开了连接,处理完成请求后再将结果发给prometheus,就broken pipe了

6. java.net.SocketException: Too many open files

指进程打开文件句柄数超过限制。当并发用户数比较大时,服务器可能会报这个异常。这是因为每创建一个 Socket 连接就需要一个文件句柄,此外服务端程序在处理请求时可能也需要打开一些文件。
lsof -p pid命令查看进程打开了哪些文件,是不是有资源泄露,也就是说进程打开的这些文件本应该被关闭,但由于程序的 Bug 而没有被关闭
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如果没有资源泄露,可以通过设置增加最大文件句柄数。具体方法是通过ulimit -a来查看系统目前资源限制,通过ulimit -n 10240修改最大文件数。

7. java.io.EOFException: SSL peer shut down incorrectly

java.io.EOFException: SSL peer shut down incorrectly
com.alibaba.fastjson.JSONException: syntax error, expect {, actual EOF, pos 0

手动curl了对方的接口,发现OK

原因:网络波动导致问题

my csdn: 生产问题:java.io.EOFException: SSL peer shut down incorrectly

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值