Oozie中文乱码问题的解决过程

Oozie是一个Hadoop生态圈中的一个工作流管理引擎框架,当大数据任务达到一定数量的时候,必然需要一个任务调度的框架来管理这些大量的任务,当时我们选择了Oozie,除了oozie之后,还有阿里开源的ZeusZ(PS: zeus需要进行二次开发,在github上已经好久没更新了),同时oozie服务的建立在cloudera manager下又是极其简单,各个原因的驱使下,相中了oozie。
我们公司的大数据平台是通过cloudera manager管理起来的,对oozie的使用也是通过Hue组件,使用该组件编写oozie工作流的过程变得相当轻松,只要几个各个action的拖拉拽即可创建一个workflow工作流。刚开始玩的还是不亦乐乎的,后面还是遇到了不少问题的,这里主要是分享下我在工作中遇到oozie的一些中文乱码问题。
//这里附上Hue中操作oozie的一个截图

《Oozie中文乱码问题的解决过程》

我遇到的中文乱码问题主要体现在以下两种情况:
1、Email Acttion发送中文邮件的时候,收到的邮件含有中文就会乱码 //包括subject、body、附件的文件名,只要是中文就显示???
2、SSH Action执行无法引用到远程服务器的编码环境变量,导致ssh到某服务器执行一个hive sql语句中含有中文的shell脚本,sql语句中的中文显示是乱码
解决上面两个问题,第一个问题是解决比较久的时间的。

1. Email Action发送中文邮件乱码的解决

针对这个问题,我的解决方式是这样的:
在展现层,我们最直观看到的是发的邮件乱码了,就会思考到底是哪一环节导致它乱的?
我在使用过程中用到了Hue、oozie、hadoop三个组件 //我是使用Hue创建的oozie的workflow
首先第一个就排除了Hue的原因,原因是:虽然我是使用Hue创建的工作流,但是在hdfs中查看创建的工作流的workflow.xml中关于email action的配置并没有乱码,所以排出了Hue的问题。然后将问题聚焦在oozie上面。
要找出oozie的问题所在,先下了一份oozie 4.2.0的源代码到本地 用ide导入项目,把源代码细细看来
//这里附上oozie core部分代码结构图

《Oozie中文乱码问题的解决过程》 oozie-core

关于的oozie的核心代码以及各个action的代码实现都在oozie-core下,找到EmailActionExecutor类,该类继承ActionExecutor,实现了发送邮件的功能。在validateAndEmail方法里有subject、body、attachment的获取来源,获取到这些来源之后,执行了该类中的email方法

public voide mail(String[] to,String[] cc,String subject,String body,String[] attachments,String contentType,String user) throws ActionExecutorException {
...   //省略代码
}

mail方法中的代码跟普通的JavaMail类似,实现的是发送邮件的功能。
其他关于源码结构、功能的东西也不多说了吧,切入重点,我从展现层面的乱码–> EmailActionExecutor
先锁定了是否是EmailActionExecutor类导致的,在validateAndMail(Context context, Element element)方法中获取subject的代码中打印了一行log输出,同时添加了一个判断编码的方法getEncoding,看subject中的中文是否乱码
//getEncoding的代码截了一小部分,全截有点长 第一次用简书写东西,代码显示的格式好像不是很好,所以用截图了~~

《Oozie中文乱码问题的解决过程》 getEncoding部分代码

打印subject的内容及编码:

// <subject> - One ought to exist.
subject = element.getChildTextTrim(SUB, ns);
String word=getEncoding(subject);
LOG.info("======subject的输出是"+subject+"===="+"subject编码格式:"+word);

查看日志文件发现输入的subject是乱码,编码格式是utf-8
//日志文件一般在你设置的日志目录下的oozie-cmf-oozie-OOZIE_SERVER-see-data-master-001.log.out文件中

得出的结论就是在EmailActionExecutor的validateAndMail(Context context, Element element)执行之前就乱了
//在得出这个结论之前也走了很多弯路,一直以为是发送邮件的email方法中没有进行编码的设置,尝试了很久发现不行。

validateAndMail方法是在EmailActionExecutor的start方法被调用的

《Oozie中文乱码问题的解决过程》

Element对象通过
XmlUtils.parseXml()获取到,subject从Element获取到时就乱了,追溯了下action.getConf() 发现打印的是workflow.xml的内容,关于subject、body、attachment的内容是乱码 说明在执行
EmailActionExecutor之前就乱码了

之后就会反思,email action在执行EmailActionExecutor就发生乱码,会不会是在读取workflow.xml配置文件的时候出现的呢,于是乎找到了WorkflowAppService这个类的readDefinition方法

《Oozie中文乱码问题的解决过程》 WorkflowAppService的readDefinition()方法

看上述截图,只是在Reader reader = new InputStreamReader(fs.open(path),"utf-8");加了utf-8的字符编码之后,打印的write.toString()显示的中文就正常显示了

再回到EmailActionExecutor的validateAndEmail,看打印的subject的log日志,发现中文能正常显示了。
再跑一次这个发邮件的工作流,收到的邮件还是乱码,这个时候又着急了,不是能正常显示了吗?为什么还乱码,静静想一下可以肯定的是乱码是在EmailActionExecutor的email()方法执行的时候出现了的
于是只要把email方法中关于subject、body、attachment的内容进行编码转换就ok了,转换如下:

  • subject的转换
message.setSubject(MimeUtility.encodeText(subject,MimeUtility.mimeCharset("UTF-8"), "B"));
  • body的转换有两个地方,一个是发附件的情况
//bodyTextPart.setText(body);
bodyTextPart.setContent(body, "text/html;charset=UTF-8");

bodyTextPart.setText(body);注释掉,换成bodyTextPart.setContent(body, "text/html;charset=UTF-8");
另一种是没有附件时

message.setContent(body, contentType+";charset=utf-8");
  • attachment文件名的转换
messageBodyPart.setFileName(MimeUtility.encodeText(new File(attachment).getName(),"UTF-8","B"));

完成上面的修改之后,Oozie的Email Action发送邮件就不会乱码了

** 总结下,关于Email Action的乱码问题,主要出现在两个方面,一是读取hdfs中工作流的workflow.xml时,需要在WorkflowAppService的readDefinition方法的Reader reader = new InputStreamReader(fs.open(path),"utf-8");加上utf-8的编码读取;二是在EmailActionExecutor的email()方法中需要对subject、body、attachment加上编码设置**

2. ssh Actin在某台服务器上执行hive sql语句乱码的问题解决

问题描述:在某台服务器上存在一个shell脚本,该脚本里头是对hive的操作,sql语句中含有中文条件,每次ssh 到这台机器,里面的sql语句执行的结果都为空,后来打印了执行的sql语句到日志,发现中文不能正常显示
解决方法:只需要在该shell脚本的开头加上

source /etc/profile
export LANG=zh_CN.UTF-8

导致乱码的主要原因是oozie执行的时候是以oozie用户在执行ssh的操作的,而该用户没有加载上述两个环境变量造成乱码

    原文作者:Ge文辉
    原文地址: https://www.jianshu.com/p/9f27a24afc08
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞