前言
本篇和大家分享的是springboot打包并結合shell腳本命令部署,重點在分享一個shell程序啟動工具,希望能便利工作;
- profiles指定不同環境的配置
- maven-assembly-plugin打發布壓縮包
- 分享shenniu_publish.sh程序啟動工具
- linux上使用shenniu_publish.sh啟動程序
profiles指定不同環境的配置
通常一套程序分為了很多個部署環境:開發,測試,uat,線上 等,我們要想對這些環境區分配置文件,可以通過兩種方式:
- 通過application.yml中編碼指定 profile.active=uat 方式指定
- 通過mvn中profiles來區分不同環境對應的配置文件夾,人工可以手動在idea勾選生成不同環境的包(推薦)
這里我們要講的是第二種,首先在mvn中配置如下內容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
<profiles> <profile> <id>node</id> <properties> <!--傳遞給腳本的參數值--> <activeprofile>node</activeprofile> < package -name>${scripts_packagename}</ package -name> <boot-main>${scripts_bootmain}</boot-main> </properties> <activation> <activebydefault> true </activebydefault> </activation> </profile> <profile> <id>node1</id> <properties> <activeprofile>node1</activeprofile> < package -name>${scripts_packagename}</ package -name> <boot-main>${scripts_bootmain}</boot-main> </properties> </profile> <profile> <id>node2</id> <properties> <activeprofile>node2</activeprofile> < package -name>${scripts_packagename}</ package -name> <boot-main>${scripts_bootmain}</boot-main> </properties> </profile> </profiles> |
節點粗解:
id:用來指定不同環境配置文件所在的目錄,如下我這里:
properties:
該節點中的節點是可作為參數傳遞給其他配置文件,如我這里的package-name節點值就可以在另外的assembly.xml或者shell腳本文件中通過${package-name}獲取到,如下:
activebydefault:
指定默認環境配置文件夾
maven-assembly-plugin打發布壓縮包
對于springboot程序打包,可以分為jar和war,這里是jar包;有場景是咋們配置文件或者第三方等依賴包不想放到工程jar中,并且把這些文件壓縮成一個zip包,方便上傳到linux;此時通過maven-assembly-plugin和maven-jar-plugin就可以做到,mvn的配置如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
<plugin> <groupid>org.apache.maven.plugins</groupid> <artifactid>maven-jar-plugin</artifactid> <version> 2.6 </version> <configuration> <archive> <addmavendescriptor> false </addmavendescriptor> <manifest> <addclasspath> true </addclasspath> <classpathprefix>lib/</classpathprefix> <mainclass>${scripts_bootmain}</mainclass> </manifest> </archive> <!--打包排除項--> <excludes> <exclude>** /*.yml</exclude> <exclude>**/*.properties</exclude> <exclude>**/*.xml</exclude> <exclude>**/ *.sh</exclude> </excludes> </configuration> <executions> <execution> <id>make-a-jar</id> <phase>compile</phase> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> <plugin> <groupid>org.apache.maven.plugins</groupid> <artifactid>maven-assembly-plugin</artifactid> <version> 2.4 </version> <!-- the configuration of the plugin --> <configuration> <!-- specifies the configuration file of the assembly plugin --> <descriptors> <descriptor>${project.basedir}/src/main/assembly/assembly.xml</descriptor> </descriptors> </configuration> <executions> <execution> <id>make-assembly</id> <phase> package </phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> |
值得注意的地方如下幾點:
- mainclass節點:用來指定啟動main函數入口類路徑,如這里的:com.sm.eurekaserverapplication
- excludes節點:排除主jar包中配置等一些列后綴文件,因為我們要包這些配置文件放到主包外面
- descriptor節點:用來指定assembly插件對應的assembly.xml配置文件
有了上面mvn配置,我們還需要assembly.xml的配置,這里提取了結合shell腳本發布程序的配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
<assembly xmlns= "http://maven.apache.org/assembly/2.0.0" xmlns:xsi= "http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http: //maven.apache.org/assembly/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd http: //maven.apache.org/assembly/2.0.0 "> <id>${activeprofile}</id> <!--打包成一個用于發布的zip文件--> <formats> <format>zip</format> </formats> <!-- true :zip中生成一級目錄(此處屏蔽,配合腳本需要profiles后綴)--> <includebasedirectory> false </includebasedirectory> <dependencysets> <dependencyset> <!--打包進zip文件的lib目錄--> <useprojectartifact> false </useprojectartifact> <outputdirectory>${ package -name}-${activeprofile}/lib</outputdirectory> <unpack> false </unpack> </dependencyset> </dependencysets> <filesets> <!-- 配置文件打包進zip文件的conf目錄 --> <fileset> <directory>${project.basedir}/src/main/profiles/${activeprofile}</directory> <outputdirectory>${ package -name}-${activeprofile}/conf</outputdirectory> <includes> <include>** /*</include> <!--<include>*.xml</include>--> <!--<include>*.properties</include>--> <!--<include>*.yml</include>--> </includes> </fileset> <!--啟動腳本打包進zip文件--> <fileset> <directory>${project.basedir}/src/main/scripts</directory> <outputdirectory></outputdirectory> <includes> <include>**/ *</include> </includes> <!-- 文件文件權限為 777 --> <filemode> 777 </filemode> <!-- 目錄權限為 777 --> <directorymode> 777 </directorymode> <!--腳本中參數變量為pom中的值 關鍵--> <filtered> true </filtered> </fileset> <!-- 項目編譯出來的jar打包進zip文件 --> <fileset> <directory>${project.build.directory}</directory> <outputdirectory>${ package -name}-${activeprofile}/</outputdirectory> <includes> <include>*.jar</include> </includes> </fileset> </filesets> </assembly> |
重點節點介紹:
- formats節點:把配置文件和jar包等壓縮成什么文件格式,這里可以有:zip,tar等
- filemode節點:指定scripts目錄下腳本文件(這里是:shenniu_publish.sh)在linux上文件權限為777
- filtered節點:腳本中參數變量為pom的profiles中properties的值(該配置,是把mvn中屬性值映射生成到sh文件中,如:${package-name})
完成上面配置后,此時我們可以通過idea上勾選切換不同環境來打zip包,如圖:
分享shenniu_publish.sh程序啟動工具
上面步驟完成了zip格式的發布包,我們再分享下啟動程序的shell腳本,該腳本具有的功能如:
解壓zip+啟動jar包啟動jar包停止對應jar運行重啟jar程序
目前該shell中封裝了兩種啟動jar命令的方式:
java -cpjava -jar
如圖命令格式:
來看全部的shell代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
#!/usr/bin/env bash #可變參數變量 languagetype= "javac" #支持 java,javac,netcore 發布 #參數值由pom文件傳遞 basezipname= "${package-name}-${activeprofile}" #壓縮包名稱 publish-test.zip的publish packagename= "${package-name}" #命令啟動包名 xx.jar的xx mainclass= "${boot-main}" #java -cp啟動時,指定main入口類;命令:java -cp conf;lib\*.jar;${packagename}.jar ${mainclass} #例子 # basezipname= "publish-test" #壓縮包名稱 publish-test.zip的publish # packagename= "publish" #命令啟動包名 publish.jar的xx #固定變量 basepath=$(cd `dirname $ 0 `/; pwd) basezippath= "${basepath}/${basezipname}.zip" #壓縮包路徑 basedirpath= "${basepath}" #解壓部署磁盤路徑 pid= #進程pid #解壓 function shenniu_unzip() { echo "解壓---------------------------------------------" echo "壓縮包路徑:${basezippath}" if [ ! `find ${basezippath}` ] then echo "不存在壓縮包:${basezippath}" else echo "解壓磁盤路徑:${basedirpath}/${basezipname}" echo "開始解壓..." #解壓命令 unzip -od ${basedirpath}/${basezipname} ${basezippath} #設置執行權限 chmod +x ${basedirpath}/${basezipname}/${packagename} echo "解壓完成。" fi } #檢測pid function getpid() { echo "檢測狀態---------------------------------------------" pid=`ps -ef | grep -n ${packagename} | grep -v grep | awk '{print $2}' ` if [ ${pid} ] then echo "運行pid:${pid}" else echo "未運行" fi } #啟動程序 function start() { #啟動前,先停止之前的 stop if [ ${pid} ] then echo "停止程序失敗,無法啟動" else echo "啟動程序---------------------------------------------" #選擇語言類型 read -p "輸入程序類型(java,javac,netcore),下一步按回車鍵(默認:${languagetype}):" read_languagetype if [ ${read_languagetype} ] then languagetype=${read_languagetype} fi echo "選擇程序類型:${languagetype}" #進入運行包目錄 cd ${basedirpath}/${basezipname} #分類啟動 if [ "${languagetype}" == "javac" ] then if [ ${mainclass} ] then nohup java -cp conf:lib\*.jar:${packagename}.jar ${mainclass} >${basedirpath}/${packagename}.out 2 >& 1 & #nohup java -cp conf:lib\*.jar:${packagename}.jar ${mainclass} >/dev/ null 2 >& 1 & fi elif [ "${languagetype}" == "java" ] then nohup java -jar ${basedirpath}/${basezipname}/${packagename}.jar >/dev/ null 2 >& 1 & # java -jar ${basedirpath}/${basezipname}/${packagename}.jar elif [ "${languagetype}" == "netcore" ] then #nohup dotnet run ${basedirpath}/${basezipname}/${packagename} >/dev/ null 2 >& 1 & nohup ${basedirpath}/${basezipname}/${packagename} >/dev/ null 2 >& 1 & fi #查詢是否有啟動進程 getpid if [ ${pid} ] then echo "已啟動" #nohup日志 tail -n 50 -f ${basedirpath}/${packagename}.out else echo "啟動失敗" fi fi } #停止程序 function stop() { getpid if [ ${pid} ] then echo "停止程序---------------------------------------------" kill - 9 ${pid} getpid if [ ${pid} ] then #stop echo "停止失敗" else echo "停止成功" fi fi } #啟動時帶參數,根據參數執行 if [ ${#} -ge 1 ] then case ${ 1 } in "start" ) start ;; "restart" ) start ;; "stop" ) stop ;; "unzip" ) #執行解壓 shenniu_unzip #執行啟動 start ;; *) echo "${1}無任何操作" ;; esac else echo " command如下命令: unzip:解壓并啟動 start:啟動 stop:停止進程 restart:重啟 示例命令如:./shenniu_publish start " fi |
正如上面小節說的,shell中的參數 package-name,activeprofile,boot-main 都是由mvn中profiles的properties中提供,是可變的參數,腳本代碼本身不需要人工去修改,只需要變的是mvn的參數即可;其實在我們生成zip包的時候,shell中的參數就被替換了,可以看zip中shell文件內容如:
linux上使用shenniu_publish.sh啟動程序
把生成的zip上傳到linux上,通過命令解壓:
1
|
unzip -od eureka-server- 0.0 . 1 -node eureka-server- 0.0 . 1 -node.zip |
其實shell腳本中包含有解壓命令,但是我在打包時放在了zip中,所以只能通過手動解壓了,當然可以調整;此時進入加壓目錄如此:
注:這里第一次執行./shenniu_publish.sh腳本時候,提示了錯誤信息;是由于我是在windows上編輯的這個腳本,其空格等和linux上不一樣,所以運行會有問題,要解決可以使用vim命令在linux把該文件轉成linux格式,如下命令:
1
2
3
|
vim shenniu_publish.sh set ff=unix :wq |
執行完后,再來運行腳本./shenniu_publish.sh,此時有如下提示:
此刻我們文件是解壓狀態,因此只需要start命令啟動程序即可:
到這里shenniu_publish.sh腳本使用就完成了,只要腳本沒有提示錯誤,基本都能啟動jar服務;其他restart和stop命令也如此執行就行:
可以去研究下shell代碼,希望該腳本能給你帶來效率和好的學習思路,下面是測試用例git地址,腳本在eureka-server項目中:https://github.com/shenniubuxing3/springcloud-finchley.sr2
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對服務器之家的支持。
原文鏈接:http://www.cnblogs.com/wangrudong003/p/10502043.html