首先,一些背景。 有哪些扩展/解决一堆短网址的工人:
http://t.co/example -> http://example.com
所以,我们只要按照重定向。 而已。 我们并没有从连接任何数据。 我们得到了200之后,我们返回最终网址和密切的InputStream。
现在,这个问题本身。 在生产服务器上的解析器线程之一挂内InputStream.close()
调用:
"ProcessShortUrlTask" prio=10 tid=0x00007f8810119000 nid=0x402b runnable [0x00007f882b044000]
java.lang.Thread.State: RUNNABLE
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.skip(BufferedInputStream.java:352)
- locked <0x0000000561293aa0> (a java.io.BufferedInputStream)
at sun.net.www.MeteredStream.skip(MeteredStream.java:134)
- locked <0x0000000561293a70> (a sun.net.www.http.KeepAliveStream)
at sun.net.www.http.KeepAliveStream.close(KeepAliveStream.java:76)
at java.io.FilterInputStream.close(FilterInputStream.java:155)
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.close(HttpURLConnection.java:2735)
at ru.twitter.times.http.URLProcessor.resolve(URLProcessor.java:131)
at ru.twitter.times.http.URLProcessor.resolve(URLProcessor.java:55)
at ...
短暂的研究之后,我明白了skip()
被调用,以清理其发送回连接池前的数据流(如果保持活动设置上?)。 不过我不知道如何避免这种情况。 此外,如果有一些不好的设计在我们的代码还是有问题JDK我对此表示怀疑。
所以,问题是:
- 是否有可能避免挂在
close()
? 保证一些合理的超时,例如。 - 是否有可能避免在所有连接读取数据? 还记得我只是想最后的URL。 其实我觉得,我不想
skip()
在所有被称为...
更新:
KeepAliveStream ,线79, close()
方法:
// Skip past the data that's left in the Inputstream because
// some sort of error may have occurred.
// Do this ONLY if the skip won't block. The stream may have
// been closed at the beginning of a big file and we don't want
// to hang around for nothing. So if we can't skip without blocking
// we just close the socket and, therefore, terminate the keepAlive
// NOTE: Don't close super class
try {
if (expected > count) {
long nskip = (long) (expected - count);
if (nskip <= available()) {
long n = 0;
while (n < nskip) {
nskip = nskip - n;
n = skip(nskip);} ...
越来越多的在我看来,有在JDK本身就是一个错误。 不幸的是,这是非常难以重现此...