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

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

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

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

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

Однако коллега не согласен, основываясь на своем опыте попыток именно этого.

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

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

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

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

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

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

Ответы [ 3 ]

16 голосов
/ 23 декабря 2010

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

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

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

6 голосов
/ 22 декабря 2010

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

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

  • Библиотеки (jar) в 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 на самом деле является потоком уровня ОС, который дорог, и вам не нужно больше нескольких тысяч.

Несомненно, есть и другие.

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

2 голосов
/ 23 декабря 2010

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

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