async-http-client请求使用NettyAsyncHttpProvider超时

时间:2014-10-28 20:03:51

标签: java netty threadpoolexecutor asynchttpclient

我正在使用async-http-client,但我遇到了NettyAsyncHttpProvider的问题。

它给出了这个警告:

Oct 28, 2014 12:50:16 PM org.jboss.netty.channel.socket.nio.AbstractNioWorkerPool
WARNING: Failed to get all worker threads ready within 10 second(s). Make sure to specify the executor which has more threads than the requested workerCount. If unsure, use Executors.newCachedThreadPool().

我的问题是即使我使用Executors.newCachedThreadPool(),以下问题仍会存在。

一旦线程数达到corePoolSize,请求就会被删除。 无论我尝试requestTimeoutInMs或其他选项,只有一小部分响应回来,而且池中的线程停滞不前。

ExecutorService executor = new CustomThreadPoolExecutor(2, 2, 60,
            TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new ThreadFactory() {
        @Override
        public Thread newThread(Runnable r) {
            int number = threadCreationCount.incrementAndGet();
            LOG.info("newThread - {} ", number);

            Thread th = new Thread(r);
            th.setName("AsyncHttpClient-" + number);
            LOG.info("thread ={}", th);
            return th;
        }
    });

    AsyncHttpClientConfig.Builder builder = new AsyncHttpClientConfig.Builder();
    builder.setMaximumConnectionsTotal(-1)
            .setMaximumConnectionsPerHost(-1)
            .setConnectionTimeoutInMs(1000)
            .setIdleConnectionInPoolTimeoutInMs(60000)
            .setIdleConnectionTimeoutInMs(60000)
            .setRequestTimeoutInMs(3000)
            .setFollowRedirects(true)
            .setMaximumNumberOfRedirects(5)
            .setAllowPoolingConnection(true)
            .setIOThreadMultiplier(4)
            .build();

    builder.setExecutorService(executor);

    AsyncHttpClientConfig config = builder.build();
    AsyncHttpClient client = new AsyncHttpClient(new NettyAsyncHttpProvider(config), config);

    //Spin up 500 async requests to google.com
    for (int i = 1; i <= 500; i++) {
        LOG.info("i = {}", i);
        ListenableFuture<Response> future = client.prepareGet("http://www.google.com").execute(
                new AsyncCompletionHandler<Response>() {
                    @Override public Response onCompleted(Response response) throws Exception {
                        LOG.info("Response = {}, count = {}", response.getStatusCode(),
                                responseCount.incrementAndGet());
                        return response;
                    }

                    @Override
                    public void onThrowable(Throwable t) {
                        LOG.error("on throwable ={}", t);
                    }

                });
    }

现在,如果我从NettyAsyncHttpProvider更改为ApacheAsyncHttpProvider,则会执行所有请求。

我在github上创建了一个示例项目来展示这个问题。 async-http-client-debugging

2 个答案:

答案 0 :(得分:1)

使用默认执行程序服务时遇到了同样的问题。我没有调试原因,但是使用下面的配置,我没有得到10秒的延迟和警告信息。

AsyncHttpClientConfig.Builder builder = new AsyncHttpClientConfig.Builder();
    builder.setConnectTimeout(3000)
            .setExecutorService(new ThreadPoolExecutor(0, 20,
                    60L, TimeUnit.SECONDS,
                    new SynchronousQueue<>()))
            .setRequestTimeout(3000)
            .setReadTimeout(3000)
            .build();

答案 1 :(得分:-1)

这不是一个线程问题。这里有两件事:

  • 您同时发送了大量请求,没有任何背压,因此您尝试同时打开500个并发连接。你最好在AHC前面有一个队列和一个专用的执行器,这样你就可以限制和控制并发飞行请求的数量。
  • 你正在锤击google.com。他们当然不允许你这样做,并阻止你的连接尝试。

PS:如果你想要在AHC谷歌小组上询问,你会得到更快的答案。