2014-10-28 3 views
3

Я использую async-http-client, но у меня возникают проблемы с NettyAsyncHttpProvider.async-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

Это не проблема с резьбой. Здесь есть 2 вещи:

  • Вы отправляете огромную группу запросов одновременно без какого-либо противодавления, поэтому одновременно пытаетесь открыть 500 одновременных соединений. Вам лучше иметь очередь и специальный Исполнитель перед AHC, чтобы вы могли ограничить и контролировать количество одновременных полетов.
  • Вы забиваете google.com. Они не позволяют делать это, конечно, и блокировать попытки подключения.

PS: У вас был бы быстрый ответ, если бы вы попросили в группе google AHC.

Смежные вопросы