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

У нас есть веб-приложение, созданное на Java, которое использует struts2, spring и JasperReport. Это приложение работает на стеклянной планете 4.0.

Библиотеки приложения находятся в папке WEB-INF/lib, а также в glassfish установлены на 4 больше, чем на те же библиотеки.

Glassfish настроен на использование 1024mb для heapspace и 512m для permgen, а большая часть потребления памяти, когда я использую библиотеки для каждого приложения, - в действиях struts и spring aop classes (с использованием профилировщика netbeans).

Проблема, с которой мы сталкиваемся, - это объем памяти, потребляемый из-за наличия библиотек в загрузчике классов для каждого приложения, потому что он является высоким и генерирует ошибки PermGen, и мы также заметили, что приложение работает медленнее с большим количеством пользователей.

из-за этого мы пытаемся использовать разделяемые библиотеки, помещаем его в папку domain1/lib и обнаруживаем, что при одном развернутом приложении время загрузки и потребление памяти значительно ниже, и приложение работает быстрее в целом. Но когда мы развертываем остальные приложения на сервере, только первое загруженное приложение работает хорошо, а остальное имеет ошибки, когда мы вызываем действия struts2. Мы считаем, что это связано с тем, что каждое приложение имеет несколько разные настройки на struts2 и log4j.

Мы также пытались помещать только определенные библиотеки на стеклянную рыбку и оставляем только struts2 в приложении, но он показывает ошибки InvocationTargetException, потому что все библиотеки зависят от lib от apache-common, и не имеет значения, если мы поместим эти библиотеки на одном или другом месте, Также, если мы поместим его в оба места, приложение не запустится.

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

Ответ 1

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

Это действительно интересные вопросы... Я не использую GlassFish, но в соответствии с документацией:

Загрузка класса приложения

[...] Вы можете указать классы библиотеки классов или приложений [...] Используйте команду asadmin deploy с опцией --libraries и укажите пути, разделенные запятыми [...]

Изоляция загрузчика класса кругооборота

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

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

  • Использование загрузчика Common Class
  • Обмен библиотеками через кластер
  • Упаковка клиентского JAR для одного приложения в другом приложении

Использование загрузчика Common Class

Чтобы использовать загрузчик Common class, скопируйте файлы JAR в каталог domain-dir/lib или as-install/lib или скопируйте файлы .class(и другие необходимые файлы, такие как файлы .properties) в каталог domain-dir/lib/classes, затем перезапустите сервер.

Использование загрузчика Common class делает приложение или модуль доступными для всех приложений или модулей, развернутых на серверах с одинаковой конфигурацией. Однако эта доступность не распространяется на клиентов приложений. Дополнительные сведения см. В разделе Использование библиотек с клиентами приложений. [...]

Тогда я бы попытался:

Решение 1

  • поместите все библиотеки, кроме банок Struts2, под domain1/lib,
  • поставьте только бабки Struts2 под domain1/lib/applibs,

затем запустите

$ asadmin deploy --libraries struts2-core-2.3.15.2.jar FooApp1.war
$ asadmin deploy --libraries struts2-core-2.3.15.2.jar FooApp2.war

Чтобы изолировать загрузку классов библиотек Struts2, оставаясь при этом под управлением Common Classloader.

Решение 2

  • поместите все библиотеки, кроме банок Struts2, под domain1/lib,
  • помещать только блоки Struts2 под domain1/lib/applibs, в разных копиях с разными именами, например, добавление _appname в именах jar

затем запустите

$ asadmin deploy --libraries struts2-core-2.3.15.2_FooApp1.jar FooApp1.war
$ asadmin deploy --libraries struts2-core-2.3.15.2_FooApp2.jar FooApp2.war

Чтобы предотвратить совместное использование библиотек путем использования (mock) разных версий этих файлов.

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

Ответ 2

Я бы поставил на то, что размещение libs под lib/или lib/ext не решит ваши проблемы с производительностью. Вы ничего не писали о приложениях или настройках сервера, таких как размер приложения, доступное пространство Heap и PermGen, но, тем не менее, я бы рекомендовал остаться с отдельными libs для каждого приложения.

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

И вы написали, что не решили ваши проблемы, но даже могут поднять новые.

Я бы рекомендовал потратить несколько часов на настройку сервера. Если он работает со значениями по умолчанию, выделите больше PermGen и HeapSpace.

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

Ответ 3

Вы можете попытаться создать так называемую тощую WAR. Упакуйте все свои WAR в EAR и переместите все обычные JAR с WEB-INF/lib в папку lib/ в EAR (не забудьте установить <library-directory> в application.xml).

Ответ 4

Я пришел сюда в поисках руководства по установке библиотек, которые совместно используются несколькими приложениями или проектами. Я глубоко разочарован тем, что принятая практика способствует установке копии каждой общей библиотеки в каждый. Итак, если у вас есть десять веб-приложений, все из которых используются, например. например, httpcomponents-client, mysql-connector-java и т.д., тогда ваша установка содержит десять копий каждого.

Такое поведение напоминает мне, мучительно, о способе мышления, который побудил меня отказаться от мэйнфрейма в пользу ПК; мышление, казалось, было "Мне все равно, сколько ресурсов потребляет мое приложение. Фактически, я бы хотел похвастаться тем, что такое ресурс". Извините, пожалуйста, пока я швырну.

  • Интерфейс, открытый библиотекой, является неизменным контрактом, который не подлежит изменению при прихоти разработчика.

  • Это понятие называется обратной совместимостью. Если вы нарушите его, вы создадите новый интерфейс.

Я знаю, по крайней мере, два типа интерфейсов, которые соответствуют букве и духу этих правил.

  • Самым старым является системные библиотеки IBM System/370. Возможно, у вас есть Foo и Foo2, где последний расширяет и/или прерывает контракт, сделанный интерфейсом Foo, в некотором роде, что сделало его несовместимым.

  • С самого начала в проекте Bell Labs Unix стандартная библиотека стандартной C придерживалась вышеуказанных правил.

  • Несмотря на то, что он намного более новый, спецификация Microsoft COM-интерфейса обеспечивает одно и то же правило.

В свою очередь, Microsoft обычно придерживается этих правил в Win32 API, хотя в этом API есть несколько исключений. В какой-то степени они пошли назад с .NET Framework, который, похоже, рабски следит за ходом Java-среды, которую он так охотно пытается заменить.

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

Если библиотеки придерживаются правила, что интерфейс является непреложным контрактом, почему они не должны жить в каталоге разделяемой библиотеки, как и системные библиотеки Unix, которые живут в его каталоге /lib, из которого все, что работает на хост разделяет одну копию стандартной библиотеки времени выполнения C, Zlib и т.д.

Цвет меня серьезно разочаровал.