Ограничение количества запросов к сервлету

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

Можно ли создать собственный пул потоков и назначить его для этого сервлета для обработки этого сценария? Мы используем сервер WebLogic 9.2. Или есть другой лучший подход для этого? Цените любые мысли.


person Community    schedule 27.10.2009    source источник


Ответы (6)


Можно ли создать собственный пул потоков и назначить его для этого сервлета для обработки этого сценария? Мы используем сервер WebLogic 9.2. Или есть другой лучший подход для этого? Цените любые мысли.

Да, это возможно. Вместо использования диспетчера самонастройки по умолчанию (начиная с Weblogic 9.x очереди выполнения заменены диспетчерами работ для пулов потоков1), вы можете создать диспетчер работ с определенным ограничения, такие как max-threads-constraint и, возможно, capacity. Затем вы можете назначить сервлет конкретному менеджеру работ, используя wl-dispatch-policy файла дескриптора развертывания weblogic.xml.


1 Обратите внимание, что по-прежнему возможно включить модель пула потоков WebLogic 8.1 и использовать очереди выполнения.

person Pascal Thivent    schedule 28.10.2009

Вам нужно что-то впереди или машина, на которой размещен сервлет, потому что, когда запросы попадают в машину, уже слишком поздно: ресурсы уже используются. Вы не можете контролировать спрос: вы можете только реагировать на него и планировать его.

Вероятно, вам понадобится балансировщик нагрузки, программный или аппаратный, в зависимости от ваших целевых требований. Программный балансировщик нагрузки может быть просто «диспетчерским сервлетом» с управлением сеансом (например, 10 одновременно с сервлетом X).

Есть и другая возможность: вы «душите» запрашивающих, выдавая соответствующий HTTP-код. Конечно, это требует дополнительной логики на стороне запрашивающей стороны... и по-прежнему потребляет некоторые ресурсы на стороне сервера.

person jldupont    schedule 27.10.2009

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

person Hank Gay    schedule 27.10.2009

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

Таким образом, вы превратите свой текущий сервлет в вызов метода.

Затем сервлет шлюза получит запрос, проверит, достаточно ли низкий счетчик, а затем увеличит его. Если больше 10, то вернуть сообщение об ошибке.

Это не идеальная ситуация, но если вы поставите что-то в очередь, браузеры через некоторое время начнут отключаться, или пользователи будут терять терпение и нажимать кнопку отправки снова и снова, так как это занимает слишком много времени.

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

person James Black    schedule 27.10.2009

Без использования балансировщиков нагрузки и т. Д. Мне кажется, что вы хотите отделить запрос от обработки.

e.g.

  1. браузер отправляет запрос. Сервлет принимает его, ставит в очередь и возвращает билет.
  2. Сервлет будет работать с этим рабочим запросом, насколько позволяют ресурсы (используя отдельный пул потоков, извлекающий рабочие элементы из очереди).
  3. Браузер может обновить (повторно ПОЛУЧИТЬ), используя этот билет, и сервлет вернет соответствующий результат (например, не обрабатывается, обрабатывается, обрабатывается).

Это довольно распространенная закономерность. Обратите внимание, что браузер не блокируется, а просто отправляет запрос, а затем регулярно проверяет, завершен ли рабочий элемент. Я успешно использовал это (например) в ситуации, когда у меня были пользователи, запрашивающие диаграммы, обработка которых занимает 5 минут или более, и которые использовали собственную библиотеку, которая не была потокобезопасной. В этом сценарии мне пришлось ограничить обработку одним потоком независимо от количества одновременных запросов.

person Brian Agnew    schedule 27.10.2009
comment
Если бы он мог использовать javascript, я бы предложил что-то вроде этого, но если они продолжат нажимать «Отправить», у вас будет несколько бесполезных запросов в очереди, так как они будут нетерпеливы, и если вы не измените форму, чтобы теперь также отправить билет. - person James Black; 27.10.2009
comment
Вы должны изменить пользовательский интерфейс, чтобы предотвратить повторную отправку. Но это тривиально. Например, первая отправка отправляет обратно «ожидающую» страницу, которая обновляется с помощью мета-заголовка HTTP «обновить» и повторно отправляет заявку для выполнения. Если он неполный, вы снова получите «ожидающую» страницу. Если завершено, вы получите результаты. - person Brian Agnew; 27.10.2009

Мне нравится идея использования статического счетчика и перенаправления, чтобы показать сообщение об ошибке, когда счетчик достиг предела.

Можем ли мы настроить отдельный сервлет и настроить пул потоков так, чтобы разрешать только X одновременных запросов, все остальные запросы будут помещены в очередь для использования следующего доступного сервлета. Выдает ли этот подход ошибку тайм-аута? Не могли бы вы поделиться более подробной информацией об этом? Спасибо

http://download.oracle.com/docs/cd/E13222_01/wls/docs92/perform/appb_queues.html

person Community    schedule 27.10.2009