使用NettyAsyncHttpProvider时,异步http客户端请求超时

3
我正在使用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个回答

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

这不是线程问题。这里有两个因素:

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

附注:如果你在AHC谷歌组上提问,你会得到更快的答案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接