Мониторинг и уничтожение заблокированных потоков в Java - PullRequest
0 голосов
/ 16 августа 2011

В приложении на основе сервлета, которое я сейчас пишу, у нас есть отдельные классы потоков для читателей и авторов. Данные передаются от записывающего устройства нескольким читателям с использованием LinkedBlockingQueue<byte[]>, поэтому читатель надежно блокирует, если нет новых данных, которые можно получить от записывающего устройства. Проблема заключается в том, что если удаленные клиенты, обслуживаемые этими потоками считывателя, разрывают соединение, Tomcat не бросит прерванный канал, если писатель не отправит новые данные и не попытается передать этот новый блок удаленным клиентам. Другими словами, наша служба может выполнить следующую атаку:

  1. Запустите запрос потоковой записи и вообще не записывайте в него никаких данных.
  2. Продолжайте создавать и удалять соединения для чтения. Поскольку средство записи не создает никаких данных, присоединенные к нему потоки чтения остаются заблокированными и используют память и другие ресурсы.
  3. Наблюдайте, как быстро серверу не хватает оперативной памяти.

Должен ли я создать отдельный поток обслуживания, который бы отслеживал сокеты, принадлежащие заблокированным потокам считывателя, и отправлял interrupt() тем, которые, по-видимому, потеряли соединение с соответствующими клиентами? Есть ли серьезные недостатки в архитектуре, описанной выше? Спасибо.

Ответы [ 2 ]

3 голосов
/ 16 августа 2011

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

Таким образом, это простоЧтобы решить эту проблему, при необходимости можно использовать метод poll для BlockingQueue вместо take . Вызов poll позволяет указать время ожидания, после которогосчитыватель вернет null, если в очередь не было добавлено никаких данных.

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

(Конечно, это не панацея; пока тайм-аут все еще работает, читатели будут потреблять ресурсы. Но в конечном итоге сервер с ограниченными ресурсами будет иметь некоторую уязвимость для атаки DDOS -и это уменьшает его влияние на настраиваемое маленькое окно, вместо того, чтобы, по крайней мере, оставлять ваш сервер постоянно поврежденным.)

0 голосов
/ 16 августа 2011

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

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

Это оставляет вам один поток на соединение, плюс пару потоков мониторинга.

...