摘要:Docker
问题复现分析
Python工程中使用需要打印输出时间的相关模块比如logging、datetime,在docker容器中运行后,在日志文件中和入库的MySQL中显示的时间比实际时间小8小时,很明显是时区不一致的问题,例如早上10点钟跑的程序,实际日志为早上2点钟
2021-09-27 02:11:11 [impala_utils] INFO [49] 批量查询2000条上个版本的分数
2021-09-27 02:11:12 [impala_utils] INFO [49] 批量查询2000条上个版本的分数
2021-09-27 02:11:13 [impala_utils] INFO [56] 批量查询304条上个版本的分数
2021-09-27 02:11:13 [impala_utils] INFO [72] 批量查询2000企业热度值
2021-09-27 02:11:14 [impala_utils] INFO [72] 批量查询2000企业热度值
2021-09-27 02:11:14 [impala_utils] INFO [79] 批量查询304企业热度值
问题分析
docker容器默认使用UTC 时间(世界协调时间),UTC时间是和时区无关的,Python的datetime模块和logging模块输出的时间都会调用时区信息输出当下时间,而在docker容器中默认是UTC时间因此拿不到时区信息。
UTC时间的补充知识:UTC时间是和时区无关的,统一的,时间戳是从UTC时间1970年1月1日起到现在的秒数,也是和时区无关的,无论在地球上的那个角落,同一时刻,UNIX时间戳都是一样的,计算机的本地时间就是根据Unix时间戳 + 时区差转换而来的。
用Python简单对比一下UTC时间和当下时区的时间
>>> from datetime import datetime
>>> datetime.utcnow()
datetime.datetime(2021, 9, 27, 3, 30, 53, 733771)
>>> datetime.now()
datetime.datetime(2021, 9, 27, 11, 31, 6, 437882) # 小时位差8个小时
解决方案
解决方案有两个思路:
- 保留UTC格式为统一换算标准,在应用层根据时区进行换算
- 在docker容器中修改时区
本文主要记录下在docker中修改时区的方法,很简单在docker容器的环境变量中写入TZ=Asia/Shanghai
,在启动容器的时候使用-e
参数,简单测试一下加上之后是否有效
[root@cloudera MY_PROJECT]# docker run -it --rm e0f83d1a47cd /bin/bash
root@df4cbd20ac5a:/home# python
Python 3.6.12 (default, Jan 12 2021, 18:11:03)
>>> import time
>>> time.localtime()
time.struct_time(tm_year=2021, tm_mon=9, tm_mday=27, tm_hour=3, tm_min=43, tm_sec=58, tm_wday=0, tm_yday=270, tm_isdst=0)
>>> exit()
增加时区环境变量之后,时间显示和本地时间一致
[root@cloudera MY_PROJECT]# docker run -it --rm -e TZ=Asia/Shanghai e0f83d1a47cd /bin/bash
root@5cac819d01e2:/home# python
>>> import time
>>> time.localtime()
time.struct_time(tm_year=2021, tm_mon=9, tm_mday=27, tm_hour=11, tm_min=44, tm_sec=41, tm_wday=0, tm_yday=270, tm_isdst=0)
最终修改的docker启动命令如下
docker run --rm \
-v /home/MY_PROJECT:/home/MY_PROJECT \
-e TZ=Asia/Shanghai \
e0f83d1a47cd \
python /home/MY_PROJECT/my_project/main/main.py
Python中UTC时间和当前时间的转化
这种情况就是使用UTC统一存储,在应用层进行转化,使用Python代码转化直接加8小时demo如下
import datetime
t1 = "2021-01-01 02:03:04"
t2 = (datetime.datetime.strptime(t1, "%Y-%m-%d %H:%M:%S") + datetime.timedelta(hours=8)).strftime("%Y-%m-%d %H:%M:%S") # '2021-01-01 10:03:04'
import time
iport datetime
t1 = int(time.time())
t2 = datetime.datetime.utcfromtimestamp(t1)
t3 = (t2 + datetime.timedelta(hours=8)).strftime("%Y-%m-%d %H:%M:%S") # '2021-09-27 12:25:22'
网友评论