Контейнеры сервлетов препятствуют тому, чтобы веб-приложения вызывали друг друга, и как они это делают?
Я знаю, что контейнер сервлета, такой как 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
Я считаю, что изоляция находится в загрузчике классов. Даже если два приложения используют одно и то же имя класса и пакет, их загрузчик классов загрузит тот, который был развернут приложением.