操作系统:CentOS Linux release 7.9.2009 (Core)
java version “1.8.0_271”
现象:springboot环境部署中经常会发现java.util.Date, java.time.LocalDateTime获取到的系统当前时间会少八个小时。有些服务器部署正常,有些异常。
去检查这个异常服务器上java应用的jdk系统变量会发现user.timezone=GMT
jdk8检查命令:
#jinfo [pid]|grep timezone
pid在linux系统中可以通过ps进程命令或jps命令获取
但是在正常的环境中查看这个变量一般是user.timezone=Asia/Shanghai 或user.timezone = GMT+08。
Asia/Shanghai和GMT+08一样都代表东八区区时。
有了这个发现就好办了,解决java时区问题有两个思路,1手动指定jdk时区,2搞明白jdk获取时区的方法。
第一种思路是可以在服务启动时传参指定时区 java -jar -Duser.timezone=GMT+08 myApp.jar
第二种需要研究下jdk系统变量是怎么获取系统时区的,网上早有人研究过openjdk相关的源码传送门,拉到最后直接看结论
在Linux系统上,jvm获取时区系统变量大概过程:
1.先找“TZ”变量,没有,到2,
2.读/etc/timezone,没有到3,
3.比较/etc/localtime文件与"/usr/share/zoneinfo目录下所有时区文件,如果有一致的,就为该时区,如果没有,到4,
4.默认为标准GMT
知道了这个步骤,这里又找到了一篇文章
一个简单的方案是配置一个TZ系统环境变量。执行命令如下
echo "export TZ='Asia/Shanghai'" >> /etc/profile && . /etc/profile
然后重启java应用,使用JDK的 jinfo [pid] | grep timezone
命令查看时区修改是否生效