前言

最近准备对数据质量进行监控,选定的工具是开源的Apache Griffin,由于文档稀缺,加上griffin本身使用的组件众多,期间采坑不少,我们将打好的包measure-0.6.0-SNAPSHOT.jar放到集群中,通过livy调用spark命令执行任务,过程还是相对繁琐的。本文就spark任务结果写入elasticsearch遇到异常做个小结。

异常

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/impl/client/HttpClients

这个好解决,加上httpClient依赖就好。

		<dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
        </dependency>

接下来又遇到了。

java.lang.NoSuchFieldError: INSTANCE
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.<clinit>(SSLConnectionSocketFactory.java:144)
    at org.apache.http.impl.client.HttpClientBuilder.build(HttpClientBuilder.java:966)
    at org.apache.griffin.measure.utils.HttpUtil$.doHttpRequest(HttpUtil.scala:50)
    at org.apache.griffin.measure.sink.ElasticSearchSink$$anonfun$org$apache$griffin$measure$sink$ElasticSearchSink$$func$1$1.apply$mcZ$sp(ElasticSearchSink.scala:69)
    at org.apache.griffin.measure.sink.ElasticSearchSink$$anonfun$org$apache$griffin$measure$sink$ElasticSearchSink$$func$1$1.apply(ElasticSearchSink.scala:69)
    at org.apache.griffin.measure.sink.ElasticSearchSink$$anonfun$org$apache$griffin$measure$sink$ElasticSearchSink$$func$1$1.apply(ElasticSearchSink.scala:69)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
    at scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask.exec(ExecutionContextImpl.scala:121)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
19/07/09 19:59:26 ERROR yarn.ApplicationMaster: RECEIVED SIGNAL TERM

根据java.lang.NoSuchFieldError: INSTANCE搜索,很多会文章会提升你更换httpclienthttpcore这两个包,然后我从最新版本往下换,换到4.3的版本,确实HttpClientBuilder.build 异常的行数变了,最开始是966,说明更换的jar包是被使用了,这个让我欣喜也迷惑了我很久。因为无论哪个版本NoSuchFieldError: INSTANCE这个问题都存在。
只有另外想办法了,之后考虑换个环境,远程集群不行,本地调用下这个httpclient测试下试试,然后写了个简单的测试用例。

def httpResult(): Unit = {
    // 集群的异常就client的创建中
    val client = HttpClientBuilder.create.build
    val dataMap = Map[String, String](("name","test2"));
    val data = JsonUtil.toJson(dataMap)
    // http request
    val params = Map[String, Object]()
    val header = Map[String, Object](("Content-Type", "application/json"))
    // HttpUtil工具就是创建并执行一个HttpPost
    val result = HttpUtil.doHttpRequest("http://sit-01:9200/griffin/accuracy","post", params, header, data)
    print(result)
  }

执行发现client的创建并没有异常,并且result返回true,在远程es中也能查到这条name的记录。于是排除es本身的问题和jar包版本的问题。百思不得其解,但是能肯定是jar包出了问题。如果集群没有采用httpclient的jar包,那么异常行数为什么会变,如果采用了为什么一直是那个异常。spark集群会不会有自带低级的httpclient版本导致冲突了。想到这,果断看了下spark2目录下的jars。

[root@sit-01 jars]# ls |grep http
commons-httpclient-3.1.jar
httpcore-4.4.8.jar

集群中spark2是cdh安装的2.3.1的版本,发现里面没有httpclient的包。于是突发奇想的在集群中添加一个httpclient-4.5.2.jar

wget https://repo1.maven.org/maven2/org/apache/httpcomponents/httpclient/4.5.2/httpclient-4.5.2.jar

果然,查看yarn管理界面,job能够正常执行,结果写入es了。

小结

如果学习或者工作中有使用一些新的东西,期间会经常遇到各类环境,版本问题,语法的问题。个人觉得还是要珍惜这些机会,如果能做出点东西是很有成就感的。找点有挑战的事情,这个过程也能加快自己的成长,毕竟搬砖多了也没意思。

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐