繁体   English   中英

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

[英]How to close AsyncHttpClient with Netty for an asynchronous Http request?

使用带有Netty提供程序的AsyncHttpClient将阻止主程序在执行异步请求时终止。 例如,以下程序在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提供商? 例如,我正在关闭AsyncHttpClient中的AsyncCompletionHandler 那是对的吗?

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

使用netty提供程序并在调试器中单步调试,我看到在回调中调用asyncHttpClient.close()会导致NioSocketChannelFactory.releaseExternalResources()在尝试关闭时失败。 抛出异常,这可能导致非守护程序线程保留,并保持vm不退出。 在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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM