赞
踩
1、时间相差8小时,不是所有而是 随机的
2、其他表用户表等涉及的时间没有相差8小时的情况,只有消息消费的地方出现
3、查询接口服务器日志发现
4、消息发送时时间是正确的,部分消息消费的日志没有打印出来
遇到时间差8小时的情况,通常
第一反应是数据的时区设置有问题;
第二个是java数据库链接没有设置时区
第三个是new Date() 获取了系统的时区,系统时区设置的有问题
第四个 破案了关键使用了rabbitmq
第五个 docker容器默认的时区少8小时(****)
select now();
show variables like "%time_zone%";
> set global time_zone = '+8:00'; ##修改mysql全局时区为北京时间,即我们所在的东8区
> set time_zone = '+8:00'; ##修改当前会话时区
> flush privileges; #立即生效
xxx?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&tinyInt1isBit=false&serverTimezone=Asia/Shanghai
/** 核销时间 */ @JsonIgnore @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date recieveTime;
/**
* 获取系统当前时间
*
* @return
*/
public static Date getDateTime() throws ParseException {
Date d = new Date();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd kk:mm:ss ");
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
String format = sdf.format(d);
Date parse = sdf.parse(format);
return parse;
}
尝试以上方案。问题仍然存在
登录rabbitmq管理后台,发现了消费端多了几个
经查发现
由于采用虚拟机和 容器化两种方式部署,容器化部署使用docker
docker作为消息消费客户端,时区默认0时区
需要手动设置时区
大部分 Docker 镜像都是基于 Alpine,Ubuntu,Debian,CentOS 等基础镜像制作而成。
基本上都采用 UTC 时间,默认时区为零时区。
docker run --name test --rm -ti alpine /bin/sh / # date Fri Nov 29 08:14:49 UTC 2019
而我们主要用的是 CST 时间,北京时间,位于东八区。时区代号: Asia/Shanghai
docker run --name test --rm -ti -v /etc/timezone:/etc/timezone:ro -v /etc/localtime:/etc/localtime:ro alpine /bin/sh / # date Fri Nov 29 16:13:55 CST 201
对比一下,我们会发现,时间上相差 8 小时。
经过一系列探索实践,我们总结了一些 Docker 时区调整方案。
在 Linux 系统中,控制时区和时间的主要是两个地方:
/etc/timezone
主要代表当前时区设置,一般链接指向/usr/share/zoneinfo
目录下的具体时区。/etc/localtime
主要代表当前时区设置下的本地时间。宿主机为 Linux 系统
当宿主机为 Linux 系统时,我们可以直接将宿主机上的/etc/timezone
和/etc/localtime
挂载到容器中,这样可以保持容器和宿主机时区和时间一致。
-v /etc/timezone:/etc/timezone:ro -v /etc/localtime:/etc/localtime:ro
使用示例如下:
docker run --name test --rm -ti -v /etc/timezone:/etc/timezone:ro -v /etc/localtime:/etc/localtime:ro alpine /bin/sh / # date Fri Nov 29 16:13:55 CST 2019
对于基于 Debian 基础镜像,CentOS 基础镜像制作的 Docker 镜像,在运行 Docker 容器时,传递环境变量-e TZ=Asia/Shanghai
进去,能修改 docker 容器时区。
-e TZ=Asia/Shanghai
使用示例如下:
docker run --name test -e TZ=Asia/Shanghai --rm -ti debian /bin/bash /# date Fri Nov 29 18:46:18 CST 2019
通过编写 Dockerfile,构建自己的 Docker 镜像,可以永久解决时区问题。
根据《Setting the timezone》提示,我们可以将以下代码添加到 Dockerfile 中:
ENV TZ Asia/Shanghai RUN apk add tzdata && cp /usr/share/zoneinfo/${TZ} /etc/localtime \ && echo ${TZ} > /etc/timezone \ && apk del tzdata
Debian 基础镜像 中已经安装了 tzdata 包,我们可以将以下代码添加到 Dockerfile 中:
ENV TZ=Asia/Shanghai \ DEBIAN_FRONTEND=noninteractive RUN ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime \ && echo ${TZ} > /etc/timezone \ && dpkg-reconfigure --frontend noninteractive tzdata \ && rm -rf /var/lib/apt/lists/*
Ubuntu 基础镜像中没有安装了 tzdata 包,因此我们需要先安装 tzdata 包。
我们可以将以下代码添加到 Dockerfile 中。
ENV TZ=Asia/Shanghai \ DEBIAN_FRONTEND=noninteractive RUN apt update \ && apt install -y tzdata \ && ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime \ && echo ${TZ} > /etc/timezone \ && dpkg-reconfigure --frontend noninteractive tzdata \ && rm -rf /var/lib/apt/lists/*
CentOS 基础镜像 中已经安装了 tzdata 包,我们可以将以下代码添加到 Dockerfile 中。
ENV TZ Asia/Shanghai RUN ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime \ && echo ${TZ} > /etc/timezone
时区问题是大问题。
时间没统一好,业务乱套。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。