Я построил веб-приложение, которое использует SpringBoot v1.3.6.RELEASE Tomcat 8.0.36 Java 1.8u101 на CentOS 7.2Springboot встроенный Tomcat Загрузчик классов медленность
Веб-приложение является также SOAP-клиент, который вызывает (JAX-WS RI 2.2.9) Если приложения остаются бездействующими в течение 15 секунд, первый вызов webservice останавливается почти на 2 секунды. Похоже, что срыв происходит в o.a.c.loader.WebappClassLoaderBase.
После 15 секунд простоя
16: 02: 36,165: Делегирование к родительскому загрузчику [email protected]
16: 02: 36,170: Поиск локальных хранилищ
16: 02: 36,170: FindResource (META-INF/услуги/javax.xml.soap.MetaFactory)
16: 02: 38,533: -> Ресурс не найдено, возвращается нуль
16: 02: 38,533: -> Ресурс не найден, возвращая NULL
следующий запрос не время простоя
16: 07: 09.981: Делегирование к родительскому загрузчику org.springframework. [email protected]
16: 07: 09,984: Поиск локальных хранилищ
16: 07: 09.985: FindResource (META-INF/услуги/javax.xml.soap. MetaFactory)
16: 07: 09,986: -> Ресурс не найдено, возвращается нуль
16: 07: 09,986: -> Ресурс не найдено, возвращается нуль
16: 07: 09,988: findResources (META-INF/услуги
Все вышеуказанные сообщения, полученные oacloader.WebappClassLoaderBase, и они, по-видимому, вызвана ClientSOAPHandlerTube.processRequest, которая из JAX-WS RI.
Вы заметите, что первый вызов занимает более 2 секунд, но последующие вызовы занимают всего миллисекунды. Мне интересно, если кто-то испытал такое поведение?
Возможных решения: Можно ли изменить из загрузчиков классов, используемых котом в springboot использовать ParallelWebappClassLoader
Или, возможно, это является продуктом пополняемого флага на загрузчике классов, но я не вижу, как изменить этот флаг в springboot.
При запуске с использованием Jetty в качестве контейнера это не происходит.
Окончательное решение: (благодаря Gergely Bacso)
@Bean
public EmbeddedServletContainerCustomizer servletContainerCustomizer() {
return new EmbeddedServletContainerCustomizer() {
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
if (container instanceof TomcatEmbeddedServletContainerFactory) {
customizeTomcat((TomcatEmbeddedServletContainerFactory) container);
}
}
private void customizeTomcat(TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory) {
tomcatEmbeddedServletContainerFactory.addContextCustomizers(new TomcatContextCustomizer() {
@Override
public void customize(Context cntxt) {
cntxt.setReloadable(false);
}
});
}
};
}
Похоже, что кэш-память становится недействительной на 15 секунд бездействия, поэтому вызов 'findResource' должен снова искать весь путь к классам. Я не могу сказать, где этот кеш может быть, так как неясно, что генерирует вывод, который вы разделили выше.Полный пример, который воспроизводит проблему, поможет здесь. Я также посмотрю, что ищет ресурс 'META-INF/services/javax.xml.soap.MetaFactory'. Выполнение этого поиска для каждого запроса кажется ненужным, так как результат вряд ли изменился. –
@ AndyWilkinson да, это мои мысли точно. Я посмотрел на WebappClassLoaderBase, и я не вижу кеша. Также я согласен с вами в том, что поиск каждого запроса кажется расточительным. Может быть, я попробую CXF вместо Metro и посмотреть, произойдет ли то же самое. – cyberoblivion