Контейнеры сервлетов препятствуют тому, чтобы веб-приложения вызывали друг друга, и как они это делают?

Я знаю, что контейнер сервлета, такой как Apache Tomcat, запускается в одном экземпляре JVM, что означает, что все его сервлеты будут работать в одном процессе.

Я также знаю, что архитектура контейнера сервлета означает, что каждое веб-приложение существует в своем собственном контексте, что предполагает, что он изолирован от других веб-приложений.

Как изображено здесь: alt text

Принимая, что каждое веб-приложение изолировано, я ожидал бы, что вы могли бы создать 2 копии одинакового веб-приложения, изменить имена и пути контекста каждого (а также любую другую соответствующую конфигурацию) и запустить их параллельно без один влияет на другой. Ответы на этот вопрос, похоже, поддерживают эту точку зрения.

Однако коллега не согласен с их опытом попытки именно этого.

Они взяли веб-приложение и попытались запустить 2 отдельных экземпляра (с разными именами и т.д.) в одном контейнере сервлетов и столкнулись с проблемами с конфликтующими 2 экземплярами (я не могу больше рассказать о том, что я не участвовал в этом Работа).

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

Оба представления не кажутся совместимыми, поэтому я спрашиваю вас: Контейнеры сервлетов предотвращают конфликтующие веб-приложения в одном и том же контейнере?

Если да, Как это сделать?

Если нет, Почему возникают помехи?

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

Ответ 1

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

Например, если два приложения имеют общий код, каждый из которых содержит один и тот же банку в своей войне, то каждое приложение будет загружать свой собственный экземпляр классов из jar и статической переменной (например, singleton) класса в одно приложение будет отличаться от статической переменной того же класса в другом приложении.

Теперь возьмите, например, что приложения пытаются использовать java.util.Logger (и, по-видимому, не включают свой собственный экземпляр классов Logger в свои военные файлы). Каждое приложение собственного загрузчика классов не найдет класс в военном файле, поэтому они будут относиться к своему родительскому загрузчику классов, что, вероятно, является общим, контейнерным загрузчиком классов. Родительский загрузчик классов загрузит класс Logger, и оба приложения будут совместно использовать один и тот же класс Logger.

Ответ 2

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

Некоторые общие ресурсы, с моей головы (и я не эксперт, поэтому не цитируйте это!):

  • Библиотеки (jars) в tomcat/common/lib (Tomcat 5) или tomcat/lib (Tomcat 6).
  • Настройки в глобальном server.xml, web.xml, tomcat-users.xml
  • ОС обеспечивала такие вещи, как stdin/stdout/stderr, сетевые сокеты, устройства, файлы и т.д.
  • Система регистрации.
  • Свойства системы Java (System.getProperty(), System.setProperty())
  • Я подозреваю... статические переменные? Я не уверен, что дизайн ClassLoader предотвратит это или нет.
  • Память. Это наиболее распространенная проблема: один сервлет может отрицать доступность других, потребляя всю память.
  • CPU - особенно с многопоточными приложениями. В JVM HotSpot каждый поток Java фактически является потоком уровня ОС, который дорог, и вам не нужно больше нескольких тысяч из них.

Несомненно, их больше.

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

Ответ 3

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