YarnClient的init方法执行后无反应

比较玄学,在使用YarnClient来查询Spark任务ID的时候,初始化方法执行完没有任何反应,相同的代码在自己Windows电脑上跑的好好的,找了一个Linux的机器也是可以的,但是放到容器里面就不行(这是什么鬼)。最终发现,原来成败仅在一念之间。。。 ### 1. 主要功能 SpringBoot启动后,连接zookeeper进行选主,抢主成功的节点连接Yarn进行任务查询,如果存在RUNNING的任务,将其kill掉,并重新提交新的Spark任务。(为的是在升级或重新安装的场景,Springboot的生命周期能和yarn上面spark任务的生命周期保持“一致”)。 ### 2. 上代码 ``` @Slf4j public class AppYarnClient { private final YarnClient client; public AppYarnClient() { client = YarnClient.createYarnClient(); Configuration conf = new Configuration(); conf.addResource(new Path("/opt/huawei/iss/conf/core-site.xml"), false); conf.addResource(new Path("/opt/huawei/iss/conf/yarn-site,xml"), false); client.init(conf); log.info("yarn client init finished..."); client.start(); log.info("yarn client start finished..."); } public List getRunningAppIds(String appName) { List applications = null; try { EnumSet appStates = EnumSet.noneOf(YarnApplicationState.class); appStates.add(YarnApplicationState.RUNNING); applications = client.getApplications(appStates); } catch (YarnException | IOException ex) { log.error("get yarn applications failed. ", ex); } List runningApps = new ArrayList(); if (CollectionUtils.isEmpty(applications)) { return runningApps; } runningApps = applications.stream() .filter(report -> report.getName().contains(appName)) .map(ApplicationReport::getApplicationId) .collect(Collectors.toList()); return runningApps; } public boolean killApplication(ApplicationId appId) { try { client.killApplication(appId); } catch (YarnException | IOException ex) { log.error("yarn kill application of {} failed, because: ", appId.toString(), ex); return false; } return true; } public void killAndSubmit() { log.info("the yarn client will work..."); ShellUtils shellUtils = new ShellUtils(); List runningAppIds = getRunningAppIds("com.huawei.iss.ce.statistic.streaming.StatisticEngine"); log.info("the running apps are {}", runningAppIds); if (CollectionUtils.isEmpty(runningAppIds)) { log.info("there are no running app!"); shellUtils.execute(new String[] {"sh", "-x", "/opt/huawei/iss/components/ComputingEngine/setup/start.sh"}); return; } for (ApplicationId runningAppId : runningAppIds) { boolean killResult = killApplication(runningAppId); log.info("kill app result is: {}, the appId is {}", killResult, runningAppId.toString()); } log.info("exist apps have been killed, will submit again."); shellUtils.execute(new String[] {"sh", "-x", "/opt/huawei/iss/components/ComputingEngine/setup/start.sh"}); } } ``` ### 3. 问题描述 在执行完yarnClient.init(conf)后,日志只打印了一句:Service: org.apache.hadoop.yarn.client.api.impl.YarnClientImpl entered state INITED,然后这个线程就结束了,没有后续,debug日志开启也没有异常打印(黑人问号???) ![image.png](https://s2.51cto.com/images/20210705/1625488530602652.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) 我就去查看源码,发现这一句是在状态转换的时候打印的: ![image.png](https://s2.51cto.com/images/20210705/1625488587297828.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) 但是里面除了属性赋值,没有其他的操作,不会有异常抛出(继续满脸疑惑???)。这时候我继续看源码,发现会有一个创建连接的过程,入口是在创建YarnClientImpl的时候: ``` @Public public static YarnClient createYarnClient() { YarnClient client = new YarnClientImpl(); return client; } // 然后在serviceInit方法里面,这方法好像在哪见过? 哦!就是在yarnClient.init(conf)里面 protected void serviceInit(Configuration conf) throws Exception { ...... if (YarnConfiguration.timelineServiceV1Enabled(conf)) { this.timelineV1ServiceEnabled = true; this.timelineDTRenewer = getTimelineDelegationTokenRenewer(conf); this.timelineService = TimelineUtils.buildTimelineTokenService(conf); } if (this.timelineV1ServiceEnabled || conf.getBoolean("yarn.timeline-service.generic-application-history.enabled", false)) { this.historyServiceEnabled = true; this.historyClient = AHSClient.createAHSClient(); this.historyClient.init(conf); } ...... super.serviceInit(conf); } ``` 正常执行的情况,AHSClient.createAHSClient();这一句是可以正常初始化并连接到对应yarn节点的,但是在容器里没有打印它的执行日志。 怀疑点1:容器网络配置有问题??? 检查端口和主机映射,完全没毛病,况且我zookeeper都用得好好的呢(傲娇)—— 排除此怀疑。 怀疑点2:用的配置文件有问题?(core-site.xml和yarn-site.xml) 将容器里的配置文件拿出来对比客户端用到的配置文件,完全一样!!! —— 排除此怀疑。 怀疑点3:kerberos认证失败??? 检查kerberos认证过程,漏掉一个文件,补上,问题还是没解决。—— 排除此怀疑。 开始怀疑人生。。。是不是错误日志被屏蔽了,没有输出来??? 尝试把错误日志输出到执行脚本的控制台,然后 ClassNotFind: javax.ws.rs.ext.MessageBodyReader,在代码里搜索了一下: ![image.png](https://s2.51cto.com/images/20210705/1625489790511832.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) 这好像也莫得问题呀。。。查看打出来的jar包,emmm,少了一个jar。 依赖树打出来看一下:都是provide,难怪没有,加到容器里去,然后重启服务,牛批!!!好了。 ### 总结 刚接触大数据组件一周,感受就是:咋动不动就是jar包冲突,类找不到呢!!! 网上可以能搜到很多大同小异的问题和解决办法(网上能搜到的解决办法我也试过,对我来说没有帮我解决问题,所以没有列举),但是如果某一天遇到了奇奇怪怪的问题并且没有解决办法时,尝试怀疑一下自己引入的jar包是否是正常的(冲突,版本不对,少引入)。另外很多源码里的日志被屏蔽了,尝试把日志输出到控制台,看看究竟报的是什么错,有助于解决问题!!!

YarnClient的init方法执行后无反应

上一篇:计算机中丢失MSVCR120.dll


下一篇:图嵌入