事情的经过如下(手机发的格式略乱):
- 自己的博客之前都是本地 maven 打包后,再用 mobaxterm 远程连接阿里云服务器,执行 java -jar 命令来启动的。博客里有文件上传和读取的代码,在之前(一年多)都是正常没有任何问题的。21 号的时候用家里的新电脑更新了一些代码,把博客重新部署了一下,直接用 ssh 连接上去的。
- 前几天在公司没事的时候用公司的 windows 电脑上的 mobaxterm 连到 r 服务器上看了下最近的日志,发现出现了很多文件读取异常( No Such File Or Directory )。而且观察下来发现都是中文文件读取不到了。再看了下 nginx 日志,发现很多非正常的请求,我一开始还以为是服务器被攻击把我服务器上的文件给删了导致的。去看了下文件也全都还在,便开始找其他原因。
- 正好当时有另外一个 bug 需要修复,于是准备先把这个 bug 修复了再慢慢去看这个文件读取问题,结果,用公司电脑重新打包上传到服务器重新启动后,文件读取失败的问题消失了。
- 后来用家里新电脑打了个包上传到服务器部署,然后用 jinfo 命令查看启动信息,发现里面的 file.encoding 以及 shn.jnu.encoding 都不是 UTF-8 ,而是一个叫做 ansi_x3.4-1968 的字符集。然后用公司电脑上传部署,再用 jinfo 查看,字符集就全是 UTF-8 了。
- 于是问题也就确定了,以前上传文件的时候是 UTF-8 编码的,现在字符集变了也就导致读取文件时找不到原来的文件了。
- 经过一番搜索后,有一篇文章提到了是因为 ssh 客户端的字符集不同导致的,大概意思就是 jar 包启动的时候读取的环境变量取决于 ssh 客户端。于是我也验证了一下,把家里电脑设置了环境变量
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
然后重新 ssh 连接服务器重新启动 jar 包,文件读取失败的问题就消失了,jinfo 查看字符集也变成 UTF-8 了。
问题找到了,最好的解决办法就是启动的时候自己手动指定字符集。但是我还是没想明白,为什么启动的时候读取的是我 ssh 客户端的环境变量配置,而不是我的服务器本机配置呢?