tom*_*mas 14 spring tomcat spring-mvc tomcat8 spring-boot
我的弹簧启动应用程序有一个奇怪的行为:
重新启动后端后,对控制器的第一次调用大约需要5秒,以下相同的请求只需要50ms.这在90%的情况下是可重现的,有时甚至第一次呼叫都很快.
我确定,问题是服务器上没有客户端.在浏览器上,我看到TTFB时间(到第一个字节的时间)增加到5秒.以下请求仅需要10毫秒的TTFB.
使用服务器上的监控工具(应用程序动态)我可以收集这种慢速服务器调用,在调用图上我可以看到:
org.apache.catalina.webresources.JarWarResourceSet:getArchiveEntries:117
Run Code Online (Sandbox Code Playgroud)
需要4916毫秒.我认为这是我的瓶颈.但我不知道如何解决它.
我已经尝试过的:
一切都没有影响服务器的延迟.
更新
由于战争文件被多次扫描,时间会丢失.
org.apache.catalina.webresources.CachedResource.validateResource正在检查我们是否有war文件(isPackedWarFile),并且此检查返回false.即使它是一个战争档案.对于这种行为不端,我有一个解决方法.我将tomcat.resource.cache-tt设置为较高的值.
但是现在org.apache.catalina.webresources.Cache.getResource有一个noCache方法.在此方法中,类和jar文件从缓存中排除.这就是为什么再次扫描war文件的原因.
扫描整个war文件大约需要5秒钟.而这个突破是世界休息的一站.并且这种扫描绝对是不必要的,因为war文件没有爆炸,因此其内容无法更改.
更新
如果我将war文件放入tomcat安装,一切都很快.嵌入式tomcat就是问题所在.
小智 4
我想您已经这样做了,但如果还没有,请查看https://cwiki.apache.org/confluence/display/TOMCAT/HowTo+FasterStartUp并实施那里建议的修复。
对于禁用嵌入式tomcat扫描,这里的评论中有一个建议https://github.com/spring-projects/spring-boot/issues/1610
如果上述建议都无法帮助您修复延迟,则可能的解决方法是在服务器启动时发出第一个请求(并从那里触发延迟)。
@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired
private RestTemplate template;
public static void main (String args[]){
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... strings) throws Exception {
// do an initial request from here to trigger scanning the war
template.exchange(...);
}
}
Run Code Online (Sandbox Code Playgroud)
这样,你的客户端就不会再遇到5秒的延迟了。我知道这是一种黑客行为,所以如果您找到一种更干净的方法来做到这一点,请改用它。
归档时间: |
|
查看次数: |
3841 次 |
最近记录: |