gpt4 book ai didi

java - 如何关闭并重新配置使用 NettyAsyncHttpProvider 的 AsyncHttpClient

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:06:05 29 4
gpt4 key购买 nike

我正在构建一个 AsyncHttpClient,如下所示:

public AsyncHttpClient getAsyncHttpClient() {
AsyncHttpClientConfig config = new AsyncHttpClientConfig.Builder()
.setProxyServer(makeProxyServer())
.setRequestTimeoutInMs((int) Duration.create(ASYNC_HTTP_REQUEST_TIMEOUT_MIN, TimeUnit.MINUTES).toMillis())
.build();

return new AsyncHttpClient(new NettyAsyncHttpProvider(config), config);
}

这在启动时被调用一次,然后返回值被传递并在不同的地方使用。 makeProxyServer() 是我自己的函数,用于获取我的代理设置并返回一个 ProxyServer 对象。我需要做的是能够更改代理服务器设置,然后重新创建 AsyncHttpClient 对象。但是,我不知道如何彻底关闭它。一些搜索让我相信 close() 并不优雅。每次代理设置更改时,我都担心启动一个全新的执行程序和一组线程。这不会经常发生,但我的应用程序运行时间很长。

我知道我可以为每个请求使用 RequestBuilder.setProxyServer(),但我想将它设置在一个位置,以便我的 asyncHttpClient 的所有调用者实例遵守系统范围的代理设置,而无需每个开发人员记住这样做。

重新配置或拆卸和重建基于 NettyAsyncHttpClient 的正确方法是什么?

最佳答案

使用AsyncHttpClient.close() 的问题在于它关闭了提供者使用的线程池执行器,那么如果不重新构建它就无法重新使用客户端,因为根据 documentation ,一旦 ts 关闭,执行器实例就不能被重用。因此,如果您这样做,除了重新构建客户端外别无他法(除非您实现自己的 ExecutorService 会有另一个关闭逻辑,但这还有很长的路要走,恕我直言)。

但是,通过查看 NettyAsyncHttpProvider 的实现,我可以看到它存储了对给定 AsyncHttpClientConfig 实例的引用并调用它的 getProxyServerSelector() 为每个新的 NettyAsyncHttpProvider.execute(Request...) 调用获取代理设置(即对于 AsyncHttpClient 执行的每个请求)。

然后,如果我们可以让 getProxyServerSelector() 返回 ProxyServerSelector 的可配置实例,就可以做到这一点。

不幸的是,AsyncHttpClientConfig 被设计为只读容器,由 AsyncHttpClientConfig.Builder 实例化。为了克服这个限制,我们必须破解它,例如使用“包装/委托(delegate)”方法:

  • 创建一个派生自 AsyncHttpClientConfig 的新类。该类应包装给定的单独 AsyncHttpClientConfig 实例并实现 AsyncHttpClientConfig getter 对该实例的委托(delegate)。

  • 为了能够在任何给定时间点返回我们想要的代理选择器,我们在 this 包装器类中使此设置可变,并为其公开 setter 。

例子:

public class MyAsyncHttpClientConfig extends AsyncHttpClientConfig
{
private final AsyncHttpClientConfig config;
private ProxyServerSelector proxyServerSelector;

public MyAsyncHttpClientConfig(AsyncHttpClientConfig config)
{
this.config = config;
}

@Override
public int getMaxTotalConnections() { return config.maxTotalConnections; }

@Override
public int getMaxConnectionPerHost() { return config.maxConnectionPerHost; }

// delegate the others but getProxyServerSelector()

...

@Override
public ProxyServerSelector getProxyServerSelector()
{
return proxyServerSelector == null
? config.getProxyServerSelector()
: proxyServerSelector;
}

public void setProxyServerSelector(ProxyServerSelector proxyServerSelector)
{
this.proxyServerSelector = proxyServerSelector;
}
}
  • 现在,在您的示例中,使用我们的新包装器包装您的 AsyncHttpClient 配置实例,并使用它来配置 AsyncHttpClient:

例子:

MyAsyncHttpClientConfig myConfig = new MyAsyncHttpClientConfig(config); 
return new AsyncHttpClient(new NettyAsyncHttpProvider(myConfig), myConfig);
  • 每当您调用 myConfig.setProxyServerSelector(newSelector) 时,由客户端中的 NettyAsyncHttpProvider 实例执行的新请求将使用新的代理服务器设置。

一些提示/警告:

  • 这种方法依赖于NettyAsyncHttpProvider的内部实现;因此对可维护性、 future Netty 库版本升级策略等做出自己的判断。在升级到新版本之前,您可以随时查看 Netty 源代码。目前,我个人认为不太可能更改太多以使此实现无效。

  • 您可以使用 com.ning.http.util.ProxyUtils.createProxyServerSelector(proxyServer)ProxyServer 获取 ProxyServerSelector -这正是 AsyncHttpClientConfig.Builder 所做的。

  • 给定的示例没有用于访问proxyServerSelector 的同步逻辑;您可能希望根据应用程序逻辑需要添加一些。

  • 也许为 AsyncHttpClient 提交一个功能请求是个好主意,以便能够为 AsyncHttpProvider 设置一个“配置工厂”,所以所有这些复杂情况会消失:-)

关于java - 如何关闭并重新配置使用 NettyAsyncHttpProvider 的 AsyncHttpClient,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19965527/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com