2014-10-28 361 views
3

我使用async-http-client,但我遇到了与NettyAsyncHttpProvider的问题。异步-http客户端请求与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

回答

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前面有一个队列和一个专用的Executor,这样你就可以限制和控制并发飞行请求的数量。
  • 你在锤击google.com。他们不会让你这样做,并阻止你的连接尝试。

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