【问题标题】:Dealing with OkHttp HTTP/2 REFUSED_STREAM errors处理 OkHttp HTTP/2 REFUSED_STREAM 错误
【发布时间】:2021-08-25 05:21:06
【问题描述】:

我们正在使用 OkHttp3 (v4.9.1) 从 Spring Boot 应用程序以高度并发的方式建立 h2c(没有 TLS 的 HTTP/2)连接。为此,我们使用以下方法缩小了支持的协议范围:

builder.protocols(List.of(Protocol.H2_PRIOR_KNOWLEDGE))

建立连接通常可以正常工作,并且使用 HTTP/2 流而不是专用连接。然而,我们观察到当服务器(基于 nginx,单节点,单地址)在达到一定数量的请求后关闭连接(如其keepalive_request 选项所指示的那样)时,会出现零星的错误突发。发生这种情况时,OkHttp 似乎不会尝试重试连接,而只是向调用者抛出异常:

okhttp3.internal.http2.StreamResetException: stream was reset: REFUSED_STREAM
    at okhttp3.internal.http2.Http2Stream.takeHeaders(Http2Stream.kt:148)
    at okhttp3.internal.http2.Http2ExchangeCodec.readResponseHeaders(Http2ExchangeCodec.kt:96)
    at okhttp3.internal.connection.Exchange.readResponseHeaders(Exchange.kt:106)
    at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.kt:79)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
    at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:34)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
    at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
    at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
    at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
    at org.example.OkHttpAutoConfiguration.lambda$authenticate$3(OkHttpAutoConfiguration.java:95)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
    at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
    at okhttp3.internal.connection.RealCall.execute(RealCall.kt:154)
    [...]

请求是这样发起的:

httpClient.newCall(buildRequest(uri)).execute()

处理这些错误的推荐方法是什么?

是否有一个选项(我们可能错过了)让 OkHttp 对应用程序透明地处理这个问题?

【问题讨论】:

    标签: okhttp http2


    【解决方案1】:

    对于这个问题,您已经为我们提供了在 OkHttp 中修复它的理由。 https://github.com/square/okhttp/issues/6700

    在此期间,您需要一个使用 try/catch 块的拦截器,如果异常符合此条件,则在 catch 子句中再次尝试。

    【讨论】:

      猜你喜欢
      • 2017-12-16
      • 1970-01-01
      • 1970-01-01
      • 2016-09-17
      • 2015-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多