根据错误状态代码关闭反应堆网络连接
为了将数据发送到远程内容交付网络,我通过Spring Webflow框架使用了Reator Netty。当客户端请求完成时,默认的反应程序Netty行为是保持连接活动并将其释放回基础连接池。
某些内容交付网络建议针对某些类型的状态代码(例如,500内部服务器错误)重新解析DNS。为此,我添加了一个自定义NettyDnsNameResolver
和DnsCache
,但我还需要关闭连接,否则它将被释放回池,并且不会重新解析DNS。
如何在出现错误状态代码时关闭连接?
到目前为止,我已经想出了以下解决方法,将ConnectionObserver
添加到反应器Netty的TcpClient
:
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();
}
}
});
即,如果连接已释放(即放回连接池中),并且释放是由状态代码为UNSUCCESS的HTTP客户端响应引起的,则关闭该连接。
这种方法感觉很笨拙。如果在错误状态码之后释放连接,并且观察器正在关闭该连接,则新请求是否可以并行获取相同的连接?框架是否在内部优雅地处理事情,或者这是否是使上述方法无效的争用条件?
提前感谢您的帮助!
解决方案
最好使用doOnResponse或doAfterResponseSuccess,具体取决于哪个用例更合适。
不过,等待释放应该不是问题
如果在错误状态码之后释放连接,而观察者正在关闭该连接,则新请求是否可以并行获取相同的连接?框架是否在内部优雅地处理事情,或者这是否是使上述方法无效的争用条件?
连接池默认运行FIFO租赁策略,如果池中有空闲连接,则不会获得相同的连接,如果将连接池切换为后进先出租赁策略,则不会获得相同的连接。获取时,会检查每个连接是否处于活动状态,并且只提供活动的连接供使用。
更新:
您也可以尝试下面的方法,只使用WebClient API而不使用反应器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);
相关文章