2014-10-28 3 views
3

async-http-client을 사용하고 있는데, NettyAsyncHttpProvider과 관련하여 문제가 있습니다. 나는 다음과 같은 문제가 지속됩니다 Executors.newCachedThreadPool()를 사용하는 경우에도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(). 

내 문제는 여기에 있습니다 :

그것은이 경고를 제공합니다.

스레드 수가 corePoolSize에 도달하면 요청이 삭제됩니다. requestTimeoutInMs 또는 다른 옵션을 사용해도 반응의 일부만 돌아오고 풀의 스레드가 멈 춥니 다. 내가 ApacheAsyncHttpProviderNettyAsyncHttpProvider에서 변경하는 경우

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); 
        } 

       }); 
    } 

는 이제 모든 요청이 수행됩니다.

문제를 보여주기 위해 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 앞에 대기열과 전용 Executor를 두어 동시 비행 요청 수를 제한하고 제어 할 수 있습니다.
  • 당신은 google.com을 망치고 있습니다. 그들은 물론 그렇게하지 못하게하고 연결 시도를 차단합니다.

추신 : AHC Google 그룹을 대신 물어 본 경우 빠른 답변을 얻을 수 있습니다.

관련 문제