Golang生产环境中time包的zonefile.zip问题

前段时间给程序加了个功能,打印时间按照时区打印,具体看起来是这样

    loc, _ := time.LoadLocation("Asia/Chongqing")
    return time.Now().In(loc).Format("2006-01-02 15:04:05")

在本地运行没有丝毫问题,于是就想当然的推到了线上,结果线上的环境在进行到这步的时候直接panic了,嗯,看来是过于的自信导致了问题,明显loc是nil了,那么打印下错误吧,结果看到了这么一行:

open /usr/local/go/lib/time/zoneinfo.zip: no such file or directory

于是瞬间就明白了,我们线上使用的是docker镜像,复制到容器里的go程序也是编译好的二进制文件,所以容器里没有go环境,导致在本地能正常运行的程序在线上因为缺少对应文件而panic。

知道了问题,就好解决了,当然这里可以直接换加了go环境的镜像,但是明显这样违背了docker作为线上生产环境的初衷,即最小可用,加入了go环境会直接把大量的冗余数据加入到容器中,使单个容器的体积直接倍增,所以我们只需要把这个特定依赖的文件复制到容器中即可,在Dockerfile中加入这样一段:

    COPY ./zoneinfo.zip /usr/local/go/lib/time/zoneinfo.zip
    // 这里我把这个文件也在本地复制到了我的项目中,因为我们的打包上线工作由线上的CI服务来完成,如果是在本地打包,那么可以直接复制原文件
    COPY /usr/local/go/lib/time/zoneinfo.zip /usr/local/go/lib/time/zoneinfo.zip

最后说一句,下划线无视error什么的,是真不可取啊,吸取教训把上面的代码也换成了

     loc, err := time.LoadLocation("Asia/Chongqing")

	if err != nil {
		LogError("parse location err:", err)
		loc = time.Local
	}

	return time.Now().In(loc).Format("2006-01-02 15:04:05")