当前位置:   article > 正文

RabbitMq入门到精通-消息消费日志不打印,时间差8小时,找了一个星期 破案了_rabbitmq日志时间不对

rabbitmq日志时间不对

问题现象:

1、时间相差8小时,不是所有而是 随机的

2、其他表用户表等涉及的时间没有相差8小时的情况,只有消息消费的地方出现

3、查询接口服务器日志发现

4、消息发送时时间是正确的,部分消息消费的日志没有打印出来

 

 

问题思考:

遇到时间差8小时的情况,通常

第一反应是数据的时区设置有问题;

第二个是java数据库链接没有设置时区

第三个是new Date() 获取了系统的时区,系统时区设置的有问题

第四个 破案了关键使用了rabbitmq

第五个 docker容器默认的时区少8小时(****)

 

问题排查

1、数据库设置时区

select now();

show variables like "%time_zone%";

> set global time_zone = '+8:00'; ##修改mysql全局时区为北京时间,即我们所在的东8区

> set time_zone = '+8:00'; ##修改当前会话时区

> flush privileges; #立即生效

 

2、设置数据库链接地址

xxx?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&tinyInt1isBit=false&serverTimezone=Asia/Shanghai

3、设置java代码

 

/** 核销时间 */
@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时区设置

大部分 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 时区调整方案。

一、运行 Docker 容器时调整时区

在 Linux 系统中,控制时区和时间的主要是两个地方:

  • /etc/timezone 主要代表当前时区设置,一般链接指向/usr/share/zoneinfo目录下的具体时区。
  • /etc/localtime 主要代表当前时区设置下的本地时间。

1. 通用 docker 时区修改方案

宿主机为 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

2. 通过传递环境变量改变容器时区

  • 适用于基于 Debian 基础镜像, CentOS 基础镜像 制作的 Docker 镜像
  • 不适用于基于 Alpine 基础镜像, Ubuntu 基础镜像 制作的 Docker 镜像

对于基于 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

二、制作 Docker 镜像时调整时区

通过编写 Dockerfile,构建自己的 Docker 镜像,可以永久解决时区问题。

1. Alpine

根据《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

2. Debian

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/*

3. Ubuntu

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/*

4. CentOS

CentOS 基础镜像 中已经安装了 tzdata 包,我们可以将以下代码添加到 Dockerfile 中。

ENV TZ Asia/Shanghai

RUN ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime \
    && echo ${TZ} > /etc/timezone

总结

时区问题是大问题。

时间没统一好,业务乱套。

 

参考材料

https://cloud.tencent.com/developer/article/1626811

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/666527
推荐阅读
相关标签
  

闽ICP备14008679号