导致"java.io.IOException:stream was reset:CANCEL"的原因是okhttp和spdy?

mlc*_*mlc 9 java networking android spdy okhttp

我正在试验OKHttp(版本2.0.0-RC2)和SPDY并且看到IOException: stream was reset: CANCEL了很多,可能是一些初步测试中所有请求的10%或更多.在使用Apache HttpClient和常规https时,就我所知,我们没有看到任何等效问题.我很确定当SPDY被禁用时我们也没有看到与OkHttp等效的东西(client.setProtocols(ImmutableList.of(Protocol.HTTP_1_1)))但我没有做足够的测试以100%自信.

这个先前的问题看到了这些异常,并且建议忽略它们,但这看起来很疯狂:我们在从服务器读取数据时遇到异常,因此我们中止数据处理代码(使用Jackson).在这种情况下我们需要做点什么.我们可以重试请求,当然,但有时它是一个POST请求,这是不重试的,如果我们已经开始从服务器接收数据,那么这是一个不错的选择,由于已经采取的请求的操作的服务器.

理想情况下,是客户端和/或我们能以减少这些异常的发生率做服务器的一些配置,但我不明白,SPDY不够好,甚至不知道从哪里开始寻找或建议我们的服务器管理员团队开始寻找.

堆栈跟踪,以防它有用:

java.io.IOException: stream was reset: CANCEL
  at com.squareup.okhttp.internal.spdy.SpdyStream$SpdyDataSource.checkNotClosed(SpdyStream.java:442)
  at com.squareup.okhttp.internal.spdy.SpdyStream$SpdyDataSource.read(SpdyStream.java:344)
  at com.squareup.okhttp.internal.http.SpdyTransport$SpdySource.read(SpdyTransport.java:273)
  at okio.RealBufferedSource.exhausted(RealBufferedSource.java:60)
  at okio.InflaterSource.refill(InflaterSource.java:96)
  at okio.InflaterSource.read(InflaterSource.java:62)
  at okio.GzipSource.read(GzipSource.java:80)
  at okio.RealBufferedSource$1.read(RealBufferedSource.java:227)
  at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.loadMore(UTF8StreamJsonParser.java:174)
  at com.fasterxml.jackson.core.base.ParserBase.loadMoreGuaranteed(ParserBase.java:431)
  at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishString2(UTF8StreamJsonParser.java:2111)
  at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishString(UTF8StreamJsonParser.java:2092)
  at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.getText(UTF8StreamJsonParser.java:275)
  at com.fasterxml.jackson.databind.deser.std.BaseNodeDeserializer.deserializeObject(JsonNodeDeserializer.java:205)
  at com.fasterxml.jackson.databind.deser.std.BaseNodeDeserializer.deserializeArray(JsonNodeDeserializer.java:230)
  at com.fasterxml.jackson.databind.deser.std.BaseNodeDeserializer.deserializeObject(JsonNodeDeserializer.java:202)
  at com.fasterxml.jackson.databind.deser.std.JsonNodeDeserializer.deserialize(JsonNodeDeserializer.java:58)
  at com.fasterxml.jackson.databind.deser.std.JsonNodeDeserializer.deserialize(JsonNodeDeserializer.java:15)
  at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:2765)
  at com.fasterxml.jackson.databind.ObjectMapper.readTree(ObjectMapper.java:1546)
  at com.fasterxml.jackson.core.JsonParser.readValueAsTree(JsonParser.java:1363)
  at (application-level code...)
Run Code Online (Sandbox Code Playgroud)

Jes*_*son 3

最好的办法是在分配了 CANCEL 错误代码的两个位置设置断点:(SpdyStream#closeInternal第 246 行)和SpdyStream#receiveRstStream(第 304 行)。如果您可以在此处放置一个断点,您就可以捕获正在取消您的流,这将揭示问题。

如果出于某种原因您无法附加调试器,您可以检测代码以在到达这些行时打印堆栈跟踪:

new Exception("SETTING ERROR CODE TO " + errorCode).printStackTrace();
Run Code Online (Sandbox Code Playgroud)

无论哪种情况,我都是该代码的作者,我很乐意帮助您解决此问题。