记录一次Ftp设置导致的,InputStream.read()阻塞问题

在最近的项目开发中,用到了多线程读取ftp上的文件,处理数据量9万左右,但每次执行,都会有几个线程长时间阻塞。导致程序卡死,无法结束。具体堆栈信息如下:

"taskExecutorTwo-119" #311 prio=5 os_prio=0 tid=0x00000000323e1000 nid=0x4064 runnable [0x0000000051f5f000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream._jr$jni$socketRead0(Native Method)
at java.net.SocketInputStream.socketRead0(SocketInputStream.java)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.io.FilterInputStream.read(FilterInputStream.java:133)
at com.google.common.io.ByteStreams.toByteArrayInternal(ByteStreams.java:180)
at com.google.common.io.ByteStreams.toByteArray(ByteStreams.java:220)
at net.risesoft.service.impl.DocInterfaceImpl.handleWs(DocInterfaceImpl.java:459)
at net.risesoft.service.impl.DocInterfaceImpl.lambda$0(DocInterfaceImpl.java:109)
at net.risesoft.service.impl.DocInterfaceImpl$$Lambda$1137/2139954890.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- <0x00000005ca2f77e0> (a java.util.concurrent.ThreadPoolExecutor$Worker)


可以看到,线程在代码中FilterInputStream.read(FilterInputStream.java:133) ,读取流的时候陷入了阻塞,ftp的通信是由socket进行的,可以看到SocketInputStream.read(SocketInputStream.java:171)也陷入了阻塞。

经过排查发现我的ftp连接设置如下:

ftpClient.setDataTimeout(2400000);
ftpClient.setSoTimeout(0);

由于之前没有详细了解过ftp连接的配置,这两个设置都是从网上直接抄过来的。后俩经过查找资料发现:

SoTimeout:用于设置传输socket控制命令超时时间

setDataTimeout:用于设置文件数据传输超时时间

这两个参数我设置太长,如果存在网络波动等因素导致程序拿不到文件时会使程序一直阻塞。将配置改为如下:

ftpClient.setDataTimeout(1*60*1000);
ftpClient.setSoTimeout(1*60*1000);

bug成功解决。




0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
下载 APP