Spring Boot 项目不同环境打包配置与Shell脚本部署实践,太实用了!

>>号外:关注“Java精选”公众号,回复“2021面试题”关键词,领取全套500多份Java面试题文件。

本篇文章和大家分享的是Spring Boot打包并结合Shell脚本命令部署,重点在分享一个shell程序启动工具,希望能便利工作;

  • 个人资料指定不同环境的配置

  • maven-assembly-plugin打发布压缩包

  • 分享shenniu_publish.sh程序启动工具

  • linux上使用shenniu_publish.sh启动程序

个人资料指定不同环境的配置

通常一套程序分为了很多个部署环境:开发,测试,uat,线上等,我们要对这些环境区分配置文件,可以通过两种方式:

  • 通过application.yml中编码指定profile.active = uat方式指定

  • 通过mvn中配置文件来区分不同环境对应的配置文件夹,人工可以手动在idea替换生成不同环境的包(推荐)

这里我们要讲的是第二种,首先在mvn中配置如下内容:

1 <profiles> 
 2 <profile> 
 3 <id> node </ id> 
 4 <properties> 
 5 <!-传递给脚本的参数值-> 
 6 <activeProfile> node </ activeProfile> 
 7 <package-name> $ {scripts_packageName} </ package-name> 
 8 <boot-main> $ {scripts_bootMain} </ boot-main> 
 9 </ properties> 
10 <activation> 
11 <activeByDefault> true </ activeByDefault> 
12 </ activation> 
13 </ profile> 
14 <profile> 
15 <id> node1 </ id> 
16 <properties> 
17 <activeProfile> node1 </ activeProfile> 
18 <程序包名称>$ {scripts_packageName} </ package-name> 
19 <boot-main> $ {scripts_bootMain}</ boot-main> 
20 </ properties> 
21 </ profile> 
22 <profile> 
23 <id> node2 </ id> 
24 <properties> 
25 <activeProfile> node2 </ activeProfile> 
26 <程序包名称> $ { scripts_packageName} </ package-name> 
27 <boot-main> $ {scripts_bootMain} </ boot-main> 
28 </ properties> 
29 </ profile> 
30 </ profiles>

官员粗解:

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

属性:该例程中的例程是可作为参数传递给其他配置文件,如我这里的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 <plugin> 
 2 <groupId> org.apache.maven.plugins </ groupId> 
 3 <artifactId> maven-jar-plugin </ artifactId> 
 4 <version> 2.6 </ version> 
 5 <configuration> 
 6 <archive> 
 7 <addMavenDescriptor>假</ addMavenDescriptor> 
 8 <manifest> 
 9 <addClasspath>真</ addClasspath> 
10 <classpathPrefix> lib / </ classpathPrefix> 
11 <mainClass> $ {scripts_bootMain} </ mainClass> 
12 </ manifest> 
13 < / archive> 
14 <!-打包排除项-> 
15 <excludes> 
16 <exclude> ** / *。yml </ exclude> 
17 <exclude> ** / *。属性</ exclude> 
18 <exclude> ** / *。xml </ exclude> 
19 <exclude> ** / *。sh </ exclude>
20 </ excludes> 
21 </ configuration> 
22 <executions> 
23 <execution> 
24 <id> make -a -jar </ id> 
25 <phase> compile </ phase> 
26 <goals> 
27 <goal> jar < / goal> 
28 </ goals> 
29 </ execution> 
30 </ executions> 
31 </ plugin> 
32 
33 <plugin> 
34 <groupId> org.apache.maven.plugins </ groupId> 
35 <artifactId> maven-assembly -plugin </ artifactId> 
36 <version> 2.4 </ version> 
37 <!-插件的配置-> 
38 <configuration> 
39 <!-指定程序集插件的配置文件->
40 <描述符> 
41 <描述符> $ {project.basedir}/src/main/assembly/assembly.xml </ descriptor> 
42 </ descriptors> 
43 </ configuration> 
44 <executions> 
45 <execution> 
46 <id> make-assembly </ id> 
47 <phase>包</阶段> 
48 <目标> 
49 <目标>单个</目标> 
50 </目标> 
51 </执行> 
52 </执行> 
53 </插件>

如下的地方如下几点:

  • mainClass代理:用于指定启动main函数入口类路径,如此处的:com.sm.EurekaServerApplication

  • 不包括摘要:排除主罐包中配置等一些列后缀文件,因为我们要包这些配置文件放到主包外面

  • 描述符描述符:用于指定程序集插件对应的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“ > 
    <id > $ {activeProfile} </ id> 
    <!-打包成一个用于发布的zip文件-> 
    <formats> 
        <format> zip </ format> 
    </ formats> 
    <!- true:zip中生成一级目录(此处屏蔽,配合脚本需要profiles后缀)-> 
    <includeBaseDirectory> false </ includeBaseDirectory> 
    <dependencySets>
        <dependencySet>
            <!-打包进来的zip文件的lib目录-> 
            <useProjectArtifact>假</ useProjectArtifact> 
            <outputDirectory> $ {package-name} - $ {activeProfile} / lib </ outputDirectory> 
            <unpack> false </ unpack> 
        </ dependencySet> 
    </ dependencySets> 

    <fileSets> 
        <!-配置文件打包进zip文件的配置目录-> 
        <fileSet> 
            <目录> $ {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> 
            <目录> $ {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>

重点介绍:

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

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

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

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

分享shenniu_publish.sh程序启动工具

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

  • 解压zip +启动jar包

  • 启动jar包

  • 停止对应jar运行

  • 重启jar程序

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

  • java -cp

  • java -jar

如命令格式:

来看全部的shell代码:

#!/ usr / bin / env bash 
#可变参数变量
languageType = “ javac”  #支持java,javac,netcore发布
#参数值由pom文件传递
baseZipName = “” $ {package-name} - $ {activeProfile} “  #压缩包名称publish-test.zip的
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的发布
#packageName =“ publish”。罐子的XX 

#固定变量
基本路径= $(光盘 `目录名称 $ 0`/; pwd)
baseZipPath = “” $ {basePath} / $ {baseZipName} .zip“   #压缩包路径
baseDirPath = ”“ $ {basePath} ”  #解压部署磁盘路径
pid =  #进程pid 

#解压
功能 shenniu_unzip()
{ 
    echo  “解压- --------------------------------------------“ 
    echo  ”压缩包路径:$ {baseZipPath} “
    如果 [!`find  $ {baseZipPath} `]
    然后
        回显 “不存在压缩包:$ {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}  ]
    然后
        回显 “运行pid:$ {pid} ” 
    else 
        echo  “未运行” 
    fi
 } 

#启动程序
function  start()
{ 
    #启动前,先停止之前的
    stop 
    if  [  $ {pid}  ] 
    then 
        echo  “停止程序失败,无法启动“ 
    else 
        echo  ”启动程序-------------------------------------------- -“ 

        #选择语言类型
        read  -p  ”输入程序类型(java,javac,netcore),继续按回车键(要么:$ {languageType}):“  read_languageType
        如果 [  $ {read_languageType}  ]
        则
            languageType = $ { read_languageType} 
        fi
        echo  “选择程序类型:$ {languageType} ” 

        #进入运行包目录
        cd  $ {baseDirPath} / $ {baseZipName} 

        #分类启动
        if  [  “ $ {languageType} ”  ==  “ javac”  ]
        则
            if  [  $ {mainclass}  ]
            然后
                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&
            音响
        的elif  [  “$ {languageType} “  ==  ” java“  ]
        然后
            nohup java -jar  $ {baseDirPath} / $ {baseZipName} / $ {packageName} .jar> / dev / null 2>&1&
            #java -jar $ {baseDirPath} / $ {baseZipName} / $ {packageName} .jar 
        elif  [  “ $ {languageType} ”  ==  “ netcore”  ]
        然后
            #nohup dotnet运行$ {baseDirPath} / $ {baseZipName} / $ {packageName}> / dev / null 2 >&1&
             nohup  $ {baseDirPath} / $ {baseZipName} / $ {packageName}  > / dev / null 2>&1&
        fi 

        #查询是否有启动进度
        getPid
        如果 [  $ {PID}  ]
        然后
            回声 “已启动” 
            #nohup日志
            尾-n 50 -f  $ {baseDirPath} / $ {的packageName} .OUT
        别的
            回声 “启动失败”
        科幻
    音响
} 

#停止程序
功能 停止()
{ 
    getPid 
    if  [  $ {pid}  ]
    然后
        回显 “停止程序------------------------------------- --------“ 
        kill  -9  $ {pid}

         getPid
        如果 [  $ {pid}  ]
        则
            #stop 
            echo  ”停止失败“
        else 
            echo  “停止成功” 
        fi 
    fi
 } 

#启动时带参数,根据参数执行
if  [  $ {#}  -ge 1]
然后
    case  $ {1}  in 
        “ start”)
            start 
        ;; 
        “ restart”)
            开始
        ;; 
        “ stop”)
            停止
        ;; 
        “ unzip”)
            #执行解压
            shenniu_unzip 
            #执行启动
            start 
        ;; 
        *)
            echo  “ $ {1}无任何操作”
         ;;
    

     
    command如下命令:
    解压缩:解压并启动
    start:启动
    stop:停止进程
    重启:重启

    示例命令如:./ shenniu_publish start 
    “ 
fi

正如上面小节说的,shell中的参数软件包名称,activeProfile,boot-main都是由mvn中profiles的属性中提供,是可变的参数,脚本代码本身不需要人工去修改,只需要变的是mvn的参数即可;其实在我们生成zip包的时候,shell中的参数就被替换了,可以看zip中shell文件内容如:

把生成的zip上传到linux上,通过命令解压:

1解压缩-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 vim shenniu_publish.sh 
2 设置 ff = unix 
3:wq

执行完后,再来运行脚本./shenniu_publish.sh,此时有如下提示:

此刻我们文件是解压状态,因此只需要启动命令启动程序即可:

到这里shenniu_publish.sh脚本使用就完成了,只要脚本没有提示错误,基本都能启动jar服务;其他重新启动和停止命令也如此执行就行:

可以去研究下shell代码,希望该脚本能给你带来效率和好的学习思路,下面是测试用例git地址,脚本在eureka-server项目中:https://github.com/shenniubuxing3/springcloud-Finchley .SR2

作者:Flag Counter

cnblogs.com/wangrudong003/p/10502043.html

往期精选  点击标题可跳转

Spring boot 项目中如何优雅停止服务的五种方法,值得收藏!

Java 中什么是 IO 流,字节流、字符流两者区别,缓冲流原理代码剖析

你可能忽视的 MyBatis 3.5.X 在 JDK8 中存在的性能问题

复盘 Spring boot 中定时任务如何启用异步线程池

Spring Boot 框架中使用自定义注解 + 拦截器实现身份证等敏感数据加解密

Java 中处理 Exception 的 9 种实践,曾被很多团队认可采纳,值得收藏!

Java 中 ThreadPoolExecutor 线程池必备知识点:工作流程、常见参数、性能调优及监控

Java 中统计代码执行耗时,列举 4 种优雅的解决方案

MySQL 分页使用 limit 和 offset 参数为什么会导致执行变慢?

全网可能是最全的 JAVA 日志框架适配、冲突解决方案

数据库在哪些场景下导致索引失效,索引何时会失效?

点个赞,就知道你“在看”!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值