У меня есть класс обслуживания
@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 секунд, я разрываю свое соединение с клиентом, подтверждая его, что его запрос будет обработан.
Он работает нормально и до сих пор без проблем. В настоящее время он может обрабатывать более 5k запросов. Проблема начинается, когда одновременно поступает много запросов, может быть, более 50 КБ, поэтому мое приложение создает новый поток для каждого нового запроса, который заставляет приложение выделять много памяти, а также иногда приводит к исчерпанию памяти JVM.
Есть ли другой способ, с помощью которого я могу немедленно начать обработку, не беспокоясь о количестве запросов, и обработать все запросы в течение 30 секунд, а также ограничить количество активных рабочих потоков.
Один из способов, который я нашел, - это реализация «производитель-потребитель», в которой я могу принимать все запросы и одновременно передавать их производителям, а мои потребители забирают запрос и начинают его обрабатывать. Для этой реализации мне нужно указать максимальное количество запросов, которое может быть принятым производителем (Пример: 100000) и ни одним из потребителей, которые могут обработать запрос (Пример: 1000), так что только 1000 потоков активны и обрабатываются один за другим, но проблема с этим подходом заключается в том, что если любой из потребителей (работающих ) thread, если блокируется по какой-то причине и если он не освобожден, то для обработки запроса остаются только оставшиеся разблокированные потоки, а количество входящих запросов в производителях постоянно увеличивается. Только увеличение количества потребителей создает больше рабочего потока, но в то же время может быть много заблокированных потоков, обрабатывающих задачу.
Пожалуйста, дайте мне знать о любом другом подходе, с помощью которого я могу это сделать.
Примечание: весь запрос должен быть обработан в течение 30 секунд, и если это невозможно, то он не соответствует критериям успеха.
Не могли бы вы дать мне ссылку, чтобы реализовать его, а также его преимущества
Что произойдет, если ваша система отключится или выйдет из строя при обработке некоторых из этих запросов? Можете ли вы позволить себе их потерять? В противном случае правильным решением, вероятно, будет очередь (например, Rabbit), а затем прослушиватель, настроенный с несколькими потребителями (или потоками), обрабатывающими запросы. По крайней мере, так вы никогда не потеряете запрос, и он переживет отключения или сбои.
Для какого-то типа запроса это нормально, он терпит неудачу, но некоторые из них имеют решающее значение, поскольку в нем задействованы деньги клиентов, и если это не удастся, потребуется ручное вмешательство, что приведет к ненужным задержкам, я думаю, я должен попробовать кролика




Вы можете использовать систему очередей, чтобы помещать запросы в очередь и подтверждать клиенту об обработке, а позже вы можете обрабатывать очередь.
Производитель-Потребитель - это похожая реализация, верно? Производитель - это очередь и потребитель, обрабатывающий запрос в очереди.
Вероятно, вам нужен механизм очередей, например RabbitMq.
Ваше приложение будет работать так:
request -> push to queue -> return ACK to client
queue -> worker threads.
Скорость потребителя queue определяется скоростью ваших рабочих потоков, поэтому вы никогда не исчерпаете свою систему.
Под нагрузкой большое количество сообщений будет помещено в очередь, а это значит, что в то время как ваши воркеры надежно берут сообщения из очереди и обрабатывают их.
Не могли бы вы предоставить какую-либо ссылку на него ?? Спасибо :)
Ссылка на какую часть? Все они базовые
Любой учебник как таковой?
Практически все, что касается производителя-потребителя, использующего, чувак, RabbitMQ.
Вот пример на официальная страница. Если вы используете фреймворк, есть вероятность, что какой-то код конфигурации / шаблонного кода уже обрабатывается в библиотеке, например, spring-rabbit
Большое спасибо
Вам нужно обслуживать большое количество (может быть одновременных) запросов, а также контролировать количество порожденных потоков (максимальное ограничение на количество потоков). Лучше всего использовать ExecuterService, который является своего рода пулом управляемых потоков, где вы можете указать размер пула потоков и отправить несколько объектов Runnable или Callable для обработки.
ExecutorService executorService = Executors.newFixedThreadPool(10);
Здесь это очень хорошо объяснено. Параллелизм потоков с использованием ExecutorService в Java 8
Попробую это
Вам нужен
ExecutorService.