Несколько JVM против сервера с одним приложением

Я имею дело с системой, которая запускает приложение Java для каждого клиента в своей собственной JVM. У нас есть около полутора десятков выделенных серверов, которые теперь работают почти на 100 JVM, и наборы пользовательских сценариев для управления этими JVM. Эта настройка действительно показывает свой возраст на данный момент: управление тем, что многие JVM становятся кошмаром для мониторинга/управления, и мы постоянно занимаемся проблемами кучи. Мы хотели бы перейти к более современному подходу и просто запустить множество приложений на одном сервере приложений на физическую машину. Однако сохранение отдельных приложений имеет определенные преимущества с точки зрения изоляции (например, из-за ошибок памяти влияет только на одного клиента). Каждый стек программного обеспечения клиента имеет требования к памяти, которые сильно различаются.

Мой вопрос: есть ли способ иметь лучшее из обоих миров здесь и запускать несколько приложений на одном JVM (сервере приложений) и поддерживать некоторый уровень изоляции? Или это просто современный жизненный факт, который вам нужно для управления требованиями к памяти набора приложений в наши дни? Существуют ли другие решения помимо сервера приложений или контейнера Java EE (например, Wildfly или Spring), которые мне здесь не хватает? Кажется, что эта система - это прорыв от другой эры!

Ответ 1

Оформить заказ мульти-арендатора JVM.

IBM JRE уже имеет это: 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 в эти дни, даже несколько контейнеров (например, докер).

Ответ 2

Там есть плюсы и минусы любого подхода:

Совместное JVM

  • Нижняя служебная информация - объем памяти JVM (основные библиотеки и т.д.) нужно загружать только один раз.
  • Лучшее использование памяти. Процессы Java будут использовать память ОС для кучи, которое в настоящее время не используется.

Отдельный JVM

  • Изоляция от "жадных" или "негерметичных" приложений.
  • Улучшена защита от вредоносного кода.
  • Легче обновлять, обновлять одно приложение, не сворачивая другое.

В целом, я бы не стал устанавливать политику одеяла. Ищите небольшие/микро-сервисы или другие приложения с низким уровнем использования, которые могут быть хорошими кандидатами для совместного использования и расширения оттуда.

Ответ 3

Посмотрите Spring Загрузка или Fabric8 для современного использования Java на управляемом пути

Ответ 4

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

У нас есть машины с двумя процессорами, каждая из которых имеет 18 ядер. Это дает две группы numa, и мы не можем обеспечить 34 потоков для распространения на обоих процессорах, если используется только одна JVM. Это очевидно потому, что предполагается, что все потоки одного и того же процесса JVM должны иметь быстрый доступ к одной и той же памяти, что не так.

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

Если кто-то знает лучший способ сделать это, я был бы очень рад услышать это.