本篇和大家分享的是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脚本部署的更多相关文章

  1. SpringBoot实现多环境配置

    1.为什么需要配置多环境配置 在实际的开发中,我们往往需要在不同的环境中使用不同的数据库.缓存配置,如果使用同一套配置文件,在不同环境部署的时候手动去修改配置文件,会使部署变得很繁琐.使用多环境配置文 ...

  2. 通过maven profile 打包指定环境配置

    背景 最近换了个新公司接手了一个老项目,然后比较坑的是这个公司的项目都没有没有做多环境打包配置,每次发布一个环境都要手动的去修改配置文件.今天正好有空就来配置下. 解决这个问题的方式有很多,我这里挑选 ...

  3. Springboot 实现多环境配置

    多环境配置 我们在开发Spring Boot应用时,通常同一套程序会被应用和安装到几个不同的环境,比如:开发.测试.生产等.其中每个环境的数据库地址.服务器端口等等配置都会不同,如果在为不同环境打包时 ...

  4. SpringBoot Profiles 多环境配置及切换

    目录 前言 默认环境配置 多环境配置 多环境切换 小结 前言 大部分情况下,我们开发的产品应用都会根据不同的目的,支持运行在不同的环境(Profile)下,比如: 开发环境(dev) 测试环境(tes ...

  5. 安装 LAMP 环境(yum 版本) shell脚本

    #!/bin/bash # 安装 LAMP 环境(yum 版本) # 本脚本适用于 RHEL7(RHEL6 中数据库为 mysql) yum makecache &>/dev/null ...

  6. linux环境下编写shell脚本实现启动停止tomcat服务

    第一步:以管理员的身份进入控制台,在指定目录下新建一个shell脚本,我这里命名为tomcat.sh 第二步:编写shell脚本 #!/bin/bash tomcat_home=/usr/tomcat ...

  7. shell脚本部署redis以及redis主从复制和redis-cluster集群

    # 关于脚本: # 使用root用户执行此脚本,提前关闭selinux: # 执行脚本之前,hostsIP内的IP修改成自己的机器IP: # hostsIp内的IP数量如果有增加或者减少,for循环的 ...

  8. 解决Jenkins用shell脚本部署后,Jenkins自动杀掉启衍生出来的守护进程

    Jenkins部署java项目遇到的问题: 1.Jenkins执行构建后,需要手动执行startup.sh,站点才能正常访问 产生原因: shell脚本发布时,会衍生进程,Jenkins默认会自动杀掉 ...

  9. 张高兴的 .NET Core IoT 入门指南:(一)环境配置、Blink、部署

    如何在 Raspberry Pi 的 Raspbian 上构建使用 GPIO 引脚的 IoT 程序?你可能会回答使用 C++ 或 Python 去访问 Raspberry Pi 的引脚.现在,C# 程 ...

随机推荐

  1. JavaScript设计模式 Item 2 -- 接口的实现

    1.接口概述 1.什么是接口? 接口是提供了一种用以说明一个对象应该具有哪些方法的手段.尽管它可以表明这些方法的语义,但它并不规定这些方法应该如何实现. 2. 接口之利 促进代码的重用. 接口可以告诉 ...

  2. celery学习笔记2

    1.定义: Celery是一个异步的任务队列(也叫做分布式任务队列) 2.工作结构 Celery分为3个部分 (1)worker部分负责任务的处理,即工作进程(我的理解工作进程就是你写的python代 ...

  3. Python常用算法(二)

    1.快速排序 过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小 一般选取第一个数作为关键数据k,我们要把比k小的所有数据移到它的左面,从后往前找第一个比它 ...

  4. 解锁 vmware esxi 6.7 并安装 mac os 10.13

    1.安装 esxi 6.7 2.下载 unlocker 2.1.1.zip 3.上传 unlocker 2.1.1.zip esxi的磁盘中 4.开启esxi的ssh登录 5.使用 ssh 登录 es ...

  5. 【莫比乌斯反演】BZOJ3309 DZY Loves Math

    Description 对于正整数n,定义f(n)为n所含质因子的最大幂指数.例如f(1960)=f(2^3 * 5^1 * 7^2)=3, f(10007)=1, f(1)=0. 给定正整数a,b, ...

  6. laravel 中的rbac自己简单的实现

    用户表 CREATE TABLE `sys_user` ( `id` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '用户编号', `ids` int(1 ...

  7. 设置yum源:

    1.企业    阿里开源镜像站:   http://mirrors.aliyun.com/ 搜狐开源镜像站: http://mirrors.sohu.com/ 网易开源镜像站: http://mirr ...

  8. ServletContextListener

    在 Servlet API 中有一个 ServletContextListener 接口,它能够监听 ServletContext 对象的生命周期,实际上就是监听 Web 应用的生命周期. 当Serv ...

  9. Python多版本管理-pyenv

    经常遇到这样的情况: 系统自带的Python是2.x,自己需要Python 3.x,此时需要在系统中安装多个Python,但又不能影响系统自带的Python,即需要实现Python的多版本共存,pye ...

  10. Netty基础系列(1) --linux网路I/O模型

    引言 我一直认为对于java的学习,掌握基础的性价比要远远高于使用框架,而基础知识中对于网络相关知识的掌握也是重中之重.对于一个java程序来说,无论是工作中还是面试,对于Netty的掌握都是及其重要 ...