Springboot 嵌入式 Tomcat 类装填器速度慢
我已经构建了一个使用SpringBoot v1.3.6.RELEASE Tomcat 8.0.36 Java 1.8u101的Web应用程序 CentOS 7.2
Web 应用程序也是调用另一个 Web 应用程序的 SOAP 客户端。(JAX-WS RI 2.2.9)如果应用程序保持空闲状态 15 秒,则第一个 Web 服务调用将停止近 2 秒。似乎停滞发生在o.a.c.loader.WebappClassLoaderBase中。
空闲 15 秒后
16:02:36.165: 委派给父类装入器org.springframework.boot.loader.LaunchedURLClassLoader@45283ce2
16:02:36.170 : 搜索本地存储库
16:02:36.170 : findResource(META-INF/services/javax.xml.soap.MetaFactory)
16:02:38.533 : --> 未找到资源,返回 null
16:02:38.533 : --> 未找到资源,返回 null
下一个请求无空闲时间
16:07:09.981 : 委派给父类装入器org.springframework.boot.loader.LaunchedURLClassLoader@45283ce2
16:07:09.984 : 搜索本地存储库
16:07:09.985 : findResource(META-INF/services/javax.xml.soap.MetaFactory)
16:07:09.986 : --> 未找到资源,返回 null
16:07:09.986 : --> 未找到资源,返回 null
16:07:09.988 : 查找资源(元INF/服务)
上述所有消息都由o.a.c.loader.WebappClassLoaderBase生成,它们显然是由来自JAX-WS RI的ClientSOAPHandlerTube.processRequest引起的。
您会注意到第一次调用需要 2 秒以上,但后续调用仅需几毫秒。我想知道是否有人经历过这种行为?
可能的解决方案:是否可以将tomcat在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);
}
});
}
};
}