问题背景
在测试环境搭建完成后,在测试过程中发现sql查询时数据库时间少8小时
排查过程
第一反应是数据库时区不对,因为项目已经在其他测试环境都部署过一次,并无此问题
执行mysql查询
show variables like’%time_zone’;
时区查询后发现是cst时区
担心是CST时区默认的不是东八区(CST时区能够表示四种时区)
但是在看了项目里日志中sql查询内容的打印发现直接打印出来的结果里的时间是对的,这样基本能确定不是数据库时区问题,并且jdbc连接也是没问题的serverTimezone也指定是Asia/Shanghai
到这里的时候大概确定问题应该出现在服务器时间问题了
登录linux服务器,执行
date -R
命令,发现时间以及时区居然是对的,也是东八区的时间;
这时发现情况不太对了,数据库时区、服务器时区都是一致的,但是查询出来的sql时间就少8小时
一开始担心是不是项目里使用时间格式化时指定时区错了,但是代码在其他环境中都是正常的。
在看了下log日志打印时发现实时打印的时间也是少8小时,这就更能确定就是服务器时间的问题了;
服务器时间时区都没问题,但是jvm里时区就少了8小时,猜测应该是tomcat里是不是指定的时区不对,查了tomcat配置文件并未发现问题,将这个tomcat部署到其他测试服务器时发现都是ok的,只有这台服务器存在这种情况;
到这里就完全卡住了,能想到的情况都排查了一般,都是应该是正常的,但是项目运行过程中为什么会少8小时;通过把项目部署到其他服务器验证看下来,问题肯定是出在服务器上;
既然确定是服务器问题,那就查服务器的时区配置,先执行env命令看服务器系统环境变量,发现这台服务器设置了TZ环境变量,但是设置的时区也是上海时间,应该是正常的不应该出现问题;
在通过其他正常服务器上执行env查看后发现并未设置TZ变量,而是通过localtime指定时区;
排查对比了所有情况后发现只有这里有区别,虽然无法理解问题原因,但是还是想尝试下将TZ变量去掉换成localtime指定是否正常
执行
unset TZ
命令删除TZ环境变量
再执行
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
命令etc目录下创建名称是localtime的快捷键指定到上海时区文件上
重启项目查看log日志打印,发现时间已经正常,重新测试功能发现项目中sql查询的结果也已经正常
问题解决~~~~
遗留问题:为什么TZ环境变量无法在jvm里生效?