解讀spark添加二方包導(dǎo)致依賴沖突排查問題
問題描述
近期發(fā)現(xiàn)了一個(gè)線上問題,本地啟動(dòng)byzer服務(wù)是正常的,但打好的docker鏡像就是拋異常跑不起來,而前幾天構(gòu)建的鏡像是正常的,初步定位到時(shí)新的發(fā)布導(dǎo)致的!
于是經(jīng)過了一系列痛苦的排查。
錯(cuò)誤堆棧
看byzer-lang最近的提交記錄都在30天前,顯示不會(huì)是它的問題,于是根據(jù)日志研究。
7bafdda4df93] __MMMMMM__ Total jobs: 1 current job:1 job script:load modelList.`` as __output__
22/02/09 14:58:32 ERROR Executor: Exception in task 0.0 in stage 2.0 (TID 2)
java.lang.IllegalArgumentException: Illegal pattern component: XXX
at org.apache.commons.lang3.time.FastDatePrinter.parsePattern(FastDatePrinter.java:282)
at org.apache.commons.lang3.time.FastDatePrinter.init(FastDatePrinter.java:149)
at org.apache.commons.lang3.time.FastDatePrinter.<init>(FastDatePrinter.java:142)
at org.apache.commons.lang3.time.FastDateFormat.<init>(FastDateFormat.java:384)
at org.apache.commons.lang3.time.FastDateFormat.<init>(FastDateFormat.java:369)
at org.apache.commons.lang3.time.FastDateFormat$1.createInstance(FastDateFormat.java:91)
at org.apache.commons.lang3.time.FastDateFormat$1.createInstance(FastDateFormat.java:88)
at org.apache.commons.lang3.time.FormatCache.getInstance(FormatCache.java:82)
報(bào)錯(cuò)xxx令人不知所措,一開始懷疑是modelList這個(gè)腳本在RestController執(zhí)行的時(shí)候,攜帶了這個(gè)xxx錯(cuò)誤參數(shù),但因?yàn)槭晴R像中不好debug,定位堆棧拋異常的是如下代碼:
val jsonDF = limitOrNot { df.limit(outputSize) }.toJSON val scriptJsonStringResult = fetchType match { case "collect" => jsonDF.collect().mkString(",")
看代碼得知是jsonDF.collect().mkString(",")這行的問題,outputSize數(shù)據(jù)有問題,但我并沒有在啟動(dòng)服務(wù)的時(shí)候請(qǐng)求任何腳本,于是陷入了死胡同。
google后發(fā)現(xiàn)是一個(gè)spark2普遍的問題,找到如下文章:
- https://www.codetd.com/en/article/12490356
- https://stackoverflow.com/questions/46429616/spark-2-2-illegal-pattern-component-xxx-java-lang-illegalargumentexception-ill
描述很清晰,是commons-lang3依賴沖突導(dǎo)致的,需要保證commons-lang3依賴在3.5以上。
于是順著這個(gè)方向,排了工程里面相關(guān)的依賴,本地啟動(dòng)正常,docker中啟動(dòng)報(bào)錯(cuò)。。。
于是懷疑是docker環(huán)境問題導(dǎo)致,拉取了最新的docker構(gòu)建腳本,發(fā)現(xiàn)大量新增代碼,果然是新增代碼的鍋,新增邏輯比較多,于是直接拉上相關(guān)同事一起看。
發(fā)現(xiàn)最近docker的lib文件夾下增加了很多jar,spark提交任務(wù)的腳本增加了很多插件類:
COPY lib/ansj_seg-5.1.6.jar \ lib/nlp-lang-1.7.8.jar \ lib/${AZURE_BLOB_NAME} \ lib/mlsql-assert-${MLSQL_SPARK_VERSION}_${SCALA_BINARY_VERSION}-0.1.0-SNAPSHOT.jar \ lib/mlsql-excel-${MLSQL_SPARK_VERSION}_${SCALA_BINARY_VERSION}-0.1.0-SNAPSHOT.jar \ lib/mlsql-ext-ets-${MLSQL_SPARK_VERSION}_${SCALA_BINARY_VERSION}-0.1.0-SNAPSHOT.jar \ lib/mlsql-shell-${MLSQL_SPARK_VERSION}_${SCALA_BINARY_VERSION}-0.1.0-SNAPSHOT.jar \ lib/mlsql-mllib-${MLSQL_SPARK_VERSION}_${SCALA_BINARY_VERSION}-0.1.0-SNAPSHOT.jar \ ${MLSQL_HOME}/libs/
spark-submit 任務(wù)啟動(dòng)腳本:
$SPARK_HOME/bin/spark-submit --class streaming.core.StreamingApp \ --driver-memory ${DRIVER_MEMORY} \ ... -streaming.plugin.clzznames "tech.mlsql.plugins.ds.MLSQLExcelApp,tech.mlsql.plugins.assert.app.MLSQLAssert,tech.mlsql.plugins.shell.app.MLSQLShell,tech.mlsql.plugins.ext.ets.app.MLSQLETApp"
顯然是二方包導(dǎo)致的依賴沖突,而之前花了大量時(shí)間改byzer的依賴,打包,部署,重新構(gòu)建docker都是無用功!
但jar還是比較多,只能窮舉的在docker環(huán)境中一個(gè)一個(gè)的刪掉,測(cè)試是否有啟動(dòng)異常,在排查到AZURE這個(gè)jar的時(shí)候發(fā)現(xiàn)了問題,該jar是我們?yōu)榱酥С諥ZURE添加的,已經(jīng)經(jīng)過沖突依賴shade處理的,shade重構(gòu)建的項(xiàng)目在這個(gè)REPO下:
GitHub - byzer-org/byzer-objectstore-dep
于是clone項(xiàng)目,使用maven Dependency Analyzer分析:
并沒有commons-lang3這個(gè)依賴,于是懷疑是其他依賴導(dǎo)致的沖突,把a(bǔ)zure相關(guān)的依賴直接引入到byzer的項(xiàng)目中(為了做依賴沖突分析),于是驚奇的發(fā)現(xiàn)commons-lang3又有了:
是因?yàn)榇虬?xiàng)目為了滿足不同的hadoop版本打包,設(shè)置了profiles,導(dǎo)致分析工具失效了:
修復(fù)問題
對(duì)azure-store項(xiàng)目中的依賴做shade處理:
<profile> <id>shade</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.0</version> <configuration> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> <createDependencyReducedPom>false</createDependencyReducedPom> <relocations> <relocation> <pattern>org.apache.commons</pattern> <shadedPattern>shadeio.azure.org.apache.commons</shadedPattern> </relocation> <relocation> <pattern>commons-lang</pattern> <shadedPattern>shadeio.azure.commons-lang</shadedPattern> </relocation> </relocations> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </profile>
在byzer-lang中添加統(tǒng)一的版本約束:
<dependencyManagement> <dependencies> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.10</version> </dependency> </dependencies> </dependencyManagement>
在啟動(dòng)byzer的子pom中顯式聲明依賴:
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency>
問題得到解決,另外發(fā)現(xiàn)一個(gè)問題,雖然dependencyManagement定義版本這種定義方式有如下規(guī)范:
- 如果子pom中顯式設(shè)置了version則以子pom的version為主
- 需要使用父pom依賴時(shí)需要聲明依賴并且不設(shè)置version
但我測(cè)試發(fā)現(xiàn)在azure這個(gè)依賴中攜帶的commons-lang3即使不在子pom聲明使用dependencyManagement定義后,其版本也會(huì)被約束成3.10而不是以前的3.3。
筆者建議聲明一下避免打包解析樹的時(shí)候出現(xiàn)問題。
?總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Feign如何解決服務(wù)之間調(diào)用傳遞token
這篇文章主要介紹了Feign如何解決服務(wù)之間調(diào)用傳遞token,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03IntelliJ IDEA中ajax開發(fā)實(shí)現(xiàn)分頁(yè)查詢示例
這篇文章主要介紹了IntelliJ IDEA中ajax開發(fā)實(shí)現(xiàn)分頁(yè)查詢,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-03-03Java異常處理Guava?Throwables類使用實(shí)例解析
這篇文章主要為大家介紹了Java異常處理神器Guava?Throwables類使用深入詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12mybatis spring配置SqlSessionTemplate的使用方式
這篇文章主要介紹了mybatis spring配置SqlSessionTemplate的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08關(guān)于SpringBoot使用Redis空指針的問題(不能成功注入的問題)
這篇文章主要介紹了關(guān)于SpringBoot使用Redis空指針的問題(不能成功注入的問題),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11