You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot Devtools打印Starting application后延迟原因及优化方法

延迟根因

这5秒固定延迟没有任何日志输出,核心是这段逻辑执行在devtools重启流程的日志系统初始化之前,即使把根日志级别开到TRACE也无法捕获输出,常见触发原因有两个:

  • devtools默认等待旧应用线程终止的超时
    devtools触发重启时,会先中断上一次运行的应用主线程,默认调用thread.join(5000)等待旧线程完全退出,避免新旧上下文出现端口、连接池之类的资源冲突。如果旧Spring上下文里存在不响应中断的组件——比如没开优雅关闭的数据库连接池、常驻的定时任务线程、没设超时的阻塞异步任务、卡住的Bean销毁逻辑——devtools会等满5秒超时才会强制启动新应用,这段等待过程新应用的日志组件还没完成初始化,不会打任何日志。
  • 本机主机名DNS解析超时
    如果本地开发机/服务器的hosts文件没有把当前主机名映射到本地回环地址,Spring Boot在初始化日志系统、绑定端口前会调用InetAddress.getLocalHost()获取本机IP,触发DNS反向查询,默认超时刚好是5秒,这段逻辑同样早于日志系统初始化,没有输出。
可落地的优化方案
  • 先排查hosts配置问题
    执行hostname命令拿到当前机器的主机名,检查hosts文件(Linux/macOS路径是/etc/hosts,Windows路径是C:\Windows\System32\drivers\etc\hosts)里是否存在127.0.0.1 你的主机名、::1 你的主机名两行映射,缺失就补上,保存后测试重启速度,先排除DNS解析的影响。
  • 调整devtools重启相关参数
    在application.yml中添加以下配置,压缩无意义的等待时间:
    spring:
      devtools:
        restart:
          # 旧应用终止等待超时,单位毫秒,默认值5000,根据自己项目的资源释放速度调整,最低可设为500
          await-termination-timeout: 1000
          # 检测到文件变更后的静默等待期,默认400ms,用来等所有编译文件写入完成,避免重复触发重启,可降到200
          quiet-period: 200
          # 文件变更轮询间隔,默认1000ms,可降到500
          poll-interval: 500
          # 排除不需要热重载的路径,减少不必要的重启触发
          exclude: static/**,public/**,logs/**,*.log
    
  • 优化旧上下文的销毁逻辑
    如果缩短等待超时后出现端口占用、连接冲突的问题,说明旧应用的销毁逻辑存在阻塞,给核心组件配置快速释放资源的参数:
    spring:
      lifecycle:
        # 每个Bean销毁阶段的最大等待时间
        timeout-per-shutdown-phase: 2s
      datasource:
        hikari:
          connection-timeout: 1000
          validation-timeout: 1000
    
    自定义的异步线程池、定时任务线程池要在销毁逻辑里主动调用shutdownNow()响应中断,不要无限期阻塞等待存量任务执行完成。

内容的提问来源于stack exchange,提问作者mowwwalker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 06:09:26