Spring Boot 项目打包 + Shell 脚本部署实践,太有用了!

3 node

6 node

7 ${scripts_packageName}

8 ${scripts_bootMain}

10 

11 true

12 

13 

14 

15 node1

16 

17 node1

18 ${scripts_packageName}

19 ${scripts_bootMain}

20 

21 

22 

23 node2

24 

25 node2

26 ${scripts_packageName}

27 ${scripts_bootMain}

28 

29 

30 

节点粗解:

id:用来指定不同环境配置文件所在的目录,如下我这里:

img

properties:该节点中的节点是可作为参数传递给其他配置文件,如我这里的package-name节点值就可以在另外的assembly.xml或者shell脚本文件中通过${package-name}获取到,如下:

img

activeByDefault:指定默认环境配置文件夹

maven-assembly-plugin打发布压缩包

对于springboot程序打包,可以分为jar和war,这里是jar包;有场景是咋们配置文件或者第三方等依赖包不想放到工程jar中,并且把这些文件压缩成一个zip包,方便上传到linux;此时通过maven-assembly-plugin和maven-jar-plugin就可以做到,mvn的配置如:

2 org.apache.maven.plugins

3 maven-jar-plugin

4 2.6

7 false

9 true

10 lib/

11 ${scripts_bootMain}

12 

13 

14 

15 

16 **/*.yml

17 **/*.properties

18 **/*.xml

19 **/*.sh

20 

21 

22 

23 

24 make-a-jar

25 compile

26 

27 jar

28 

29 

30 

31 

32

33 

34 org.apache.maven.plugins

35 maven-assembly-plugin

36 2.4

37 

38 

39 

40 

41 ${project.basedir}/src/main/assembly/assembly.xml

42 

43 

44 

45 

46 make-assembly

47 package

48 

49 single

50 

51 

52 

53 

值得注意的地方如下几点:

  • mainClass节点:用来指定启动main函数入口类路径,如这里的:com.sm.EurekaServerApplication

  • excludes节点:排除主jar包中配置等一些列后缀文件,因为我们要包这些配置文件放到主包外面

  • descriptor节点:用来指定assembly插件对应的assembly.xml配置文件

有了上面mvn配置,我们还需要assembly.xml的配置,这里提取了结合shell脚本发布程序的配置:

<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 ">

${activeProfile}

zip

false

false

p a c k a g e − n a m e − {package-name}- packagename{activeProfile}/lib

false

p r o j e c t . b a s e d i r / s r c / m a i n / p r o f i l e s / {project.basedir}/src/main/profiles/ project.basedir/src/main/profiles/{activeProfile}

p a c k a g e − n a m e − {package-name}- packagename{activeProfile}/conf

**/*

${project.basedir}/src/main/scripts

**/*

777

777

true

${project.build.directory}

p a c k a g e − n a m e − {package-name}- packagename{activeProfile}/

*.jar

重点节点介绍:

  • formats节点:把配置文件和jar包等压缩成什么文件格式,这里可以有:zip,tar等

  • fileMode节点:指定scripts目录下脚本文件(这里是:shenniu_publish.sh)在linux上文件权限为777

  • filtered节点:脚本中参数变量为pom的profiles中properties的值(该配置,是把mvn中属性值映射生成到sh文件中,如:${package-name})

完成上面配置后,此时我们可以通过idea上勾选切换不同环境来打zip包,如图:

img

分享shenniu_publish.sh程序启动工具

上面步骤完成了zip格式的发布包,我们再分享下启动程序的shell脚本,该脚本具有的功能如:

  • 解压zip+启动jar包

  • 启动jar包

  • 停止对应jar运行

  • 重启jar程序

目前该shell中封装了两种启动jar命令的方式:

  • java -cp

  • java -jar

如图命令格式:

img

来看全部的shell代码:

#!/usr/bin/env bash

#可变参数变量

languageType=“javac” #支持 java,javac,netcore 发布

#参数值由pom文件传递

baseZipName=“ p a c k a g e − n a m e − {package-name}- packagename{activeProfile}” #压缩包名称 publish-test.zip的publish

packageName=“${package-name}” #命令启动包名 xx.jar的xx

mainclass="KaTeX parse error: Expected 'EOF', got '#' at position 14: {boot-main}" #̲java -cp启动时,指定m…{packageName}.jar ${mainclass}

#例子

# baseZipName=“publish-test” #压缩包名称 publish-test.zip的publish

# packageName=“publish” #命令启动包名 publish.jar的xx

#固定变量

basePath=$(cd dirname $0/; pwd)

baseZipPath=“ b a s e P a t h / {basePath}/ basePath/{baseZipName}.zip”  #压缩包路径

baseDirPath=“${basePath}” #解压部署磁盘路径

pid= #进程pid

#解压

function shenniu_unzip()

{

echo “解压---------------------------------------------”

echo “压缩包路径:${baseZipPath}”

if [ ! find ${baseZipPath} ]

then

echo “不存在压缩包:${baseZipPath}”

else

echo “解压磁盘路径: b a s e D i r P a t h / {baseDirPath}/ baseDirPath/{baseZipName}”

echo “开始解压…”

#解压命令

unzip -od  b a s e D i r P a t h / {baseDirPath}/ baseDirPath/{baseZipName} ${baseZipPath}

#设置执行权限

chmod +x  b a s e D i r P a t h / {baseDirPath}/ 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  b a s e D i r P a t h / {baseDirPath}/ baseDirPath/{baseZipName}

#分类启动

if [ “${languageType}” == “javac” ]

then

if [ ${mainclass} ]

then

nohup java -cp conf:lib*.jar: p a c k a g e N a m e . j a r   {packageName}.jar  packageName.jar {mainclass} > b a s e D i r P a t h / {baseDirPath}/ baseDirPath/{packageName}.out 2>&1 &

#nohup java -cp conf:lib*.jar: p a c k a g e N a m e . j a r   {packageName}.jar  packageName.jar {mainclass} >/dev/null 2>&1 &

fi

elif [ “${languageType}” == “java” ]

then

nohup java -jar  b a s e D i r P a t h / {baseDirPath}/ baseDirPath/{baseZipName}/${packageName}.jar >/dev/null 2>&1 &

# java -jar  b a s e D i r P a t h / {baseDirPath}/ baseDirPath/{baseZipName}/${packageName}.jar

elif [ “${languageType}” == “netcore” ]

then

#nohup dotnet run  b a s e D i r P a t h / {baseDirPath}/ baseDirPath/{baseZipName}/${packageName} >/dev/null 2>&1 &

nohup  b a s e D i r P a t h / {baseDirPath}/ baseDirPath/{baseZipName}/${packageName} >/dev/null 2>&1 &

fi

#查询是否有启动进程

getPid

最后

分享一套我整理的面试干货,这份文档结合了我多年的面试官经验,站在面试官的角度来告诉你,面试官提的那些问题他最想听到你给他的回答是什么,分享出来帮助那些对前途感到迷茫的朋友。

面试经验技巧篇
  • 经验技巧1 如何巧妙地回答面试官的问题
  • 经验技巧2 如何回答技术性的问题
  • 经验技巧3 如何回答非技术性问题
  • 经验技巧4 如何回答快速估算类问题
  • 经验技巧5 如何回答算法设计问题
  • 经验技巧6 如何回答系统设计题
  • 经验技巧7 如何解决求职中的时间冲突问题
  • 经验技巧8 如果面试问题曾经遇见过,是否要告知面试官
  • 经验技巧9 在被企业拒绝后是否可以再申请
  • 经验技巧10 如何应对自己不会回答的问题
  • 经验技巧11 如何应对面试官的“激将法”语言
  • 经验技巧12 如何处理与面试官持不同观点这个问题
  • 经验技巧13 什么是职场暗语

面试真题篇
  • 真题详解1 某知名互联网下载服务提供商软件工程师笔试题
  • 真题详解2 某知名社交平台软件工程师笔试题
  • 真题详解3 某知名安全软件服务提供商软件工程师笔试题
  • 真题详解4 某知名互联网金融企业软件工程师笔试题
  • 真题详解5 某知名搜索引擎提供商软件工程师笔试题
  • 真题详解6 某初创公司软件工程师笔试题
  • 真题详解7 某知名游戏软件开发公司软件工程师笔试题
  • 真题详解8 某知名电子商务公司软件工程师笔试题
  • 真题详解9 某顶级生活消费类网站软件工程师笔试题
  • 真题详解10 某知名门户网站软件工程师笔试题
  • 真题详解11 某知名互联网金融企业软件工程师笔试题
  • 真题详解12 国内某知名网络设备提供商软件工程师笔试题
  • 真题详解13 国内某顶级手机制造商软件工程师笔试题
  • 真题详解14 某顶级大数据综合服务提供商软件工程师笔试题
  • 真题详解15 某著名社交类上市公司软件工程师笔试题
  • 真题详解16 某知名互联网公司软件工程师笔试题
  • 真题详解17 某知名网络安全公司校园招聘技术类笔试题
  • 真题详解18 某知名互联网游戏公司校园招聘运维开发岗笔试题

资料整理不易,点个关注再走吧
“激将法”语言

  • 经验技巧12 如何处理与面试官持不同观点这个问题
  • 经验技巧13 什么是职场暗语

[外链图片转存中…(img-QD1VzfQ0-1718717063547)]

面试真题篇
  • 真题详解1 某知名互联网下载服务提供商软件工程师笔试题
  • 真题详解2 某知名社交平台软件工程师笔试题
  • 真题详解3 某知名安全软件服务提供商软件工程师笔试题
  • 真题详解4 某知名互联网金融企业软件工程师笔试题
  • 真题详解5 某知名搜索引擎提供商软件工程师笔试题
  • 真题详解6 某初创公司软件工程师笔试题
  • 真题详解7 某知名游戏软件开发公司软件工程师笔试题
  • 真题详解8 某知名电子商务公司软件工程师笔试题
  • 真题详解9 某顶级生活消费类网站软件工程师笔试题
  • 真题详解10 某知名门户网站软件工程师笔试题
  • 真题详解11 某知名互联网金融企业软件工程师笔试题
  • 真题详解12 国内某知名网络设备提供商软件工程师笔试题
  • 真题详解13 国内某顶级手机制造商软件工程师笔试题
  • 真题详解14 某顶级大数据综合服务提供商软件工程师笔试题
  • 真题详解15 某著名社交类上市公司软件工程师笔试题
  • 真题详解16 某知名互联网公司软件工程师笔试题
  • 真题详解17 某知名网络安全公司校园招聘技术类笔试题
  • 真题详解18 某知名互联网游戏公司校园招聘运维开发岗笔试题

[外链图片转存中…(img-26f1l8Gi-1718717063548)]

资料整理不易,点个关注再走吧

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值