vsb>По-моему это как раз гораздо сложней будет.
По твоему предположению. А по моему опыту — мы в одном проекте именно так и сделали — все легко и работает прекрасно.
vsb>Два набора логов
А разве я предложил тебе сделать оба томката активными в нормальном режиме? Тебе никто не мешает сделать один из томкатов основным, а другой "будить" только на то короткое время, когда апдейтится основной. И тогда проблема двойных логов сократится практически в ноль.
vsb>два пула соединений
Да хоть десять, в чем проблема-то?
vsb>нужен какой-то умный роутер перед этим всем, который будет правильно разруливать, на какой томкат слать запрос
Этого софта хоть ж... жуй, настраивается негроадмином за копейки, и после этого даже прекрасно работает. Именно так в моем проекте и произошло.
vsb>Если прям с нуля это всё делать, может оно и имеет смысл
Мы делали не с нуля. У нас был сначала одна машина и один "томкат". Потом появилось требование добавить вторую машину со вторым "томкатом", что и было легко и непринужденно сделано.
vsb>но на текущий момент мне кажется разумней просто завязаться на томкат, в котором этот функционал есть из коробки и который по сути не требует никакой переделки приложения (ну кроме исправления багов, мешающих нормально выгружать).
Ну то есть "оно работает, просто не работает" Ну, хозяин — барин
"Больше 100кмч можно ехать на автобане в любом ряду кроме правого крайнего" (c) pik
"В германии земля в частной собственности" (c) pik
"Закрывать школы, при нулевой смертности среди детей и подростков, это верх глупости" (c) Abalak
Здравствуйте, vsb, Вы писали:
vsb>Т.е. на что надо обращать внимание, чтобы при выгрузке приложения от него не оставалось никаких следов в JVM? Приложения используют Spring, Wicket, некоторые просто на сервлетах.
Искренне не советую бороться с этим. Засунь наоборот томкат в приложение как либу и забудь о всех этих варах как о страшном сне.
Здравствуйте, Аноним931, Вы писали:
А>Что-то сложно очень у тебя. А>Вариант просто тупо поставить два томката не устраивает?
По-моему это как раз гораздо сложней будет. Два набора логов, два пула соединений, нужен какой-то умный роутер перед этим всем, который будет правильно разруливать, на какой томкат слать запрос (или делать внешнюю реализацию сессий). Если прям с нуля это всё делать, может оно и имеет смысл, но на текущий момент мне кажется разумней просто завязаться на томкат, в котором этот функционал есть из коробки и который по сути не требует никакой переделки приложения (ну кроме исправления багов, мешающих нормально выгружать).
Здравствуйте, vsb, Вы писали:
vsb>Т.е. на что надо обращать внимание, чтобы при выгрузке приложения от него не оставалось никаких следов в JVM? Приложения используют Spring, Wicket, некоторые просто на сервлетах. vsb>Как можно это дело вообще промониторить? Ну помимо того, что сидеть и сто раз редеплоить, мониторя расход памяти. Т.е. как понять, что я выгрузил приложение и оно ушло на 100% в небытие?
Поставить перед томкатом элементарный балансировщик, типа nginx, томкатов иметь минимум 2 шт., обновлять по одному. Это намного проще и быстрее, чем "сидеть и сто раз редеплоить, мониторя расход памяти", можно сказать первый шаг к HA. А там и кубернетес с докером не за горами )
Всю жизнь использовал томкат для запуска одного приложения, причём при перезапуске просто стопал томкат и тд. При этом при локальной разработке делал re-deploy и периодически в томкате заканчивалась память, приходилось рестартовать. Проблем это не создавало.
Сейчас хочу попробовать использовать tomcat без перезапуска на боевых сервисах. Т.е. чтобы при обновлении приложения ни один запрос не терялся. В принципе в томкате такую возможность я нашёл (можно задеплоить новую версию не останавливая старую, потом остановить старую). Но проблема в том, что боюсь, что вернутся те проблемы с исчерпанием памяти и хочу понять, на что надо обращать внимание.
Т.е. на что надо обращать внимание, чтобы при выгрузке приложения от него не оставалось никаких следов в JVM? Приложения используют Spring, Wicket, некоторые просто на сервлетах.
Как можно это дело вообще промониторить? Ну помимо того, что сидеть и сто раз редеплоить, мониторя расход памяти. Т.е. как понять, что я выгрузил приложение и оно ушло на 100% в небытие?
Томкат жалуется на thread-local переменные, но вроде пишет, что потоки обновляет. Значит проблемы нет? Чистить вручную thread-local за всеми библиотеками это нереальное занятие, их все на каждый чих юзают. Да я и не понимаю, какая тут проблема и зачем вообще что-то писать, конечно при выгрузке приложения нужно обновить все потоки и все старые thread-local переменные исчезнут.
Здравствуйте, vsb, Вы писали:
vsb>Всю жизнь использовал томкат для запуска одного приложения, причём при перезапуске просто стопал томкат и тд. При этом при локальной разработке делал re-deploy и периодически в томкате заканчивалась память, приходилось рестартовать. Проблем это не создавало.
Сейчас модно пихать всё в какой-нибудь docker/k8s и выкидывать томкат, заменяя на что-нибудь легковесное.
vsb>Сейчас хочу попробовать использовать tomcat без перезапуска на боевых сервисах. Т.е. чтобы при обновлении приложения ни один запрос не терялся.
Пускать всё в одном процессе создаёт другие риски — деплоишь ты новую версию и из-за какой-нибудь ошибки у тебя всё наворачивается с OOM. Упс.
vsb>Т.е. на что надо обращать внимание, чтобы при выгрузке приложения от него не оставалось никаких следов в JVM? Приложения используют Spring, Wicket, некоторые просто на сервлетах.
Да, тут непросто. Обычно образуются циклические зависимости между какими-то глобальными штуками. Как ты уже упомянул — thread-local переменные, ещё часто проблемы вызвает какой-нибудь logger api, кастомные class loaders, runtime-кодогенерация.
vsb>Как можно это дело вообще промониторить? Ну помимо того, что сидеть и сто раз редеплоить, мониторя расход памяти. Т.е. как понять, что я выгрузил приложение и оно ушло на 100% в небытие?
Снимать дамп памяти и смотреть количество загруженных инстансов определённого класса.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Что-то сложно очень у тебя.
Вариант просто тупо поставить два томката не устраивает?
"Больше 100кмч можно ехать на автобане в любом ряду кроме правого крайнего" (c) pik
"В германии земля в частной собственности" (c) pik
"Закрывать школы, при нулевой смертности среди детей и подростков, это верх глупости" (c) Abalak
Здравствуйте, vsb, Вы писали:
vsb>Всю жизнь использовал томкат для запуска одного приложения, причём при перезапуске просто стопал томкат и тд. При этом при локальной разработке делал re-deploy и периодически в томкате заканчивалась память, приходилось рестартовать. Проблем это не создавало.
vsb>Сейчас хочу попробовать использовать tomcat без перезапуска на боевых сервисах. Т.е. чтобы при обновлении приложения ни один запрос не терялся. В принципе в томкате такую возможность я нашёл (можно задеплоить новую версию не останавливая старую, потом остановить старую). Но проблема в том, что боюсь, что вернутся те проблемы с исчерпанием памяти и хочу понять, на что надо обращать внимание.
vsb>Т.е. на что надо обращать внимание, чтобы при выгрузке приложения от него не оставалось никаких следов в JVM? Приложения используют Spring, Wicket, некоторые просто на сервлетах.
vsb>Как можно это дело вообще промониторить? Ну помимо того, что сидеть и сто раз редеплоить, мониторя расход памяти. Т.е. как понять, что я выгрузил приложение и оно ушло на 100% в небытие?
Надо, что бы приложение грузилось каждый раз новым класслоадером, тогда легко проследить. Если что-то не выгрузилось, у тебя будут каждый раз новый инстанс класслоадера. Течь должно быстро, легко увидеть с помощью jmap и похожих инструментнов или простого jvm логгера. Выгружается все пачкой, видно сразу.По идее так и должно быть, иначе у тебя класс не обновляется.
НО. Надо проследить, что и все библиоткеки так же грузятся, или что там ничего не копится. Это сложнее, если они загрузились другим класслоадером.
Если какие-то объекты копятся — ищи их gc roots. VisualVM или аналог поможет.
Логгеры, незакрытые дескрипторы, всякие евент обработчики да и просто кривые кеши могут держать все. Думаю, что в новых либах проблем еще больше.
-XX:+HeapDumpOnOutOfMemoryError & -XX:MaxMetaspaceSize тебе в помощь, когда все сломается
Ну и да, я бы на всякий случай написал стресс-тест на редеплой как настоящий параноик.
vsb>Томкат жалуется на thread-local переменные, но вроде пишет, что потоки обновляет. Значит проблемы нет? Чистить вручную thread-local за всеми библиотеками это нереальное занятие, их все на каждый чих юзают. Да я и не понимаю, какая тут проблема и зачем вообще что-то писать, конечно при выгрузке приложения нужно обновить все потоки и все старые thread-local переменные исчезнут.
Надо выгрузить, сделать forceGC (проверить что есть full GC) и посмотреть классы до загрузки.
Вообще, (как и пишут) лучше все максимально разделить. Микросервисы и fault tolerance что бы не терять пакеты. Но это уже глобальный редезайн.