Несколько JVM против одного сервера приложений
Я имею дело с системой, которая запускает Java-приложение для каждого клиента в своей собственной JVM. У нас есть около полудюжины выделенных серверов, на которых сейчас работает около 100 JVM, и набор пользовательских сценариев для управления этими JVM. Эта установка действительно показывает свой возраст на данный момент: управление таким количеством JVM становится кошмаром мониторинга / управления, и мы постоянно имеем дело с проблемами размера кучи. Мы хотели бы перейти к более современному подходу и просто запустить несколько приложений на одном сервере приложений для каждой физической машины. Однако разделение приложений имеет определенные преимущества с точки зрения изоляции (например, ошибки нехватки памяти влияют только на одного клиента). Программный стек каждого клиента предъявляет различные требования к памяти.
Мой вопрос: есть ли способ получить лучшее из обоих миров и запустить несколько приложений в одной JVM (сервер приложений) и при этом сохранить некоторую степень изоляции? Или это просто современный факт жизни, который вам необходим для управления требованиями к памяти для набора приложений в наши дни? Есть ли здесь другие решения, кроме сервера приложений или контейнера Java EE (например, Wildfly или Spring), которые мне здесь не хватает? Похоже, что эта система - воздержание от другой эры!
4 ответа
Оформить заказ на "мультитенантных" JVM.
У JRE IBM это уже есть: http://www.ibm.com/developerworks/library/j-multitenant-java/
Waratek реализовал его поверх Oracle JRE и создал ElastiCat, вилку Tomcat, которая изолирует различные приложения в одном контейнере: http://www.elasticat.com/faq/
Ходят слухи, что мультитенантность появится и в официальной JVM Oracle Java 9.
================================================== =====
Обновление: Java 9 вышла, но от Oracle нет ни слова о многопользовательском режиме. Кажется, что они предпочитают иметь несколько JVM в наши дни, даже несколько контейнеров (например, Docker).
Есть плюсы и минусы любого подхода:
Совместная JVM
- Меньшая нагрузка - объем памяти JVM (библиотеки ядра и т. Д.) Необходимо загружать только один раз.
- Лучшее использование памяти. Процессы Java будут использовать память ОС для пространства кучи, которое в данный момент может не использоваться.
Отдельная JVM
- Изоляция от "жадных" или "негерметичных" приложений.
- Лучшая защита от вредоносного кода.
- Более простые обновления, обновление одного приложения без сбивания другого.
В целом, я бы не стал устанавливать общую политику. Ищите небольшие / микро-сервисы или другие приложения с низким уровнем использования, которые могут быть хорошими кандидатами, чтобы поделиться ими и расширяться оттуда.
Взгляните на Spring Boot или Fabric8 для современного подхода к запуску Java управляемым способом
Еще одна важная причина иметь несколько JVM вместо одной - это столкновение с группами numa. Вы не можете распределять свои потоки в одной JVM, подходящей для групп numa, как вы можете с несколькими процессами jvm. По крайней мере, я так и не нашел способ сделать это.
У нас есть машины с двумя процессорами, каждый из которых имеет 18 ядер. Это дает две группы numa, и мы не можем принудительно распределить 34 потока на оба процессора, если используется только одна JVM. Это очевидно потому, что предполагается, что все потоки одного и того же процесса JVM должны иметь быстрый доступ к одной и той же памяти, что не так.
Имея 34 процесса, система предполагает, что им не нужна общая память, и таким образом распределяет их по обоим процессорам.
Если кто-то знает лучший способ сделать это, я был бы очень рад услышать это.