springboot打包不同环境配置与shell脚本部署
本篇和大家分享的是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中配置如下内容:
<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的配置如:
<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脚本发布程序的配置:
<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></fileMode>
<!-- 目录权限为777 -->
<directoryMode></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 -cp
- java -jar
如图命令格式:

来看全部的shell代码:
#!/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 $`/; 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 >& &
#nohup java -cp conf:lib\*.jar:${packageName}.jar ${mainclass} >/dev/null >& &
fi
elif [ "${languageType}" == "java" ]
then
nohup java -jar ${baseDirPath}/${baseZipName}/${packageName}.jar >/dev/null >& &
# java -jar ${baseDirPath}/${baseZipName}/${packageName}.jar
elif [ "${languageType}" == "netcore" ]
then
#nohup dotnet run ${baseDirPath}/${baseZipName}/${packageName} >/dev/null >& &
nohup ${baseDirPath}/${baseZipName}/${packageName} >/dev/null >& &
fi #查询是否有启动进程
getPid
if [ ${pid} ]
then
echo "已启动"
#nohup日志
tail -n -f ${baseDirPath}/${packageName}.out
else
echo "启动失败"
fi
fi
} #停止程序
function stop()
{
getPid
if [ ${pid} ]
then
echo "停止程序---------------------------------------------"
kill - ${pid} getPid
if [ ${pid} ]
then
#stop
echo "停止失败"
else
echo "停止成功"
fi
fi
} #启动时带参数,根据参数执行
if [ ${#} -ge ]
then
case ${} 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上,通过命令解压:
unzip -od eureka-server-0.0.-node eureka-server-0.0.-node.zip
其实shell脚本中包含有解压命令,但是我在打包时放在了zip中,所以只能通过手动解压了,当然可以调整;此时进入加压目录如此:

注:这里第一次执行./shenniu_publish.sh脚本时候,提示了错误信息;是由于我是在windows上编辑的这个脚本,其空格等和linux上不一样,所以运行会有问题,要解决可以使用vim命令在linux把该文件转成linux格式,如下命令:
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
springboot打包不同环境配置与shell脚本部署的更多相关文章
- SpringBoot实现多环境配置
1.为什么需要配置多环境配置 在实际的开发中,我们往往需要在不同的环境中使用不同的数据库.缓存配置,如果使用同一套配置文件,在不同环境部署的时候手动去修改配置文件,会使部署变得很繁琐.使用多环境配置文 ...
- 通过maven profile 打包指定环境配置
背景 最近换了个新公司接手了一个老项目,然后比较坑的是这个公司的项目都没有没有做多环境打包配置,每次发布一个环境都要手动的去修改配置文件.今天正好有空就来配置下. 解决这个问题的方式有很多,我这里挑选 ...
- Springboot 实现多环境配置
多环境配置 我们在开发Spring Boot应用时,通常同一套程序会被应用和安装到几个不同的环境,比如:开发.测试.生产等.其中每个环境的数据库地址.服务器端口等等配置都会不同,如果在为不同环境打包时 ...
- SpringBoot Profiles 多环境配置及切换
目录 前言 默认环境配置 多环境配置 多环境切换 小结 前言 大部分情况下,我们开发的产品应用都会根据不同的目的,支持运行在不同的环境(Profile)下,比如: 开发环境(dev) 测试环境(tes ...
- 安装 LAMP 环境(yum 版本) shell脚本
#!/bin/bash # 安装 LAMP 环境(yum 版本) # 本脚本适用于 RHEL7(RHEL6 中数据库为 mysql) yum makecache &>/dev/null ...
- linux环境下编写shell脚本实现启动停止tomcat服务
第一步:以管理员的身份进入控制台,在指定目录下新建一个shell脚本,我这里命名为tomcat.sh 第二步:编写shell脚本 #!/bin/bash tomcat_home=/usr/tomcat ...
- shell脚本部署redis以及redis主从复制和redis-cluster集群
# 关于脚本: # 使用root用户执行此脚本,提前关闭selinux: # 执行脚本之前,hostsIP内的IP修改成自己的机器IP: # hostsIp内的IP数量如果有增加或者减少,for循环的 ...
- 解决Jenkins用shell脚本部署后,Jenkins自动杀掉启衍生出来的守护进程
Jenkins部署java项目遇到的问题: 1.Jenkins执行构建后,需要手动执行startup.sh,站点才能正常访问 产生原因: shell脚本发布时,会衍生进程,Jenkins默认会自动杀掉 ...
- 张高兴的 .NET Core IoT 入门指南:(一)环境配置、Blink、部署
如何在 Raspberry Pi 的 Raspbian 上构建使用 GPIO 引脚的 IoT 程序?你可能会回答使用 C++ 或 Python 去访问 Raspberry Pi 的引脚.现在,C# 程 ...
随机推荐
- java处理图片--图片的缩放,旋转和马赛克化
这是我自己结合网上的一些资料封装的java图片处理类,支持图片的缩放,旋转,马赛克化.(转载请注明出处:http://blog.csdn.net/u012116457) 不多说,上代码: packag ...
- 玩转SSH--Hibernate(三)---手动修改数据库,前台查询信息不同步更新问题解决方法
在用hibernate时遇到一个挺纠结的问题,就是我在手动修改数据库的信息后,前台页面查询到的信息还是之前的结果,一开始以为是缓存的问题,经过多次修改和在网上查询资料,最终发现可能是hibernate ...
- C# 操作Word文本框——插入表格/读取表格/删除表格
在文本框中,我们可以操作很多元素,如文本.图片.表格等,在本篇文章中将着重介绍如何插入表格到文本框,插入的表格我们可以对表格进行格式化操作来丰富表格内容.此外,对于文本框中的表格内容,我们也可以根据需 ...
- linux相关命令及配置(四)
Linux第四章课堂笔记一.RPM包管理命令 1.RPM包是本地文件,存在于本地文件中 2.使用RPM命令管理.rpm包 3.挂载光驱 # mount /dev/cdrom /media/ 查看:rp ...
- java面向对象中四种权限(private,protected,public,友好型)详解
转自http://blog.csdn.net/a1237871112/article/details/50926975 及http://blog.csdn.net/blackmanren/articl ...
- fiddler抓包软件的使用--请求头--ajax
User-Agent: FiddlerHost: localhost:49828Content-Length: 0Accept: application/xmlContent-Type: applic ...
- BZOJ_3398_[Usaco2009 Feb]Bullcow 牡牛和牝牛_组合数学
BZOJ_3398_[Usaco2009 Feb]Bullcow 牡牛和牝牛_组合数学 Description 约翰要带N(1≤N≤100000)只牛去参加集会里的展示活动,这些牛可以是牡牛, ...
- [Noi2015]软件包管理器 BZOJ4196
分析:水题 每次安装的时候和根节点求lca的过程中区间覆盖+区间查询 每次删除的时候查询子树中安装的数量+区间覆盖 附上代码: #include <cstdio> #include < ...
- JAVA中正则表达式总结
昨天,我的朋友请教我正则表达式.我也好久没有写过正则表达式了,昨天刚好看了下如鹏网创始人杨中科老师关于正则表达式的讲解.使我加深了正则表达式的印像.现我把他总结下: 许多语言,包括Perl.PHP.P ...
- 磁盘IOPS计算与测量
IOPS (Input/Output Per Second)即每秒的输入输出量(或读写次数),是衡量磁盘性能的主要指标之一.IOPS是指单位时间内系统能处理的I/O请求数量,一般以每秒处理的I/O请求 ...