Логика для одновременного управления в блоке / методе - PullRequest
0 голосов
/ 20 марта 2010

1) Моя среда - веб-приложение, я разрабатываю сервлет для получения запроса.

A) В некотором блоке / методе, которым я хочу управлять одновременно с , не превышающим 5
Б) если в этом блоке 5 запросов, то новый приход должен ждать до 60 секунд, а затем выдает ошибку
C) если количество запросов ожидания / ожидания превышает 30, 31-й запрос будет выдан с ошибкой

Как мне это сделать?

2) (Необязательный вопрос) сверху Я должен распределить логику управления всем кластеризованным хостам. Я планирую использовать hazelcast для совместного использования логики управления (например, счетчик тока)

Я вижу, что они предоставляют BlockingQueue & ExectorService, но я не знаю, как использовать в моем случае. Пожалуйста, порекомендуйте, если у вас есть идея.

Ответы [ 3 ]

1 голос
/ 20 марта 2010

Для А взгляните на это: http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Semaphore.html

Для B взгляните на Object.wait () и Object.notify ()

C должно быть легко, если у вас есть A и B.

1 голос
/ 20 марта 2010

В ответах @Roman и @David Soroko рассказывается, как это сделать в сервлете (как попросил ОП).

Однако этот подход имеет проблему, заключающуюся в том, что tomcat должен выделять поток для каждого запроса, чтобы они могли участвовать в логике очередей / тайм-аутов, реализованной сервлетом. Каждый из этих потоков использует память и другие ресурсы. Это плохо масштабируется. И если вы не сконфигурируете достаточное количество потоков, запросы будут либо отброшены диспетчером запросов tomcat, либо поставлены в очередь / заблокированы по другой логике.

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

РЕДАКТИРОВАТЬ - В модели сервлета каждый запрос выделяется одному потоку на весь его срок службы. Например, в типичной модели «проталкивания сервера» каждый активный клиент имеет ожидающий HTTP-запрос, запрашивающий у сервера дополнительные данные. Когда новые данные поступают на сервер, сервер отправляет ответ, и клиент немедленно отправляет новый запрос. В классической модели реализации сервлета это означает, что сервер должен иметь запрос «в процессе» ... и поток ... для каждого активного клиента, даже если большинство потоков просто ожидают поступления данных.

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

0 голосов
/ 20 марта 2010

Попробуйте семафоры :

Счетный семафор. Концептуально Семафор поддерживает набор разрешений. Каждый acqu () блокирует при необходимости пока разрешение не будет доступно, а затем берет это. Каждый релиз () добавляет разрешение, потенциально освобождая блокировка эквайера. Тем не менее, нет фактического разрешительные объекты используются; Семафор просто ведет подсчет числа доступно и действует соответственно.

...