dromara/hutool

HttpUtil#downloadBytes(String url)无法传超时时间导致线程阻塞

Closed this issue · 10 comments

版本情况

JDK版本: openjdk_8_201
hutool版本: 5.8.26

问题描述(包括截图)

这个方法无法传超时时间导致一旦发生网络问题就可能导致阻塞

  1. 复现代码

  2. 堆栈信息

"ForkJoinPool.commonPool-worker-1" #2149 daemon prio=5 os_prio=0 tid=0x00007ff44c10f000 nid=0x867 runnable [0x00007ff3f028a000]
   java.lang.Thread.State: RUNNABLE
        at java.net.SocketInputStream.socketRead0(Native Method)
        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 sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
        at sun.security.ssl.InputRecord.read(InputRecord.java:503)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:975)
        - locked <0x00000007118f6a80> (a java.lang.Object)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
        - locked <0x00000007118f6c08> (a java.lang.Object)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
        at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
        at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:162)
        at cn.hutool.http.HttpConnection.connect(HttpConnection.java:377)
        at cn.hutool.http.HttpRequest.send(HttpRequest.java:1158)
        at cn.hutool.http.HttpRequest.execute(HttpRequest.java:968)
        at cn.hutool.http.HttpRequest.executeAsync(HttpRequest.java:953)
        at cn.hutool.http.HttpDownloader.requestDownload(HttpDownloader.java:97)
        at cn.hutool.http.HttpDownloader.downloadBytes(HttpDownloader.java:40)
        at cn.hutool.http.HttpUtil.downloadBytes(HttpUtil.java:425)
  1. 测试涉及到的文件(注意脱密)

比如报错的Excel文件,有问题的图片等。

你可以使用HttpRequest构建请求:

HttpUtil.createGet(url, true)
  .timeout(timeout)
  .executeAsync()
  ..bodyBytes()

主要是我觉得既然提供了对应的api其实就应该更加完善,提供一个选项或者使用全局默认。如果不能加超时时间,downloadBytes其实就没存在的必要了,因为都走上述您提供的代码就可以了,并且可以完美避坑。

@sanyou3 全局配置可见:HttpGlobalConfig.setTimeout()

这个也改变不了downloadBytes阻塞的问题。。。

@sanyou3 我这边没有更好的办法了……欢迎提供思路。

我建议可以在下个版本加一个重载方法,嘿嘿。

@sanyou3 加个超时时间么?这个和全局设置是一样的,既然解决不了阻塞问题,那加个重载也没有意义吧。

您没懂我的意思,之所以阻塞是因为没有超时时间,设置超时时间就没这个问题了。HttpGlobalConfig.setTimeout()设置的超时时间目前无法作用到downloadBytes方法,所以我说HttpGlobalConfig.setTimeout()没用。加个重载方法或者让downloadBytes能够使用HttpGlobalConfig.setTimeout()这个全局配置就可以了。

@sanyou3 sorry,明白了,脑袋蒙住了。我看了源码,确实没有使用全局的超时。

这是个bug。

5.8.28会:

  1. 修复全局超时在download中无效的问题
  2. 增加超时重载方法。

嘿嘿。