Предотвратить клиент от перегрузки сервера? - PullRequest
6 голосов
/ 09 февраля 2011

У меня есть сервлет Java, который перегружается запросами клиентов в часы пик.Некоторые клиенты охватывают параллельные запросы.Иногда количество запросов в секунду слишком велико.

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

Ответы [ 3 ]

1 голос
/ 09 февраля 2011

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

Однако, если вам абсолютно необходимо ограничить число клиентов, есть несколько вариантов.

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

Выясните, с какой скоростью ваша система может обрабатывать трафик.Либо в целом, либо для каждого клиента.Затем поместите счет в memcached, который представляет эту скорость.Каждый раз, когда вы получаете запрос, уменьшайте значение.Периодически увеличивайте счетчик, чтобы пропускать больше трафика.

Например, если вы можете обрабатывать 10 запросов в секунду, ставьте счетчик 50 каждые 5 секунд, максимум до 50. Таким образом, вы не 'Не пополняйте его все время, но вы также можете справиться с небольшим разрывом, ограниченным окном.Вам нужно будет поэкспериментировать, чтобы найти хорошую частоту обновления.Ключ для этого счетчика может быть либо глобальным ключом, либо основанным на идентификаторе пользователя, если вам нужно ограничить этот способ.

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

Несмотря на это, я бы сначала изучил другие варианты.Удушение ваших клиентов - это обычно хороший способ раздражать их.Скорее всего, НЕ лучшая идея.:)

1 голос
/ 11 февраля 2011

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

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

Если вы используете Tomcat, вы можете настроить максимальное количество одновременных запросов, разрешенных через maxThreads иНастройки acceptCount.Прочитайте введение в http://tomcat.apache.org/tomcat-6.0-doc/config/http.html для получения дополнительной информации об этом.

Для более сложных элементов управления (таких как ограничения для каждого пользователя), если вы используете прокси через Apache, вы можете использовать множествопомогите разобраться с ситуацией.В Google есть несколько модулей: limitipconn, mod_bw и mod_cband.Их немного сложнее настроить и понять, чем основные элементы управления, которые, вероятно, предлагает ваш сервер приложений, поэтому вы можете просто придерживаться их.

1 голос
/ 09 февраля 2011

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

Отклонять запросы легко;просто запустите фиксированное количество экземпляров.ОС может поставить или не поставить в очередь несколько запросов на подключение, но в целом пользователи просто не смогут подключиться.Более изящный способ сделать это состоит в том, чтобы служба возвращала код ошибки, указывающий, что клиент должен повторить попытку позже.

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

Оба могут общаться через один из классов в Java.util.concurrent , например LinkedBlockingQueue или ThreadPoolExecutor .Если вы хотите стать действительно модным, вы можете использовать что-то вроде PriorityBlockingQueue , чтобы обслуживать одних клиентов раньше других.

Я, я бы добавил больше оборудования, как сказал Анон;)

...