【问题标题】:async-http-client requests timing out with NettyAsyncHttpProviderasync-http-client 请求使用 NettyAsyncHttpProvider 超时
【发布时间】:2014-10-28 20:03:50
【问题描述】:

我正在使用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

【问题讨论】:

    标签: java netty threadpoolexecutor asynchttpclient


    【解决方案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();
    

    【讨论】:

      【解决方案2】:

      这不是线程问题。这里有两件事在起作用:

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

      PS:如果您改为在 AHC google 小组中提问,您会得到更快的答案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-13
        • 1970-01-01
        • 2013-08-03
        • 2020-01-23
        • 2018-04-22
        • 2011-11-05
        • 2010-12-12
        相关资源
        最近更新 更多