解决.net core3.1部署到Linux CentOS docker时区问题 原创
解决.net core3.1部署到Linux CentOS docker时区问题
Posted By : 蓝狐 Updated On : 2020-06-02
最近遇到一个“.net core3.1部署到Linux CentOS docker时区“问题,总是不对,始终晚8个小时,程序取到的是UTC时间而不是我想要的东8北京时间。
一、主要技术及框架
1、.Net Core3.1
2、Docker(镜像:mcr.microsoft.com/dotnet/core/aspnet:3.1-alpine)
3、Linux CentOS
4、ElasticSearch,Kibana
5、NLog
二、问题现象
看日志记录的时间戳,始终晚了8个小时,导致通过NLog根据日期没提案生成一个日志索引就有问题,比如6月1号8点之前的日志数据就会落在了5月31号的索引中。如下图:
这个问题虽然通过Kibana选择时间筛选最终可以选择到对应的日志(会自动做一个时区转换),但是始终存在一个问题(8小时的差异),有些日志要到前一天的索引中去查询。这就给我们统计查询带来了不便。
那么我们要怎么修正这个问题呢?
三、分析原因
首先先,我们来看看ES记录的原始信息:
@timestamp记录的是es的date类型,被自动转换成了带时区的字符串:2020-05-31T16:00:00.1209997+00:00
后面加就是相对UTC的时区,加00就表示是UTC时间。
最开始我通过构建docker镜像的时候使用下面命令:
docker cp /usr/share/zoneinfo/Asia/Shanghai lanhusoft-docker:/etc/localtime
其中lanhusoft-docker为容器名。
刚开始以为解决了,最后才知道是暂时解决了,把容器的时间改为了CST,通过date命令查看时间是北京时间了。
但是,过了一段时间重新使用jenkin重新构建,又发现不对了。但是在另外一个程序相同代码,相同构建时间又是正常啊的。(不知道为啥?不知道是不是.net core bug?)
进入容器使用date查看时间又是北京时间,而且宿主机器也是北京时间。奇怪的是.NET Core程序取到的当前时间却是UTC时间。
通过TimeZoneInfo.Local.DisplayName查看找到了原因,返回的是UTC时区时间,而且直接打印DateTime.Now到页面也是跟北京时间晚了8个小时。
看来通过上面的的方法不是完美和根本解决办法,因为alpine镜像先默认是UTC时间。
推荐:
需要指定北京时间,需要安装包tzdata。
四、解决方案
alpine安装包命令是apk add,如果每次构建镜像的时候现安装包tzdata,因为网络原因会很慢,导致影响Jenkin构建的速度。所以我自己写了一个镜像。
aspnet-3.1-alpine-lanhu.dockerfile:
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-alpine
MAINTAINER www.lanhusoft.com <2351310751@qq.com>
#设置alpine时区
ENV TIMEZONE Asia/Shanghai
# Install base packages
RUN apk update && apk add curl bash tree tzdata \
&& cp -r -f /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \
&& echo "${TIMEZONE}" > /etc/timezone \
&& echo -ne "Alpine Linux 3.4 image. (`uname -rsv`)\n" >> /root/.built
# Define bash as default command
CMD ["/bin/bash"]
以上脚本apk除了安装tzdata,还安装了其他基础常用的工具包,curl,bash,tree。
在docker文件aspnet-3.1-alpine-lanhu.dockerfile所在目录运行下面命令构建docker镜像:
docker build -f aspnet-3.1-alpine-lanhu.dockerfile -t aspnet-3.1-alpine-lanhu:latest .
说明:-f镜像脚本文件,-t镜像名称,冒号后面是tag。
最后,在项目的Dockerfile中引用这个新生成的镜像:
FROM aspnet-3.1-alpine-lanhu AS base
ARG app_env=development
WORKDIR /app
EXPOSE 80
COPY . ./
ENV ASPNETCORE_ENVIRONMENT $app_env
ENTRYPOINT ["dotnet", "XX.Web.dll"]
说明:aspnet-3.1-alpine-lanhu就是之前我们自定义的alpine镜像,其中XX.Web.dll是asp.net core的启动dll。
这样每次构建就会很快,基本上10多秒就搞定。
-----------------------------------
©著作权归作者所有:来自51CTO博客作者编程的世界你不懂的原创作品,请联系作者获取转载授权,否则将追究法律责任
解决.net core3.1部署到Linux CentOS docker时区问题
https://blog.51cto.com/u_11990719/4994115
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2022-03-09 [学习笔记] 哈希函数和 SHA-256
2021-03-09 Vue CLI配置原理详解