`
brandNewUser
  • 浏览: 455393 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

locale错误导致Java中文乱码错误的总结

阅读更多
线上执行MapReduce任务计算时,经过排查发现了某些服务器计算的数据出现中文乱码问题,但是服务器的配置是完全一致的。由于我们使用的key可能包含中文,中文乱码问题体现在每次合并map记录的时候计算数据的随机性,每次执行的结果都不一样(由于Map任务执分配的随机性)。
(注:此文章大部分都参考了同事查找到的问题解决方法。)
 
在执行Java进程的过程中,通过命令:jinfo+Java进程号 可以查看java进程运行的一些环境信息,其中也包括-D设置的相关参数。
 
截取的所有信息中,我们比较感兴趣的是下面两行配置:
file.encoding = ANSI_X3.4-1968
sun.jnu.encoding = ANSI_X3.4-1968
 
 
而其他DataNode上MR进程的相关配置,按照常理来说,这个错误是不应该发生的。
sun.jnu.encoding = UTF-8
file.encoding = UTF-8
 
 
考虑到出问题的那台机器在某天重启过,定位在某次重启时执行的环境问题。执行
 
  • 如果将这台服务器下线,任务执行成功;
  • 如果将任务全部加上对于这里面的两个属性,就会肯定成功,因为此时已经被改变:
java -Dsun.jnu.encoding=UTF-8 -Dfile.encoding=UTF-8 ${mainClass}

 

 
参考了下面一篇文章协助解决这个问题:
 
临时的解决方案,或者将这台服务器执行下线操作,或者将整个集群的mapreduce.admin.map(reduce).child.java.opts设置上加入这两个参数,保证后续所有的MR任务都使用这两个参数。
 
那么问题始终是要找到原因的,于是马上补充一下关于locale的相关知识,下面ubuntu wiki上的内容算是说的比较全面的:
 
执行locale命令,可以得出所有的locale信息(本机的环境并没有问题,ssh到服务器上执行出来的结果也正确):
LANG="zh_CN.UTF-8"
LC_COLLATE="zh_CN.UTF-8"
LC_CTYPE="zh_CN.UTF-8"
LC_MESSAGES="zh_CN.UTF-8"
LC_MONETARY="zh_CN.UTF-8"
LC_NUMERIC="zh_CN.UTF-8"
LC_TIME="zh_CN.UTF-8"
LC_ALL=
 
 
按照wiki的说明,总共分为12个大类:
  • 语言符号及其分类(LC_CTYPE)
  • 数字(LC_NUMERIC)
  • 比较和排序习惯(LC_COLLATE)
  • 时间显示格式(LC_TIME)
  • 货币单位(LC_MONETARY)
  • 信息主要是提示信息,错误信息, 状态信息, 标题, 标签, 按钮和菜单等(LC_MESSAGES)
  • 姓名书写方式(LC_NAME)
  • 地址书写方式(LC_ADDRESS)
  • 电话号码书写方式(LC_TELEPHONE)
  • 度量衡表达方式(LC_MEASUREMENT)
  • 默认纸张尺寸大小(LC_PAPER)
  • 对locale自身包含信息的概述(LC_IDENTIFICATION)。
 
其中的设置又分为相应的优先级,LC_ALL>LC_*>LANG,LC_ALL是最上级设定或者强制设定,而LANG是默认设定值,当前集群中的所有服务器都没有进行这些参数的手动设置。
 
经过检查,发现mac的字符集确实与其他的有所不同,具体可以参考下面这篇文章:
 
其中说到了:
“Mac OSX uses a special kind of decomposed UTF-8 to store filenames. If you need to read in filenames and write them to a ‘normal’ UTF-8 file, you must normalize them. My understanding of this is that when you pass a name with an accented character like é, it will decompose this into e plus ’ before saving it to the filesystem (this behavior is defined by the Unicode standard).”
 
 
我们的远程服务器并没有显示地指定LC_*参数,那么就会出现本机登陆的相关locale信息被带到远程服务器上。由于Mac中如果没有设置默认则为:
LC_CTYPE=UTF-8
 
 
这个参数会被带到相关的服务器节点中,服务器的操作系统为CentOS,而在CentOS中并没有UTF-8这个值,可以被设置为zh_CN.UTF-8或者en_US.UTF-8这两种类型,而Mac上的UTF-8是无效的。
 
而Java虚拟机在启动的时候,会根据LC_CTYPE来决定sun.jnu.encoding和file.encoding的设置,由于Mac带过来的设置是非法的,导致这两个值被设置成:ANSI_X3.4-1968,这也是其他两个mac用户亲身实践得到的经验(Mac用户的优越感造就了一个大坑…),哈哈。
 
最后,通过手动改变服务器启动加载的配置文件/etc/profile,强制显示地设置locale参数来Fix这个问题,这也是比较推荐的方式(相对于改变java参数来说)。
export LANG=en_US.UTF-8
export LC_CTYPE=en_US.UTF-8
export LC_NUMERIC=en_US.UTF-8
export LC_TIME=en_US.UTF-8
export LC_COLLATE=en_US.UTF-8
export LC_MONETARY=en_US.UTF-8
export LC_MESSAGES=en_US.UTF-8
export LC_PAPER=en_US.UTF-8
export LC_NAME=en_US.UTF-8
export LC_ADDRESS=en_US.UTF-8
export LC_TELEPHONE=en_US.UTF-8
export LC_MEASUREMENT=en_US.UTF-8
export LC_IDENTIFICATION=en_US.UTF-8
export LC_ALL=en_US.UTF-8
 
 
 
分享到:
评论

相关推荐

    java国际化中文乱码问题解决包

    Java 国际化(i18n)是让软件能够适应不同语言和地区的过程,而中文乱码问题在处理多语言支持时经常遇到。`ResourceBundle` 是 Java 中用于管理国际化资源的关键类,它允许开发者存储特定语言环境下的文本、消息和...

    tomcat 下catalina.out 日志乱码问题处理

    此外,还需要检查Linux服务器的系统编码(如`locale`设置),确保与Java环境保持一致。 总之,解决Tomcat的`catalina.out`日志乱码问题,需要综合考虑Java环境、操作系统环境以及具体应用的配置。通过调整这些设置...

    Centos7缺少字体文件导致activiti图片汉子乱码的问题

    Dsun.awt.fontMetalLook=metal -Dapple.awt.graphics.UseQuartz=true -Dswing.aatext=true -Dawt.useSystemAAFontSettings=gasp -Djava.locale.providers=JRE,SPI -Djava.protocol.handler.pkgs=...

    oracle数据库乱码问题解决

    当客户端与服务器端使用的字符集不同时,就可能导致数据在传输过程中发生错误转换,从而出现乱码。 2. **操作系统字符集设置问题**:如果操作系统的默认字符集与数据库的字符集设置不一致,也会导致乱码的出现。 3. ...

    jsp中文乱码问题的综合说明文档

    在开发Java Web应用程序时,尤其是使用JSP技术时,经常会出现中文乱码的问题。这个问题让很多开发者感到困扰,但只要了解其原因并掌握相应的解决策略,就能顺利地处理这类问题。以下是对“jsp中文乱码问题”的综合...

    Struts2乱码终极解决办法

    这不仅影响用户体验,还可能导致数据处理错误。本文将详细介绍如何彻底解决Struts2中的乱码问题,并提供实际可行的解决方案。 #### 二、乱码产生的原因 在Struts2框架中,中文乱码主要由以下几个方面的原因造成: 1...

    乱码问题的解决

    这不仅影响用户体验,还可能导致数据丢失或错误解析。本文将深入探讨文件下载乱码问题的解决办法,并详细介绍HTTP消息头的相关属性及其作用,帮助开发者更好地理解和处理此类问题。 #### 二、HTTP消息头概述 HTTP...

    javadoc转chm.pdf

    但如果你的项目采用UTF-8编码,Javadoc生成时可能会出现警告,因为GBK无法完全映射UTF-8的所有字符,导致乱码。为了解决这个问题,你需要在生成Javadoc时通过VM options指定编码设置,如`-encoding UTF-8 -charset ...

    linux系统安装oracle数据库详解

    这个错误意味着字符集设置不正确,导致乱码。解决方法是在安装前设置正确的locale和字符集。 接下来是关于kernel参数的警告:“Checking kernel parameters Warning”。这通常是指操作系统内核参数可能不符合Oracle...

    Struts2常量的具体用法实例

    Struts2是Apache软件基金会的一个开源项目,它是一个基于MVC(Model-View-Controller)设计模式的Java Web应用框架。在Struts2中,常量配置是非常关键的一环,它们控制着框架的行为和性能,通过在struts.xml文件中...

Global site tag (gtag.js) - Google Analytics