登陆时间的优化
这是一个登陆的请求,在项目启动后首次调用,耗时近800ms,而第二次调用改接口时则只花费了29ms,性能有较大的提升空间。
下面针对此问题进行一系列的优化。
耗时排查
项目启动后清空日志,然后调用接口,发现会创建一个dispatcherServlet
,耗时4ms,又根据日志实际打印的时间发现,实际耗时近200ms
数据库初始化以及链接耗时近400ms,存在很大优化空间 。
业务执行第一次耗时也非常久。
优化
1、启动时自动执行Initializing
在spring boot load-on-startup默认值是-1,项目启动时,默认不会初始化DispatcherServlet,也就是不会调用Servlet接口的init()方法
在yml配置文件中进行如下配置,即可指定启动时初始化:
spring:
servlet:
load-on-startup: 1 # 启动的时候初始化DispatcherServlet
2、数据库优化
hikari:
minimum-idle: 10 # 池中维护的最小空闲连接数
connection-test-query: SELECT 1
在如上两步操作后,发现性能得到了部分优化,但还是达不到理想的效果
经过检查,在如上配置后数据库并没有初始化。
3、项目启动优化
创建类InitRunner 继承ApplicationRunner
ApplicationRunner是一个接口,常用于项目启动后,(也就是ApringApplication.run()执行结束),立马执行某些逻辑。
可用于项目的准备工作,比如加载配置文件,加载执行流,定时任务等等。
@Component
@Slf4j
public class InitRunner implements ApplicationRunner {
@Resource
private IUserService userService;
@Override
public void run(ApplicationArguments args) throws Exception {
ThreadUtil.execAsync(() -> {
try {
userService.getById(1); // 数据库探测,帮我在项目启动的时候查询一次数据库,防止数据库的懒加载
log.info("启动项目web请求查询成功"); // 发送一次异步的web请求,来初始化 tomcat连接
HttpUtil.get("http://localhost:9090/");
log.info("启动项目tomcat连接查询成功"); // 发送一次异步的web请求,来初始化 tomcat连接
} catch (Exception e) {
log.warn("启动优化失败", e);
}
});
}
}
再次测试发现,前端网络请求共耗时418ms,后端方法执行则耗费了256ms,那么 中间还有150ms发生了什么呢?将日志打印级别修改为debug
查看日志发现是tomcat占用了较多时间
于是在项目初始化的时候就调用http请求,以完成tomcat初始化
@Component
@Slf4j
public class InitRunner implements ApplicationRunner {
@Resource
private IUserService userService;
@Override
public void run(ApplicationArguments args) throws Exception {
ThreadUtil.execAsync(() -> {
try {
userService.getById(1); // 数据库探测,帮我在项目启动的时候查询一次数据库,防止数据库的懒加载
log.info("启动项目web请求查询成功"); // 发送一次异步的web请求,来初始化 tomcat连接
HttpUtil.get("http://localhost:9090/");
log.info("启动项目tomcat连接查询成功"); // 发送一次异步的web请求,来初始化 tomcat连接
} catch (Exception e) {
log.warn("启动优化失败", e);
}
});
}
}
测试后,优化完成。