当前位置: 首页 > 知识库问答 >
问题:

根据错误状态代码关闭Reactor网络连接

梁宏才
2023-03-14

我通过Spring Webflux框架使用Reactor Netty,以便将数据发送到远程内容交付网络。当客户端请求完成时,默认的反应器Netty行为是保持连接活动并将其释放回底层连接池。

一些内容交付网络建议在某些类型的状态代码(例如500个内部服务器错误)上重新解析DNS。为了实现这一点,我添加了一个自定义的NettyDnsNameResolverDnsCache,但我也需要关闭连接,否则它将被释放回池中,并且不会重新解析DNS。

如何关闭错误状态代码上的连接?

到目前为止,我通过在Retor Netty的TcpClient中添加Connection观察者提出了以下解决方法:

TcpClient tcpClient = TcpClient.create()
        .observe((connection, newState) -> {
            if (newState == State.RELEASED && connection instanceof HttpClientResponse) {
                HttpResponseStatus status = ((HttpClientResponse) connection).status();
                if (status.codeClass() != HttpStatusClass.SUCCESS) {
                    connection.dispose();
                }
            }
        });

也就是说,如果连接已被释放(即放回连接池)并且释放是由带有不成功状态代码的HTTP客户端响应引起的,则关闭连接。

这种方法感觉很笨拙。如果连接在错误状态代码后被释放,并且观察者正在关闭该连接,那么新请求能否并行获取相同的连接?该框架是否在内部优雅地处理事情,或者这是使上述方法无效的竞争条件?

提前感谢您的帮助!

共有1个答案

费子濯
2023-03-14

最好使用doOnResponse或doAfterResponseSuccess,这取决于哪个用例更合适。

然而,等待释放应该不是问题

如果连接在错误状态代码之后被释放,并且观察者正在关闭该连接,那么新请求是否可以并行获取相同的连接?框架内部是否优雅地处理事情,或者这是使上述方法无效的竞争条件?

默认情况下,连接池使用FIFO租赁策略运行,因此如果池中有空闲连接,则无法获得相同的连接,如果将连接池切换为LIFO租赁策略,则情况并非如此。获取时,将检查每个连接是否处于活动状态,并且只提供一个活动连接供使用。

更新:

您还可以尝试以下方法,该方法仅使用WebClient API,而不使用Reactor Netty API:

return this.webClient
           .get()
           .uri("/500")
           .retrieve()
           .onStatus(status -> status.equals(HttpStatus.INTERNAL_SERVER_ERROR), clientResponse -> {
                clientResponse.bodyToFlux(DataBuffer.class)
                              .subscribe(new BaseSubscriber<DataBuffer>() {
                                  @Override
                                  protected void hookOnSubscribe(Subscription subscription) {
                                      subscription.cancel();
                                  }
                              });
                return Mono.error(new IllegalStateException("..."));
           })
           .bodyToMono(String.class);
 类似资料:
  • 使用Alamofire 4/Swift 3,您如何区分由于以下原因而失败的请求: 网络连接(主机关闭,无法连接到主机)vs 代码: 我们希望以不同的方式处理每个案件。在后一种情况下,我们要询问回答。(在前一种情况下,我们不知道,因为没有回应)。

  • 我坚持这个问题,如果有任何帮助是非常感谢的 请在以上问题上帮助我

  • 我使用代理集成的api网关公开了多个lambda。我时不时会收到状态代码502的奇怪错误。lambda cloud watch日志中没有任何内容。下面我发布了示例请求的api网关日志: 基本上,api网关似乎无法到达lambda,对lambda的调用正在返回: 还有其他人遇到过这些问题吗?从我的角度来看,唯一可能的修复方法是编写重试机制,但从我的角度来看,我缺少一些配置,或者是AWS故障,他们应该

  • 我使用axios与自己的API(不是用NodeJS编写的)通信。 当我发布一个非简单的请求时,axios总是直接转到控制台中显示网络错误的catch块,即使有2个成功的Http请求。 错误:网络错误堆栈跟踪:createerror@http://localhost:3000/statist/js/bundle.js:1634:15 handleerror@http://localhost:3000

  • 问题内容: 我正在使用以下代码从Go应用执行SET和EXPIRE。 但我开始出现错误: 使用封闭的网络连接 。我使用Gary Burd的Redigo软件包和RedisLabs。 我连接到Redis的代码是: 问题答案: 您可以使用来管理多个连接,检查空闲连接是否仍在运行,并自动获取新连接。您也可以在拨打新连接时自动执行AUTH步骤:

  • jd.getNetworkType(OBJECT) 获取网络类型。 OBJECT 参数说明: 参数 类型 必填 说明 success Function 是 接口调用成功的回调 fail Function 否 接口调用失败的回调函数 complete Function 否 接口调用结束的回调函数(调用成功、失败都会执行) success 回调参数说明: 参数 说明 networkType 网络类型