为什么 Spring Rest 服务在第一次请求时速度很慢?

Pan*_*ssa 10 java spring request delay postman

所以这个问题已经被问过几次了,但似乎没有人以可以帮助我的方式回答它。我目前正在为处理产品数据的简单应用程序制作后端。它甚至没有使用 JSP,只是一个普通的 Rest 后端。使用 Spring 的 RestController。

“问题”是:启动后的第一个请求比其他所有请求需要更长的时间才能从服务器获得答案。(我只是用一个简单的 JPA 用户实体来测试 Postman)

需要考虑的一些事项:

  • 它本身可能不是数据库问题,因为它显然只是在第一个传入请求时初始化某些内容,而不是在启动时初始化
  • 在日志中,当第一个实际请求传入(通过 Postman)时,它会显示“初始化 Spring DispatcherServlet 'dispatcherServlet'”。
  • 如果我从数据库中提取所有用户(目前只有一个用户),则启动后的第一个请求需要 140 毫秒(根据 Postman 的说法)。此后,相同的请求最多需要 10ms。
  • 有一个标志对类似问题提出了一些答案:spring.mvc.servlet.load-on-startup=1。尽管这仅删除了上面提到的(DispatcherServlet 的初始化)日志记录。
  • 看起来这是标准行为,与我实际编码实体和/或 RestController 的方式无关。

如何使第一个请求更快/如何强制 Spring 在第一个请求到来之前实际初始化所有内容?

无论如何,一些代码:

用户.java:

@Entity
@Table(name = "users")
@Data
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @NonNull
    private String firstName;
    @NonNull
    private String lastName;

    @NonNull
    @OneToOne(cascade = CascadeType.ALL)
    private Address billingAddress;

    //a bit more. a list and another address
}
Run Code Online (Sandbox Code Playgroud)

用户控制器.java:

@RestController
@RequestMapping("users")
public class UserController {

    private final UserRepository userRepository;

    @Autowired
    public UserController(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @GetMapping()
    public List<User> getAllUsers() {
        return (List<User>) userRepository.findAll();
    }

    //more stuff
}
Run Code Online (Sandbox Code Playgroud)

Sle*_*mer 6

你自己回答了这个问题。Spring 中的很多东西都是惰性初始化,用于性能和资源消耗优化。用户真的会注意到一个请求花费了 140 毫秒而不是 10 毫秒吗?可能不会。请注意,这不是每个用户一个请求,而是每次启动时每个初始化路径一个请求。

话虽如此......您还回答了如何“修复”它。部署后(我假设通过 CI/CD 自动进行),您提交一个或多个请求(CI/CD 的一部分),这将触发您所需的所有路径的初始化。即,如果您有 5 个数据库连接,则可能需要提交 5 个请求来初始化所有内容。

这是完全可以接受的,并且是一个称为“预热系统”的过程。

  • 嗯,好吧,我明白为什么这种延迟加载可能很好,但我仍然不明白为什么我不能只在应用程序属性中设置一个标志,这样它就不会这样做。在我看来,手动发送请求似乎是一种解决方法。但是,是的,你是对的,如果只是第一个,那就没那么重要了。 (2认同)
  • @Panossa“热身”不是解决方法。它的标准程序包括基准测试、部署、汽车发动机、烤箱/烧烤(预热)、熨斗等。可以继续下去。很少有东西能够立即发挥全部性能。 (2认同)