背景
Flink Job 的开发中,需要在同一个工程内完成多 module,多环境的打包,通过一个代码库生成多种不同的 Artifact。经过探索,通过 Maven 实现了该需求。
实现方式
-
组织资源文件
为应对多环境的需求,需要按照一定的规则组织资源文件(resources),如下图所示:
(资源文件路径示例图)
需要注意以下几点:
- 每个 module 对应一组 Artifacts,每组 Artifacts 包含若干个对应不同环境的 Artifact,如:
- module helloworld 对应一组产物(helloworld.local.jar、helloworld.dev.jar、helloworld.prod.jar)
- helloworld.local.jar 用于本地运行调试
- helloworld.dev.jar 用于开发环境
- helloworld.prod.jar 用于生产环境
- 将环境无关的资源和环境相关的资源分开放置,如:
- 在默认资源路径(src/main/resources)下面放置与环境无关的资源,这些资源会被放入所有的 Artifact 中
- 在一个独立于默认资源路径的单独路径(如 src/main/env)下保存各个环境的资源,这些资源只会被放入针对某个特定环境生成的 Artifact 中
- 每一个环境有一个单独的目录,用环境的名字命名,比如 local,dev,prod,seayoo-dev,seayoo 等
- 环境目录下存放的,资源文件命名应当相同,比如图中,每个环境目录下均包含命名为 “conf.txt” 的资源。这样才能做到程序只访问固定名字的资源,在生成的时候才决定 Artifact 要在哪个环境中部署。
-
编写 pom.xml 文件
需要在 pom.xml 文件中的 <build> 部分添加如下配置:
<build>
<!-- ${project.name} 是 module 的名字,${env} 是指定的环境 -->
<finalName>${project.name}.${env}</finalName>
<resources>
<resource>
<!-- 默认资源路径,存放环境无关的资源 -->
<directory>src/main/resources</directory>
</resource>
<resource>
<!-- 环境相关的资源路径 -->
<directory>src/main/env/${env}</directory>
</resource>
</resources>
</build>
需要注意以下几点:
- 标签 <resources> 可以包含多个 <resource>,每个 resource 都可以对应一个资源路径 <directory>
- ${env} 不是 pom.xml 内部定义的变量,而是从外部传入的,用于在生成制品的时候指定对应的环境
- ${project.name} 是 Maven 内部定义的 module 名字,在指定了生成的 project 之后该变量会被自动赋值
- <finalName> 标签的作用是配置 Artifact 的名称,格式可以灵活配置
-
执行生成命令
mvn clean package -pl helloworld -am -D env=local
-
-pl(--projects)
选项后可跟随 {groupId}:{artifactId} 或者所选模块的相对路径(多个模块以逗号分隔),此处传入的参数 helloworld 为指定生成 Artifact 的 module 名字,可指定多个,用 ‘,’ 间隔。
-
-am(--also-make)
同时处理选定模块所依赖的模块。
-
-D(--define)
表示 Properties 属性,可在 pom.xml 中定义变量,并通过此处传入的参数进行插值。此处的 env 是 pom.xml 中定义的用来指定环境的变量。可传入多个参数,用多个 -D 来指定。
执行命令后生成的 Artifact 为 helloworld.local.jar
:
Jar 内部包含的资源如下:
程序读取 conf.txt 中包含的环境相关的信息后,进行输出,如下: