【Maven實戰技巧】「外掛使用專題」Maven-Assembly外掛實現自定義打包

李浩宇Alex發表於2021-08-03

前提概要

最近我們專案越來越多了,然後我就在想如何才能把基礎服務的打包方式統一起來,並且可以實現按照我們的要求來生成,通過研究,我們通過使用maven的assembly外掛完美的實現了該需求,爽爆了有木有。本文分享該外掛的配置以及微服務的統一打包方式。

maven-assembly-plugin打包外掛

配置步驟及其他事項

首先我們需要在pom.xml中配置maven的assembly外掛

<build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <executions>
		<!-- 配置執行器 -->
          <execution>
            <id>make-assembly</id>
			<!-- 繫結到package生命週期階段上 -->
            <phase>package</phase>
            <goals>
			  <!-- 只執行一次 -->
              <goal>single</goal>
            </goals>
            <configuration>
              <!--生成包的末尾新增assembly id,一般關閉 -->
              <appendAssemblyId>false</appendAssemblyId>
              <finalName>${project.artifactId}-${project.version}</finalName>
              <!--載入指定的配置檔案-->
              <descriptors>
              		<descriptor>src/main/assembly/assembly.xml</descriptor>
              </descriptors>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
 </build>

配置引數介紹說明

  • execution:配置執行器
    • phase:繫結到package生命週期階段上
    • goal:{single}:只執行一次
    • configuration->appendAssemblyId:生成包的末尾新增assembly id,一般關閉
    • descriptor:src/main/assembly/assembly.xml:後續會講解,主要用於描述如何進行打包的規則。

自定義格式包assembly.xml

接著我們在src/main/assembly檔案中配置assembly.xml檔案

  <assembly>
      <id>唯一編號</id>
      <formats>
	      <!--打包的檔案格式,也可以有:war zip-->
          <format>tar.gz</format>
      </formats>
      <!--tar.gz壓縮包下是否生成和專案名相同的根目錄-->
      <includeBaseDirectory>true</includeBaseDirectory>
     <fileSets>
         <fileSet>
             <directory>src/main/bin</directory>
             <outputDirectory>/</outputDirectory>
			 <!-- Linux許可權 -->
             <fileMode>0644</fileMode>
         </fileSet>
         <fileSet>
			<directory>target/classes/META-INF/conf</directory>
            <outputDirectory>conf/META-INF/conf</outputDirectory>
			<!-- Linux許可權 -->
			<fileMode>0644</fileMode>
        </fileSet>
		<fileSet>
			<directory>target/classes</directory>
			<outputDirectory>conf</outputDirectory>
			<fileMode>0644</fileMode>
			<includes><!-- 只負責這些目標檔案-->
				<include>*.properties</include>
				<include>*.xml</include>
			</includes>
		</fileSet>
     </fileSets>
     <!-- 輸出到lib路徑 -->
     <dependencySets>
          <dependencySet>
             <!--是否在最外層套一個本專案的名稱的檔案目錄-->
             <useProjectArtifact>true</useProjectArtifact>
             <!-- 輸出到這個路徑下 -->
             <outputDirectory>lib</outputDirectory>
             <!--將scope為runtime的依賴包打包-->
             <scope>runtime</scope>
         </dependencySet>
     </dependencySets>
 </assembly>
  • 生成的lib資料夾下放該專案的所有依賴以及該服務jar包,src/main/bin資料夾下我們一般放start.sh和stop.sh兩個指令碼檔案用來開啟和關閉該服務,打包後直接放到根目錄下

  • 生成的tar.gz檔案的名字為:[maven-assembly-plugin外掛中配置的finalName]-[assembly.xml配置的id(若assembly中沒有指定id,則只有前半部分)].

assembly的具體語法,請參見官網:

  • 所以:maven-compiler-plugin是用來將程式碼生成jar的工具,maven-assembly-plugin是用來生成指定格式的工具。

  • 配置完成後進入標籤裡指定的位置建xml檔案,這裡是src/assembly/assembly-descriptor.xml,內容如下:

<assembly
	xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
	<id>my-assembly</id>
	<formats>
          <!--打包生成後的格式 -->
		<format>zip</format>
	</formats>
     <!-- -->
	<includeBaseDirectory>false</includeBaseDirectory>
	<fileSets>
		<fileSet>
               <!--指令碼所在的資料夾,以及打包後將指令碼輸出到哪個資料夾中 -->
			<directory>src/scripts</directory>
			<outputDirectory>alarm/bin</outputDirectory>
               <!-- 哪些檔案會被提取 -->
			<includes>
				<include>*.sh</include>
			</includes>
               <!-- 檔案許可權及編碼 -->
			<fileMode>0755</fileMode>
			<lineEnding>unix</lineEnding>
		</fileSet>
		<fileSet>
               <!--同上,這裡配置的是配置檔案所在的資料夾 -->
			<directory>src/main/resources</directory>
			<outputDirectory>alarm/conf</outputDirectory>
			<includes>
				<include>*.yml</include>
			</includes>
			<lineEnding>unix</lineEnding>
		</fileSet>
		<!--artifact -->
		<fileSet>
               <!--這裡的target是maven-compiler-plugin生成該專案的jar包的位置 -->
			<directory>target</directory>
			<outputDirectory>alarm/lib</outputDirectory>
			<includes>
				<include>*.jar</include>
			</includes>
			<fileMode>0755</fileMode>
		</fileSet>
	</fileSets>
	<dependencySets>
		<dependencySet>
               <!--這裡是將該專案依賴的所有jar包存入lib資料夾中 -->
			<outputDirectory>alarm/lib</outputDirectory>
			<useProjectArtifact>false</useProjectArtifact>
			<useProjectAttachments>true</useProjectAttachments>
			<scope>runtime</scope>
		</dependencySet>
	</dependencySets>
</assembly>

啟動指令碼

在完成以上配置後,只需在指定的位置建立scripts/start.sh和stop.sh兩個指令碼即可完成。具體啟動指令碼如下:

start.sh啟動檔案指令碼

#!/bin/sh
basepath=$(cd `dirname $0`;cd '../'; pwd)
echo "path:"$basepath
jarHome='/my.jar'
echo "Starting my service"
ls_date=`date +%Y%m%d`
if [ ! -d "${basepath}/log" ]; then
  mkdir ${basepath}/log
fi
if [ ! -d "$basepath/log/${ls_date}" ]; then
  mkdir $basepath/log/${ls_date}
fi
nohup java -jar $basepath$jarHome --spring.config.location=$basepath/conf/server-attach.yml,$basepath/conf/server-shared.yml> $basepath/log/${ls_date}/${ls_date}.log &
#####

主要命令是獲取當天日期,然後在log資料夾下建立指定日期的資料夾,並將日誌存放進去。其中–spring.config.location用於載入指定的配置檔案,多個配置檔案用逗號分割。

stop.sh停止檔案指令碼

停止指令碼通過ps -ef獲取程式id然後kill,如下:

#!/bin/sh
my=`ps -ef |grep my.jar | grep -v grep | awk '{print $2}'`
kill -9 $my

結語

以上配置完成後使用mvn package命令即可自動打成一個zip壓縮包,包內包含bin、conf、lib資料夾,可用啟動指令碼一鍵啟動。實際上這裡能修改的地方還有很多,包括啟動指令碼也可以用其他方式如java -classpath方式啟動等等,具體的可以根據自身需求進行相應修改。

相關文章