суббота, 14 ноября 2009 г.

Tomcat многострадальный

Когда удалось настроить Jmeter руки так и зачесались поиздеваться над томкатычем. он уменя 5.5.25. Итак, вот что получилось.
Я создал небольшое приложение на основе JPA, в котором с помощью запроса выбирал из БД MySQL 40 тыщ записей, в коде проходился по всем полученым ентити, считая среднее по одному параметру. Одинокий запрос, кинутый в томката, приходил ответом примерно через 1.4-2 секунды.

Томкат, запущенный с дефолтными параметрами виртуальной машины сдался после пары минут агонии все от 5 одновременных настойчивых потоков-клиентов. Что естественно, был выкинут эксепшын OutOfMemory. Кроме того, стоит отметить, что производительность томката (кол-во обрабатываемых запросов в секунду) падала с увеличением кол-во потоков.

Задав для томката аргумент -Xmx512m, я получил весьма устойчивого бойца. Горячая ночь с 50 одновременно ломящимися потоками не смогла его сломить. Из 65000 обработанных запросов было отвергнуто только 6. А производительность была выше, чем в случае одного потока. Позднее я попробовал в течение небольшого промежутка времени даже 100 одновременных потоков. Все прошло без проблем.

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

Достаточно интересным оказалось наблюдение за количеством занимаемой томкатом памяти. В течение теста она держалась на максимуме, что весьма ожидаемо. Однако, после окончания теста сборщик мусора даже в течение нескольких часов не удосужился освободить память, оставляя все как есть до худших времен. Вот такой вот лейзи сборщик. JDK я использовал сановскую, 1.5.0_12. Не могу конкретно оценить насколько такое поведение сборщика ухудшило бы производительность в реальных условиях, однако момент весьма неприятный.

Чтобы удостовериться в том, что сборщик действительно ленится (может он просто не видит, что есть мусор?), я написал сервлет который напоминал сборщику о его прямых обязанностях:
System.gc();
Последовательные вызовы сервлета смогли уменьшить занимаемую томкатом память в метрах 512 -> 356 -> 312 -> ... -> 110. Но неужели следует это делать вручную?
Вот здеся рассказывается о тонкостях сборщика мусора, потом следует почитать.

Комментариев нет:

Отправить комментарий