在docker里 ,乱码似乎是司空见惯的事情,容器封装的java应用,经常在输出日志中看到歪七扭八的"代码",即便LANG值为zh_CN.UTF-8。
而docker里的时区也是频繁,之前通过挂载系统中/etc/localtime解决容器级的时区,不过java应用也发现在日志中仍旧是UTC时间,一般容器时区准确了,也就没问题,如果还不行,尝试加上"-Duser.timezone=GMT+08"。
我说说我遇到的几种具体情况和解决方法吧。
1. tomcat
vim bin/catalina.sh
增加或修改以下内容
JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF8 -Duser.timezone=GMT+08"
2.netty
#!/bin/bash
export JAVA_HOME=/usr/java/jdk1.7.0_60
pid=/var/run/netty.pid
lib=/data/sspdsp/lib
export CLASSPATH=$CLASSPATH
conf=/data/sspdsp/conf
export LANG="en_US.UTF-8"
# Extra Java CLASSPATH elements.
for f in $lib/*.jar; do
if [ "$CLASSPATH" ]; then
export CLASSPATH=$CLASSPATH:$f
else
export CLASSPATH=$f
fi
done
$JAVA_HOME/bin/java -Xms1024m -Xmx2048m -Dfile.encoding=UTF8 -Duser.timezone=GMT+08 -cp $CLASSPATH com.emar.ssp.SspServer /data/sspdsp/conf/config.properties 200 &
echo $! > $pid
echo "ssp-creative start"
3.resin
resin 作为web服务器,根据启动方式的不同,可以修改以下某一个。
> resin.xml -Dfile.encoding=UTF-8
> resin.properties jvm_args : -Dfile.encoding=UTF-8
4.jar
非web应用,直接启动jar程序,采用supervisord守护进程的方式,配置的启动命令是:
command=java -jar -Xms2048m -Dfile.encoding=UTF-8 -Dspring.config.location=./app.properties app.jar
*********************************************************************************************************************************************************************************************************************************
解决方式
经过上述比较,在容器中运行的Java应用获取到的时区是以伦敦为标准而不是容器的时区,正巧看到桥er桑的一篇文章,写到了在docker容器中运行的java应用打出的日志时间和通过date -R方式获取的容器标准时间有八个小时时间差~用到了他提供的第二种方法,在main函数启动时候加入VM参数,运行指令如下:java -jar -Duser.timezone=GMT+08 XXX.jar
具体在k8s启动文件中体现为:
修改以后重启PODS,可以看到效果如下:
总结
- 首先[桥er桑]的第一种方法我在容器中并没有找到路径下的相关文件,在yaml文件加入环境变量配置无效
- 其次有同事之前在代码里面format设置时区,不过并没有解决这个问题,在此我也没进行过多尝试
- kubernetes不知道是否有更好的解决方案,希望得到k8s大神的指导~可以更方便的解决这个问题
- 在非Java语言应用,或者Tomcat下运行的Java应用,不知道这个问题存不存在,需要了解到底层机制才能真正的明白这个问题,希望在彻底明白以后再好好记录一番。