Spring Boot的JdbcTemplate通过cron启动不工作手动启动正常是什么原因?
可能的原因及排查方案
工作目录异常导致配置加载错误
cron任务默认的工作目录为/root,若你的application.properties配置文件存放在jar包所在目录,且启动命令未显式指定配置文件路径,Spring Boot会优先加载/root目录下的配置文件(如果存在错误配置),或仅加载jar包内置的默认配置,可能出现数据源连接实例错误、自定义spring.appds数据源未正确初始化等问题,导致查询无返回。你手动进入jar包目录启动时,工作目录匹配,可正常加载同目录下的正确配置。
修复方案:修改cron启动命令,先切换到jar包所在目录再执行启动,示例:cd /opt/your-app-dir && java -jar your-app.jar也可显式指定配置文件路径:
java -jar /opt/your-app-dir/your-app.jar --spring.config.location=/opt/your-app-dir/application.propertiescron环境变量缺失导致会话参数不匹配
cron执行上下文的环境变量和你手动SSH登录EC2的环境变量完全隔离,若你的配置依赖环境变量占位符、或者Oracle连接依赖NLS_LANG、TNS_ADMIN等系统变量,cron环境中缺失对应配置会导致JDBC连接的数据库会话参数和你手动执行SQL的会话参数不一致。你调用的是Oracle表函数,若函数逻辑依赖NLS_DATE_FORMAT、时区等会话参数,参数不匹配会导致函数返回空结果。
修复方案:在cron启动命令中显式声明需要的环境变量,或先执行环境变量初始化脚本再启动应用,示例:export NLS_LANG=AMERICAN_AMERICA.AL32UTF8 && cd /opt/your-app-dir && java -jar your-app.jar连接池初始连接无效
若你配置的cron任务是EC2开机自启任务,应用启动时EC2网络尚未完全就绪、Oracle数据库监听还未连通,DBCP2初始化的10个初始连接都是僵死的无效连接。应用运行时拿到无效连接执行SQL,会出现无返回、超时等问题。你手动重启时网络已经正常,连接池新建的连接都是有效连接,查询即可恢复正常。
修复方案:新增DBCP2连接校验配置,保证每次获取连接时校验有效性:spring.datasource.dbcp2.test-on-borrow=true spring.datasource.dbcp2.validation-query=SELECT 1 FROM DUAL同时可在cron启动应用前增加网络连通性检测,确认Oracle1521端口可连通后再启动应用。
自定义数据源初始化失败
你使用的是自定义前缀spring.appds的数据源,而非Spring Boot默认的spring.datasource,如果数据源配置类的加载逻辑依赖当前工作目录的资源,cron启动时工作目录异常会导致自定义数据源未正确初始化,应用实际用到了无权限的默认数据源,无法正常访问lic.skd_es_i下的表函数,返回空结果。
内容的提问来源于stack exchange,提问作者Caffeine Coder

