字符集问题讨论

3 天前
 OnlyJack

版本 spring boot 2.7.18 jdk version 1.8

问题:ECS 启动 打印的日志有中文 无乱码情况,到容器运行之后 竟然出现了部分中文乱码,详细把基础镜像、业务镜像都拆分了一遍 专门加上 LANG=en_US.UTF-8 ,仍然无用 包括在 k8s yaml 都增加了环境变量 依然显示 LANG=C.utf8 ,最终发现是通过阿里云控制台登录容器终端,字符集确实是有问题 通过 kubectl exec 进去之后,显示字符集是没问题的,但 java 服务启动依然会有部分中文乱码。

大佬们,请把你们的解决方案放在评论区~

1059 次点击
所在节点    Linux
18 条回复
dode
3 天前
吃瓜
OnlyJack
3 天前
@dode 好瓜
Dorathea
3 天前
不用中文日志, 不折腾...
OnlyJack
3 天前
@Dorathea 大佬说得对,但是项目运行之后 一些落库的 含有中文,也会有乱码情况
dode
3 天前
使用 debian 、ubuntu 容器镜像,安装中文语言包,部署启动应用服务
OnlyJack
3 天前
@dode 在基础镜像 尝试了,无用 仍然会乱码~
midsolo
3 天前
有排除疑难杂症的时间,不如构建一个支持中文的 ubuntu 镜像。

FROM ubuntu:20.04
RUN apt-get update && \
apt-get install -y language-pack-zh-hans locales && \
locale-gen zh_CN.UTF-8 && \
update-locale LANG=zh_CN.UTF-8
ENV LANG=zh_CN.UTF-8
ENV LC_ALL=zh_CN.UTF-8
julyclyde
3 天前
应该是你没明白环境变量的传播关系导致的
我猜你说的“专门加上”是加在 bashrc 甚至.bash_profile 里了
shuangbiaog
3 天前
有没有检查 jvm 启动参数和日志框架配置呢
runliuv
3 天前
java -Dfile.encoding=utf-8 。
要么控制台有乱码,要么 TXT 日志有乱码。反正 2 者乱一样儿。
OnlyJack
3 天前
@midsolo 是的 构建了,依然不行哦 尝试过了的
OnlyJack
3 天前
@julyclyde 对 其实和环境变量没啥太大关系
vvtf
3 天前
java 没特别设置的不会是乱码, 你可以把日志拉到本地看下是不是 utf8 格式的.
所以大概率就是终端的乱码.
需要 exec -ti 进入容器时设置一下 LANG 试试.
OnlyJack
3 天前
@shuangbiaog 加的都挺全了,依然是部分中文乱码

-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 -Dspring.http.encoding.charset=UTF-8 -Dspring.http.encoding.enabled=true -Dspring.messages.encoding=UTF-8
OnlyJack
3 天前
@vvtf exec -it 容器内是 LANG=en_US.UTF-8
OnlyJack
3 天前
感谢各位大佬~ 实际上的问题出在 java 项目上,在编译的过程中 父 pom 没有指定 utf-8 导致的,包括子 pom 和运行过程中导致的。

其实这个相当于 java 项目不规范导致的,理论上都要增加 utf-8 并且要设置为全局。

父 pom 配置
<!-- 设置项目编码为 UTF-8 ,解决编译和运行时的中文乱码问题 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>


子 pom 配置
<encoding>UTF-8</encoding>


WebApplication.java

// 设置系统默认编码为 UTF-8 ,解决容器环境中文乱码问题
// 必须在 Spring Boot 启动之前设置,确保日志输出使用正确的编码
System.setProperty("file.encoding", "UTF-8");
System.setProperty("sun.jnu.encoding", "UTF-8");
julyclyde
3 天前
@OnlyJack exec 那是 non login shell 的
和 java 进程的环境变量是两码事
OnlyJack
1 天前
@julyclyde 是的,只是这么阐述~~~

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/1172323

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX