spring - 性能 - Spring Boot - 服务器响应时间

标签 spring spring-mvc spring-boot tomcat tomcat8

我的 Spring Boot 应用程序出现了一个奇怪的行为:

  • 前端/客户端 - 角度 6
  • 后端 - spring boot - spring MVC - 嵌入式 tomcat - Linux

重启后端后,对 Controller 的第一次调用大约需要 5 秒,以下相同的请求只需要 50 毫秒。这在 90% 的情况下是可重现的,有时甚至第一次调用也很快。

我确定,问题出在服务器上而不是客户端上。在浏览器上,我看到 TTFB 时间(到第一个字节的时间)增加到 5 秒。以下请求只需要 10ms 的 TTFB。

使用服务器上的监控工具(应用程序动态),我可以收集如此缓慢的服务器调用,并且在调用图上我可以看到:

org.apache.catalina.webresources.JarWarResourceSet:getArchiveEntries:117

需要 4916 毫秒。所以这是我的瓶颈,我想。但我不知道如何解决它。

我已经尝试过的:

  • 从 hikaricp 切换到 apache tomcat jdbc 连接池
  • 将 Spring Boot 从 2.0.0 升级到 2.0.5
  • 将 java 升级到 1.8.0_181
  • 属性 spring.jpa.tomcat.testOnBorrow = true
  • 属性 spring.jpa.tomcat.validationQuery = 选择 1

一切都不会影响服务器延迟。

更新

由于war文件被多次扫描而导致时间丢失。

org.apache.catalina.webresources.CachedResource.validateResource 正在检查我们是否有一个 war 文件 (isPackedWarFile),这个检查返回 false。即使它是一个 war 文件。对于这种行为不端,我有一个解决方法。我将 tomcat.resource.cache-tt 设置为高值。

但是现在 org.apache.catalina.webresources.Cache.getResource 有一个 noCache 方法。在这种方法中,classjar 文件被排除在缓存之外。这就是再次扫描war文件的原因。

扫描整个 war 文件大约需要 5 秒。而这个突破是一个停止世界的突破。而且这种扫描是完全没有必要的,因为war文件没有被炸开,所以它的内容也不能改变。

更新

如果我将 war 文件放入 tomcat 安装中,一切都会很快。嵌入式tomcat就是问题所在。

最佳答案

我想你已经这样做了,但如果你还没有,看看 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(...);
    }

}

这样,您的客户端将不再遇到 5s 延迟。我知道这是一个 hack,所以如果你找到一种更简洁的方法来代替它。

关于spring - 性能 - Spring Boot - 服务器响应时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52648831/

相关文章:

java - 将JSP页面添加到Spring服务中

java - Spring Boot Security - Postman 给出 401 Unauthorized

postgresql - 在 Spring Boot 2、Hibernate、PostgreSQL 中通过 JDBC 语句执行 DDL 时出错

java - Hibernate 上多对多关系的无限递归

java - 将 Spring 配置从 XML 转换为基于 Java : No Qualifying bean Exception

spring - 使用 Tomcat 和 Spring 配置 AspectJ LTW 时遇到问题

java - 我如何在带有 spring 的 servlet 过滤器中使用 @Transactional 和 sessionFactory bean

java - 如何使用 Jackson 反序列化 2D 数组

java - Spring MVC RequestMapping 发布方法

node.js - 与前端和后端的错误通信(Java - Angular)