美文网首页
JVM输出日志-时区差异

JVM输出日志-时区差异

作者: 偷油考拉 | 来源:发表于2023-01-12 17:02 被阅读0次

    故障现象

    容器内时间,已经通过 ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 修正好了。

    root@094bd0f1b1b2:/usr/local/tomcat# date
    Fri Jan 13 11:09:02 AM CST 2023
    root@e41641d35798:/usr/local/tomcat# date +%Z
    CST
    root@e41641d35798:/usr/local/tomcat# date +'%:z %Z'
    +08:00 CST
    root@e41641d35798:/usr/local/tomcat# ll /etc/localtime 
    lrwxrwxrwx 1 root root 33 Jan 13 13:18 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai
    root@e41641d35798:/usr/local/tomcat# cat /etc/timezone 
    Etc/UTC
    root@e41641d35798:/usr/local/tomcat# echo $TZ
    
    
    

    但是,docker logs 显示时间仍然不正常

    2023-01-13 03:07:50.363  INFO 1 --- [nio-8080-exec-1] c.s.lis.pubfun.OptimisticLockDataCheck   : 不做校验
    2023-01-13 03:07:50.398  INFO 1 --- [nio-8080-exec-1] c.s.lis.pubfun.OptimisticLockDataCheck   : 不做校验
    2023-01-13 03:07:50.404  INFO 1 --- [nio-8080-exec-1] c.s.lis.pubfun.OptimisticLockDataCheck   : 不做校验
    

    JVM怎么获取timezone信息

    https://docs.oracle.com/en/industries/health-sciences/data-management-workbench/3.0/install-guide/verify-time-zone-setting-used-java-virtual-machine-jvm.html

    1. JVM uses the environment variable TZ if it is set.
    2. If TZ is not set, then JVM looks for the file /etc/sysconfig/clock and finds the ZONE entry.
    3. If neither TZ nor ZONE is set, JVM compares the contents of /etc/localtime to the files in /usr/share/zoneinfo looking for a match. The matching path and filename under /usr/share/zoneinfo provides the time zone.

    故障分析

    Java 在 unix 系统下如何判断 time zone ? 翻译如下

    当没有设置 TZ 环境变量的时候, POSIX specification 并没有指定如何判断 timezone 。我在 Linux Standard Base 上没有找到相关资料。 base system library (GNU libc) 使用 /etc/localtime 来判断 timezone。在非嵌入式Linux上,/etc/localtime 是存储 timezone 信息的地方,理想情况这个故事就到此结束了。

    (然而, FreeBSD 、NetBSD 、 OpenBSD 使用 /etc/localtime。 Solaris 还有一些其他系统使用 /etc/TIMEZONE。参考 Rosetta Stone for UnixDietlibc (used in some embedded Linux systems) 使用 /etc/localtime, uClibc 使用 /etc/TZ (unless patched).)

    然而,Java 不是这么做的。DebianUbuntu 有一个 /etc/timezone 文件保存 timezone 的信息。这个文件用于系统打包,这样它就可以记住像Europe/Amsterdam这样的地理名称,而不仅仅是时区的描述(比如:CET、CEST和CEDT)。这不仅对利于人类理解,而且在更新地理区域设置时更坚实。Sun (现在是 Oracle) Java 偏向使用 /etc/timezone (Red Hat发行版对应于 /etc/sysconfig/clock ) see bug #6456628 而不是 /etc/localtimeOpenJDKgcj 随之效防。

    参考:
    How do I find the current system timezone?
    Java Time Zone is messed up.

    解决方案很简单:同时更新 /etc/timezone/etc/localtime 文件。在 DebianUbuntu上, 官方推荐使用 dpkg-reconfigure tzdata。只对一个应用设置时区,设置 TZ 环境变量即可 (在所有unix平台适用)。

    解决方案

    echo "Asia/Shanghai" > /etc/timezone 
    dpkg-reconfigure -f noninteractive tzdata
    
    sudo ln -fs /usr/share/zoneinfo/Europe/Dublin /etc/localtime
    sudo dpkg-reconfigure -f noninteractive tzdata
    

    Dockerfile 范例

    FROM tomcat:9.0.69-jdk8-temurin
    VOLUME $CATALINA_HOME/logs
    ARG WAR_FILE=target/*.war
    COPY $WAR_FILE ./webapps/
    COPY ./docker-entrypoint.sh .
    RUN set -eux; \
            \
            ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && dpkg-reconfigure -f noninteractive tzdata; \
            chmod +x ./docker-entrypoint.sh
    EXPOSE 8080
    ENTRYPOINT ["./docker-entrypoint.sh"]
    CMD ["catalina.sh", "run"]
    

    相关文章

      网友评论

          本文标题:JVM输出日志-时区差异

          本文链接:https://www.haomeiwen.com/subject/qqxwcdtx.html