Обрабатывать несколько запросов одновременно - PullRequest
0 голосов
/ 23 мая 2018

У меня есть класс обслуживания

    @Path("/")
     public class ABC {
      @Path(/process/{param})
      public String processRequest(@PathParam("param") String param){
        Thread t = new Thread(()->{
         // Do some processing with the param parmeter
          System.out.println("Processing started for -> "+ param);
          //Do many more things
          //DB transactions,etc.
           });
          t.start();
          return "Your request will be processed";
        }
}

Я принимаю некоторый параметр и начинаю обрабатывать его в новом потоке, и в то же время, чтобы он завершил обработку в течение 30 секунд, я разрываю соединение склиент, подтвердив ему, что его запрос будет обработан.

Он работает нормально и до сих пор без проблем. В настоящее время он может обрабатывать более 5 000 запросов.Проблема начинается, когда одновременно поступает много запросов, может быть, больше 50 тыс., Поэтому мое приложение создает новый поток для каждого нового запроса, что приводит к тому, что приложение выделяет много памяти, а также иногда приводит к исчерпанию памяти JVM.

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

Одним из способов, который я нашел, была реализация Producer-Consumer, в которой я могу принимать все запросы и одновременно отправлять их производителям, а мои потребители принимают запрос и начинают его обрабатывать. Для этой реализации мне нужно указать максимальное число запросов, которое можетбыть принятым производителем (например: 100 000) и ни одним из потребителей, которые могут обработать запрос (например: 1000), так что только 1000 потоков активны и обрабатывают один за другим, но проблема с этим подходом заключается в том, что если какой-либо извспомогательный (работающий) поток, если по какой-либо причине блокируется, а если не освобожден, то для обработки запроса остаются только оставшиеся разблокированные потоки, и входящий запрос постоянно увеличивается у производителей.Только увеличение количества потребителей создает больше рабочих потоков, но в то же время может быть много заблокированных потоков, обрабатывающих задачу.

Пожалуйста, дайте мне знать любой другой подход, с помощью которого я могу это сделать.

Примечание. Весь запрос должен быть обработан в течение 30 секунд, а если он не может выполнить, он не соответствует критериям успеха.

Ответы [ 3 ]

0 голосов
/ 23 мая 2018

Возможно, вам нужен механизм организации очередей, такой как RabbitMq.

Ваше приложение будет работать так:

request -> push to queue -> return ACK to client

queue -> worker threads.

Скорость потребителя queue определяется скоростью ваших рабочих потоков, поэтомувы никогда не исчерпаете свою систему.

Под нагрузкой большое количество сообщений будет поставлено в очередь, а это означает, что ваши сотрудники надежно отбирают сообщения из очереди и обрабатывают их.

0 голосов
/ 14 февраля 2019

Вам необходимо обслуживать большое количество (может быть одновременных) запросов, а также хотеть контролировать количество порождаемых потоков (максимальное ограничение на количество потоков).Лучше всего использовать ExecuterService, который является своего рода управляемым пулом потоков, где вы можете указать размер пула потоков и отправить для обработки несколько объектов Runnable или Callable.

ExecutorService executorService = Executors.newFixedThreadPool(10);

Здесь все очень хорошо объяснено. Параллельный поток с использованием ExecutorService в Java 8

0 голосов
/ 23 мая 2018

Вы можете использовать систему очередей для помещения запросов в очередь и подтверждения клиента об обработке, а затем вы можете обработать очередь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...