Безопасно ли использовать один и тот же Classloader для общих библиотек между несколькими элементами <Host>? - PullRequest
1 голос
/ 11 апреля 2019

Вот фрагмент из моего файла server.xml в Tomcat:

<Host name="client9001.example.com" appBase="/web/my-product-code" autoDeploy="true"></Host>
<Host name="client9002.example.com" appBase="/web/my-product-code" autoDeploy="true"></Host>
<Host name="client9003.example.com" appBase="/web/my-product-code" autoDeploy="true"></Host>
...
<Host name="client9254.example.com" appBase="/web/my-product-code" autoDeploy="true"></Host>

Хорошо известно, что каждый элемент Host создает свой собственный экземпляр WebappClassloader, что делает каждый хост полностьюизолированный и безопасный.С помощью этой настройки я могу безопасно использовать один экземпляр Tomcat для обслуживания клиентов X, каждый из которых обслуживается в отдельном поддомене.Эта настройка предотвращает манипулирование объектами клиента A действиями клиента B.

Однако это создает немасштабируемую потребность в пространстве без кучи (поскольку каждый класс загружается X раз), и мне было интересно, смогу ли ясоздать загрузчик общего класса для всех хостов.Я знаю, что Tomcat поддерживает такие вещи (используя загрузчик классов "Common" в https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html#Class_Loader_Definitions), но мой вопрос заключается в том, безопасно ли это делать. Я имею в виду, я могу сделать свои собственные классы безопасными, исключив все статическиеполей, но достаточно ли этого? Я беспокоюсь о сторонних библиотеках, таких как Spring Framework, Log4J, Joda-time и некоторых других, которые поставляются с моим кодом продукта.

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

Должен ли я пойти по этому пути и пересмотреть все эти 6027 полей? Я имею в виду, является ли эта идея плохой идеей? Если да, то какой тип кода может когда-либо передаваться в загрузчике классов "Common"?

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

1 Ответ

0 голосов
/ 12 апреля 2019

Я был бы очень осторожен ... и решил, стоит ли производительность рисковать

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

Я посмотрел на Log4J, который создает регистраторы через LogManager, который расширяет java.util.logging.LogManager, который используется для поддержки набора общего состояния о регистраторах и сервисах журналов.

Представьте себе случай, когда эти клиенты private static final Logger LOGGER = LogManager.getLogger(); создают регистраторы для каждого хоста

 <Host name="client9001.example.com">  
 <Host name="client9002.example.com">
 <Host name="client9003.example.com"> 

 <Host name="BADclient.example.com"> 

Поскольку LogManager статически совместно используется всеми хостами, плохой клиент может вызвать LogManagers.getLoggerNames();, который вернет список всех зарегистрированных регистраторов этому статическому экземпляру LogManager и приведет к утечке информации о других клиентах, работающих на том же экземпляре tomcat / be смог удалить список событий для других хостов, используя тот же класс (** я не пробовал это **)

По сути, вы хотите разместить код, который будет на 100% разделен между всеми хостами (и всеми будущими хостами), работающими на JVM. Типичным примером будет инициализация соединения JDBC.

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

Возможно, этот вопрос заинтересует Загрузчик классов Tomcat нарушает политику делегирования , когда он спрашивает об опасности использования загрузчиков общих классов в Tomcat

...