Как правильно закрыть Apache Pooled HttpClient? - PullRequest
0 голосов
/ 10 ноября 2019

У меня есть требование, при котором я буду направлять большое количество полезных нагрузок JSON с помощью вызовов REST PUT. Я хочу сделать несколько одновременных звонков в сервис. Моя реализация выглядит следующим образом:

class FileUploaderService{

      private PoolingHttpClientConnectionManager connManager;

      public void close(){
          connManager.close();
      }
      public FileUploaderService(){

           connManager 
                  = new PoolingHttpClientConnectionManager();
            connManager.setMaxTotal(20);
            connManager.setDefaultMaxPerRoute(20);
      }
      public void uploadFile(InputStream is){

       CloseableHttpClient client = HttpClients.custom().
       setConnectionManager(connManager).build();

       uploadFile(client,is); //Logic do to REST PUT calls
   }
}

Теперь я хочу вызвать FileUploaderService одновременно, как показано ниже

    FileUploaderService fileUploader = new FileUploaderService();
    ExecutorService executor = Executors.newFixedThreadPool(20);
    CompletionService<Boolean> completionService = new ExecutorCompletionService<>(executor);
    List<Future<Boolean>> futures = new ArrayList<>();
    for(int i=1;i<=1500;i++) {

        futures.add((Future<Boolean>) completionService.submit(()->{

            InputStream is = new FileInputStream(getFileName()));
            try {
                fileUploader.uploadFile(is); //Reusing same FileUploaderInstance
            } catch (Exception e) {

                e.printStackTrace();
                return false;
            }
            return true;
        }));
    }

    fileUploader.close();
}

Как видите, я хочу использовать пул потоков размером 20, чтобы сделать одновременнымзвонки для завершения загрузки 1500 файлов. Я использую один и тот же экземпляр FileUploaderService, передаваемый каждому потоку для выполнения работы, которая внутренне получает HttpClient от PooledHttpConnectionManager.

Мои вопросы

1) Эффективен ли этот подход? 2) Моя полезная нагрузка довольно велика, иногда до 1 миллиона записей. Там будет непрерывная передача данных в службу в течение очень долгого времени. Нужно ли устанавливать конкретное время ожидания соединения или устанавливать его как -1 (никогда не истекает) 3) Каков эффективный способ закрытия соединений после завершения всех 1500. Это число может меняться и динамично. 4) Есть ли способ закрыть соединение / выпуск обратно в пул, с помощью FileUploaderService. Я пытался вызвать close на HttpClient, но, по-видимому, он также закрывает исключения, генерирующие пул. Таким образом, должен быть способ следить за тем, чтобы никакая другая обработка не происходила, и безопасно закрывать пул соединений.

На основе чтения https://www.baeldung.com/httpclient-connection-management, представляется целесообразным использовать тот же объект HttpClientдля всех одновременных звонков. Это правда во всех случаях?

Если я использую один HttpClient, дает ли пул различные подключения к одному и тому же клиенту. Как добиться параллелизма, если для загрузки одного соединения требуется много времени.

Наконец, каков наилучший способ отслеживать количество используемых соединений и количество бесплатных для аренды.

Спасибо

...