如何使用Netty关闭AsyncHttpClient以获取异步Http请求?

米格尔·甘博亚(Miguel Gamboa)

使用AsyncHttpClientwithNetty提供程序将防止主程序在我们执行异步请求时终止。例如,以下程序将在println之后终止,具体取决于提供者是JDKAsyncHttpProvider还是NettyAsyncHttpProvider

public class Program {
    public static CompletableFuture<Response> getDataAsync(String uri) {
        final AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
        final CompletableFuture<Response> promise = new CompletableFuture<>();
        asyncHttpClient
            .prepareGet(uri)
            .execute(new AsyncCompletionHandler<Response>(){
                @Override
                public Response onCompleted(Response resp) throws Exception {
                    promise.complete(resp);
                    asyncHttpClient.close(); // ??? Is this correct ????
                    return resp;
                }
            });
        return promise;
    }

    public static void main(String [] args) throws Exception {
        final String uri = "…";
        System.out.println(getDataAsync(uri).get());
    }
}

关于AsynHttpClient文档状态:

AHC是可以在裸露的JDK,Netty和Grizzly之上工作的抽象层。请注意,JDK的实现非常有限,您应该真正使用其他真正的提供程序。

要将AsyncHttpClient与Netty一起使用,我们只需要在java类路径中包含相应的库即可。因此,我们可以Program使用以下类路径配置之一运行前一个以使用Netty,也可以不使用:

  • -cp .;async-http-client-1.9.24.jar;netty-3.10.3.Final.jar;slf4j-api-1.7.12.jar 将使用 NettyAsyncHttpProvider
  • -cp .;async-http-client-1.9.24.jar;slf4j-api-1.7.12.jar 将使用 JDKAsyncHttpProvider

我们还应该怎么做才能正确使用Netty provider?例如,我正在关闭AsyncHttpClientAsyncCompletionHandler那是对的吗?

是否有任何配置可以更改观察到的行为?

阿尔珀·阿克特(Alper Akture)

使用netty提供程序并在调试器中逐步进行调试,我看到在回调内调用asyncHttpClient.close()会导致NioSocketChannelFactory.releaseExternalResources()在尝试执行关闭操作时失败。引发异常,这很可能导致非守护程序线程保留,并阻止虚拟机退出。引发的异常记录在WARN上,因此您可能看不到它(如果将slf4j-log4j12-1.7.7.jar添加到类路径中,则应该看到它)。因此,您不能在回调中调用close()(并且无论如何,您无需在每次请求执行后将其关闭)。

这是跟踪:

 WARN [New I/O worker #1] (NettyAsyncHttpProvider.java:79) - Unexpected error on close
java.lang.IllegalStateException: Must not be called from a I/O-Thread to prevent deadlocks!
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.shutdown(AbstractNioSelector.java:415)
at org.jboss.netty.channel.socket.nio.NioWorker.shutdown(NioWorker.java:36)
at org.jboss.netty.channel.socket.nio.AbstractNioWorkerPool.shutdown(AbstractNioWorkerPool.java:142)
at org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory.releaseExternalResources(NioClientSocketChannelFactory.java:225)
at com.ning.http.client.providers.netty.channel.ChannelManager.close(ChannelManager.java:355)
at com.ning.http.client.providers.netty.NettyAsyncHttpProvider.close(NettyAsyncHttpProvider.java:70)
at com.ning.http.client.AsyncHttpClient.close(AsyncHttpClient.java:336)
at com.cie.program.Program$1.onCompleted(Program.java:23)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章