简介:Datastream作业开发经常会遇到一些jar包冲突等问题。依赖关系被打包到作业jar中,可能存在依赖冲突。Datastream作业开发经常会遇到一些jar包冲突等问题。本文主要说明在job开发中需要引入哪些依赖,哪些需要打包到jobjar中,避免不必要的依赖被放入jobjar和可能的依赖冲突。一个Datastream作业主要涉及以下依赖:Flink的核心依赖和应用自身的依赖。每个Flink应用都依赖于一系列相关的库,这些库至少应该包括Flink的API。许多应用程序还依赖于与连接器相关的库(例如Kafka、Cassandra等)。在运行Flink应用时,无论是在分布式环境中运行,还是在本地IDE中测试,都需要Flink的运行时相关依赖。和大多数运行用户自定义应用的系统一样,Flink中有两大类依赖:Flink核心依赖:Flink本身由一组运行系统所必需的类和依赖组成,例如coordinator、network、checkpoint、faulttolerance、API、操作符(如windows)、资源管理等。所有这些类和依赖的集合构成了Flink运行时的核心,必须在Flink应用程序启动时存在。这些核心类和依赖被打包在flink-distjar中。它们是Flink的lib文件夹的一部分,也是Flink基础容器镜像的一部分。这些依赖之于Flink,就像Java运行所需的String、List等包含类的核心库(rt.jar、charsets.jar等)之于Java。Flink的核心依赖不包含任何连接器或扩展库(CEP、SQL、ML等),这使得Flink的核心依赖尽可能小,以避免默认在classpath中过度依赖,减少依赖冲突。用户应用程序依赖项:指特定用户应用程序所需的所有连接器、格式或扩展库。用户应用程序通常打包为jar文件,其中包含应用程序代码以及所需的连接器和库依赖项。用户应用程序依赖不应该包括FlinkDataStreamAPI和运行时依赖,因为这些已经包含在Flink的核心依赖中。依赖配置步骤1.添加基础依赖每一个Flink应用的开发都需要至少添加对相关API的基础依赖。手动配置项目时,需要添加对Java/ScalaAPI的依赖(这里以Maven为例,其他构建工具(Gradle、SBT等)也可以使用相同的依赖)。org.apache.flinkflink-streaming-java_2.111.12.3提供重要说明:请注意,所有这些依赖项的范围都设置为“已提供”。这意味着它们需要被编译,但是它们不应该被打包到项目生成的应用程序jar文件中——这些依赖是Flink核心依赖,它们在实际运行时已经被加载。强烈建议将依赖项设置为“provided”范围,未能将它们设置为“provided”最多只会导致jar膨胀,因为它还包括所有Flink核心依赖项。而且在最坏的情况下,应用jar文件中添加的Flink核心依赖会和你自己的一些依赖发生版本冲突(通常通过Flink的反向类加载机制来避免)。关于IntelliJ的注意事项:为了让应用程序在IntelliJIDEA中运行,有必要在运行配置中选中“Includedependencieswith"Provided"scope”选项框。如果您没有该选项(可能是由于使用了较旧的IntelliJIDEA版本),那么一个简单的解决方法是创建一个调用应用程序的main()方法的测试用例。2.添加连接器和库依赖项。大多数应用程序的运行都需要特定的连接器或库,例如Kafka、Cassandra等连接器。这些连接器不是Flink核心依赖的一部分,必须作为附加依赖添加到应用程序中。以下代码是添加Kafka连接器依赖项的示例(Maven语法):org.apache.flinkflink-connector-kafka_2.111.12。3我们建议将应用代码及其所有依赖以jar-with-dependencies的形式打包到一个应用jar中。应用jar包可以提交到已有的Flink集群中,也可以添加到Flink应用的容器镜像中。对于从Maven作业模板(参见下面的Maven作业模板部分)创建的项目,依赖项将通过mvncleanpackage命令自动添加到应用程序的jar包中。对于没有模板配置的情况,推荐使用MavenShadePlugin(配置见附件)构建包含依赖的jar包。重要提示:为了Maven(和其他构建工具)正确地将依赖项打包到应用程序jar中,这些应用程序依赖项的范围必须为“编译”(不同于核心依赖项,其范围必须指定为“提供”)。Scala版本说明不同版本的Scala(2.11、2.12等)彼此不兼容。因此,Scala2.11对应的Flink版本不能用于使用Scala2.12的应用。所有依赖(或传递)Scala的Flink依赖项都以它们构建时使用的Scala版本作为后缀,例如flink-streaming-scala_2.11。当只使用Java开发时可以选择任意Scala版本,使用Scala开发时需要选择与应用的Scala版本相匹配的Flink依赖版本。注意:2.12.8之后的Scala版本不兼容之前的2.12.x版本,所以Flink项目无法将2.12.x版本升级到2.12.8之后的版本。用户可以在本地编译Scala版本对应的Flink。为了使其工作,需要添加-Djapicmp.skip以在构建时跳过二进制兼容性检查。Hadoop依赖项的一般规则:永远不要将与Hadoop相关的依赖项直接添加到您的应用程序中。(唯一的例外是当使用已有的Hadoop输入/输出格式和Flink的Hadoop兼容包时)如果你想将Flink和Hadoop结合使用,你需要包含Hadoop依赖的Flink启动项,而不是添加Hadoop作为应用程序依赖项。Flink将使用HADOOP_CLASSPATH环境变量指定的Hadoop依赖项,可以通过以下方式设置:exportHADOOP_CLASSPATH=hadoopclasspath``这种设计有两个主要原因:一些与Hadoop的交互可能发生在Flink的核心模块中,以及在用户应用程序启动之前,例如为检查点设置HDFS,为Hadoop使用Kerberos令牌进行身份验证,或者在YARN上部署等。Flink的反向类加载机制从核心依赖项中隐藏了许多传递依赖项。这不仅适用于Flink自身的核心依赖,也适用于Hadoop的依赖。这样,应用程序可以使用相同依赖项的不同版本而不会发生依赖项冲突(相信我们,这很重要,因为Hadoop依赖项树非常庞大。)如果在IDE内进行测试或开发时需要Hadoop依赖项(例如HDFS访问),请将这些依赖项的范围配置为测试或提供。转换表连接器/格式资源#Flink使用Java的服务提供者接口(SPI)机制,通过特定的标识符加载表的连接器/格式工厂。由于每个表的连接器/格式的名为org.apache.flink.table.factories.Factory的SPI资源文件位于同一目录:在META-INF/services下,在构建使用多个表连接器/格式的项目时uberjar,这些资源文件会相互覆盖,从而导致Flink无法正确加载工厂类。这种情况下,推荐的方法是通过mavenshade插件的ServicesResourceTransformer对META-INF/services目录下的这些资源文件进行转换。给定示例的pom.xml文件内容如下,其中包含连接器flink-sql-connector-hive-3.1.2和flink-parquet格式。4.0.0org.examplemyProject1.0-SNAPSHOTorg.apache.flinkflink-sql-connector-hive-3.1.2__2.111.13.0org.apache.flinkflink-parquet__2.11<1.13.0<构建>org.apache.maven.pluginsmaven-shade-pluginshadepackageshade</plugins>配置好ServicesResourceTransformer后,项目构建uber-jar时,META-INF/services目录下的这些资源文件会整合在一起,不会互相覆盖。Mavenjobtemplates强烈推荐使用这种方式配置,可以减少很多重复的配置工作。先决条件唯一的环境要求是安装Maven3.0.4(或更高版本)和Java8.x。创建项目通过以下两种方式之一创建项目:使用Mavenarchetypes$mvnarchetype:generate\-DarchetypeGroupId=org.apache.flink\-DarchetypeArtifactId=flink-quickstart-java\-DarchetypeVersion=1.12.3这允许您命名新创建的项目。它会以交互方式要求您提供groupId、artifactId和包名称。运行快速启动脚本$curlhttps://flink.apache.org/q/quickstart.sh|bash-s1.12.3我们建议您将此项目导入到您的IDE中进行开发和测试。IntelliJIDEA原生支持Maven项目。如果你使用Eclipse,你可以使用m2e插件导入Maven项目。一些Eclipse包默认包含该插件,否则您需要手动安装。请注意:默认的JavaJVM堆大小对于Flink来说可能太小了。你必须手动增加它。在Eclipse中,选择RunConfigurations->Arguments并写入VMArguments框:-Xmx800m。在IntelliJIDEA中,更改JVM选项的推荐方法是使用帮助|编辑自定义VM选项选项菜单。有关详细信息,请参阅此帖子。构建项目要构建/打包项目,请转到项目目录并运行“mvncleanpackage”命令。执行将生成一个JAR文件:target/-.jar,其中包含您的应用程序,以及作为依赖项添加到应用程序的连接器和库。注意:如果您使用与StreamingJob不同的类作为应用程序的主类/入口点,我们建议您相应地更改pom.xml文件中的mainClass设置。这样,Flink就可以直接从JAR文件中运行应用程序,而无需额外指定主类。附录:用于构建具有依赖项的jar包的模板要构建包含连接器和库所需的所有依赖项的应用程序JAR,可以使用以下阴影插件定义:org.apache.maven.pluginsmaven-shade-plugin3.1.1packageshadecom.google.code.findbugs:jsr305org.slf4j:*log4j:*排除>排除>*:*META-INF/*.SFMETA-INF/*.DSAMETA-INF/*.RSAmy.programs.main.clazz原版正文链接本文为阿里云原创内容,未经许可不得转载