[英]Unable to submit Spring boot java application to Spark cluster
我使用Spring Boot開發了一個Web應用程序,該應用程序使用Apache Spark來查詢來自不同數據源(例如Oracle)的數據。 開始時,我曾計划運行應用程序而不使用spark-submit腳本提交應用程序,但是看起來如果不提交jar便無法連接到主集群。 我已經成功生成了一個uber jar,其中包含我正在使用的所有依賴項和子項目,但是Spark似乎不喜歡Spring Boot應用程序。 當我嘗試提交應用程序時,spark顯示以下錯誤:
Exception in thread "main" java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation (class org.slf4j.impl.Log4jLoggerFactory loaded from file:/home/rojasmi1/spark/spark-1.4.0/assembly/target/scala-2.10/spark-assembly-1.4.0-hadoop2.2.0.jar). If you are using Weblogic you will need to add 'org.slf4j' to prefer-application-packages in WEB-INF/weblogic.xml Object of class [org.slf4j.impl.Log4jLoggerFactory] must be an instance of class ch.qos.logback.classic.LoggerContext
at org.springframework.util.Assert.isInstanceOf(Assert.java:339)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.getLoggerContext(LogbackLoggingSystem.java:151)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.getLogger(LogbackLoggingSystem.java:143)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.beforeInitialize(LogbackLoggingSystem.java:89)
at org.springframework.boot.logging.LoggingApplicationListener.onApplicationStartedEvent(LoggingApplicationListener.java:152)
at org.springframework.boot.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:139)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:151)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:128)
at org.springframework.boot.context.event.EventPublishingRunListener.publishEvent(EventPublishingRunListener.java:100)
at org.springframework.boot.context.event.EventPublishingRunListener.started(EventPublishingRunListener.java:54)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:277)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
at ch.dlx.QubidaOracleConnectorApplication.main(QubidaOracleConnectorApplication.java:12)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:664)
at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:169)
at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:192)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:111)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
使用Spark的默認log4j配置文件:org / apache / spark / log4j-defaults.properties
我試圖在pom文件中排除slf4j-log4j12依賴性,但是我仍然遇到相同的錯誤。
pom文件包含以下配置:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ch.dlx</groupId>
<artifactId>qubida-oracle-connector</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>qubida-oracle-connector</name>
<description></description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spark -->
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>1.4.0</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_2.11</artifactId>
<version>1.4.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-hadoop-core</artifactId>
<version>1.3.0</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- DB Drivers -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.4.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<keepDependenciesWithProvidedScope>true</keepDependenciesWithProvidedScope>
<artifactSet>
<excludes>
<exclude>org.slf4j</exclude>
</excludes>
</artifactSet>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
有沒有辦法將Spring Boot應用程序提交到集群? 是否應該考慮需要公開RESTful API的其他類型的項目? 有沒有一種方法可以在不提交.jar的情況下連接到spark集群?
在此先感謝您的幫助。
我有一個類似的問題,要解決該問題,請嘗試使用以下排除方法刪除Spring Boot日志記錄:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
如果在初始化servlet時仍然出現錯誤
java.lang.NoSuchMethodError:javax.servlet.ServletContext.getVirtualServerName()Ljava / lang / String;
然后嘗試使用入門級父級的1.2.1.RELEASE版本,因為這是由Spark Cluster使用的servlet-api版本引起的。
在構建時,Spring Boot會查看您的構建中是否包含了特定的日志記錄實現,如果尚未包含,則默認使用Logback。 顯然,Spark在運行應用程序時將Log4J添加到類路徑中,這又會導致運行時錯誤,因為Spring Boot現在在類路徑上找到兩個記錄器實現:一個是在構建時包含的(Logback),另一個是在運行時添加(Log4J)。
如果Spark提供了一種在運行時禁止包含Log4J的方法,則可以這樣做,並且默認情況下只需讓Spring Boot連接到Logback中即可。
如果Spark強迫您使用Log4J,那么解決方案將是在您的構建中顯式包括Log4J(而不是Logback),以便Spring Boot在構建時“看到”它,因此不包括Logback。
編輯:我應該已經通過查看Spring Boot文檔檢查了我的假設。 您還必須明確排除Log4J。 參見Spring Boot的Logging Docs 。
Spark僅支持log4j。 為了強制spring-boot默認使用log4j而不是logback,請從spring-boot參考文檔中應用此過程,但請確保將log4j2更改為log4j,並為其提供一個版本,例如1.2.17。 您還需要將log4j.properties文件放在src/main/resources
。 您可以從Spark的/ conf目錄復制log4j.properties.template並將其重命名為log4j.properties。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.