2014-10-28 359 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的谷歌羣組上詢問,您會得到更快的答案。