Эффективно развертывайте несколько экземпляров одной и той же WAR (разные контексты, один и тот же контейнер)

У меня есть одна WAR (app.war) и один контейнер (Tomcat, Jetty, Glassfish, что угодно). Моя цель - развернуть по запросу сотни экземпляров этого же веб-приложения в контейнере.

http://foo/app1 --> app.war
http://foo/app2 --> app.war
http://foo/app3 --> app.war 
...
http://foo/appN --> app.war

Некоторые очевидные способы достижения этого:

  • В Tomcat создайте один файл context.xml для каждого приложения (с именем appN.xml), все указывая на ту же WAR. Другие контейнеры имеют сходные методы
    • Проблема с этим подходом: он взорвет WARN раз, заняв много места на диске.
  • Используйте символические ссылки для создания папок webapp/{app1, app2, appN}, указывающих на взорванную версию app.war. Это предотвращает взрыв дискового пространства, но JVM по-прежнему загружает много дубликатов JAR в память.
  • Используйте некоторую общую папку lib, чтобы содержать большинство банок (и комбинацию из двух предыдущих опций).

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

Любые идеи?

Ответ 1

Jetty добавила поддержку того, что вы ищете некоторое время назад, с так называемыми наложениями.

http://wiki.eclipse.org/Jetty/Tutorial/Configuring_the_Jetty_Overlay_Deployer

Копирование бит со страницы вики:

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

Ответ 2

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

Что касается многоуровневых установок, следует рассмотреть следующие соображения:

Преимущества многопользовательской работы:

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

Downsides:

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

Ответ 3

Вы можете настроить Apache на передней панели (mod_proxy/mod_proxy_ajp), чтобы указать виртуальные хосты на одну WAR, развернутую на Tomcat. Ваше приложение должно быть спроектировано/написано таким образом, чтобы обслуживать весь запрос. Конфигурация конкретного веб-сайта может быть сохранена в базе данных или в виде файла конфигурации в вашем приложении - вашему приложению просто нужно будет исследовать имя пользователя, запрашивающего доменное имя, убедитесь, что установлены правильные настройки (один раз за сеанс). В общем, вы должны решить это с помощью одного приложения. Отличные разработчики LAZY.

Ответ 4

Хорошо, если это для эксперимента, то любой из перечисленных вами методов может работать.

Если это для производства, я бы рекомендовал против этого. Хотя я не тестировал ВСЕ контейнеры, контейнеры, которые я использовал, заставляют меня полагать, что он намного более устойчив, просто предоставляя безголовые виртуальные машины с контейнерами. Linux VM могут быть очень маленькими, и с технологией VM вы можете добавлять или вычитать столько случаев, сколько необходимо.

Если вы действительно хотите иметь динамически растущее решение, вам следует попытаться устранить отдельные точки отказа, а затем попытаться объединить весь мир в один.

Если вам действительно нужно "до второго" расширения/сжатия нагрузки, вы должны посмотреть на AWS или CloundFoundry.

Ответ 5

Если вы используете Jetty, вы можете добавлять контексты программно.

WebAppContext webapp = new WebAppContext();
webapp.setBaseResource(myBaseDirectory);
webapp.setContextPath(myContextPath);

Просто сделайте это в цикле для всех ваших контекстов. Он должен иметь близкие к нулю служебные данные дискового пространства.

Вероятно, аналогичный способ сделать это в Tomcat.