最近公司开发新项目,原来使用的docker部署,且由外部团队负责。这次想自己内部负责运维和部署,于是选择了使用java jar包
的方式直接部署,由于没有相关经验,所以自己从网上查了一些资料(见文章末尾)。
理想方案
Springboott默认读取核心配置文件(application.properties/application.yml)的优先级为
还有一种最高优先级的方式是项目启动时通过命令的方式指定项目加载核心配置文件,命令如下
java –jar -Dspring.config.location=xxx/xxx/xxxx.properties xxxx.jar
如果Spring Boot在优先级更高的位置找到了配置,那么它会无视优先级更低的配置
其他一些的配置文件,如数据源配置文件,公共资源定义配置文件(常量,FTP信息等),quartz定时器,日志等配置文件也放到jar外。
Springboot项目可以通过注解方式来获取相关配置文件,所以我们也是通过注解方式让项目能够引用到jar包外部的配置文件的,如下图:
@PropertySource里面的value有两个值,第一个是classpath下config目录下的数据源配置文件,第二个则是根据spring.profiles.path动态获取的目录,spring.profiles.path是我们在核心文件自定义的一个配置项,它的值是我们配置文件统一管理的文件夹路径,后面的ignoreResourceNotFound=true则是设定假如根据前面一个路径没有找到相关配置文件,则根据第二个路径去找。
可以在springboot配置文件中指定加载logback日志配置文件:
logging:
config: config/logback.xml
pom文件中修改打包设置
<build>
<resources>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>truefiltering>
resource>
<resource>
<directory>src/main/resourcesdirectory>
<excludes>
<exclude>**/*.propertiesexclude>
<exclude>**/*.xmlexclude>
<exclude>**/*.ymlexclude>
excludes>
<filtering>falsefiltering>
resource>
resources>
<plugins>
<plugin>
<artifactId>maven-jar-pluginartifactId>
<configuration>
<archive>
<manifest>
<addClasspath>trueaddClasspath>
<classpathPrefix>lib/classpathPrefix>
<useUniqueVersions>falseuseUniqueVersions>
<mainClass>com.xrq.demo.ApplicationmainClass>
manifest>
<manifestEntries>
<Class-Path>./Class-Path>
manifestEntries>
archive>
<excludes>
<exclude>*.propertiesexclude>
<exclude>*.ymlexclude>
<exclude>*.xmlexclude>
<exclude>config/**exclude>
excludes>
configuration>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-dependency-pluginartifactId>
<executions>
<execution>
<id>copyid>
<phase>packagephase>
<goals>
<goal>copy-dependenciesgoal>
goals>
<configuration>
<outputDirectory>
${project.build.directory}/lib
outputDirectory>
configuration>
execution>
executions>
plugin>
plugins>
build>
这样打包时jar会排除配置文件,单独在目录下生成lib文件夹放第三方依赖库
改好pom.xml的build模块后,就可以通过mvn package 或者mvn install打出我们的jar包了
启动命令示例
nohup java -Xms500m -Xmx500m -Xmn250m -Xss256k -server -XX:+HeapDumpOnOutOfMemoryError -jar $JAR_PATH/test-0.0.1-SNAPSHOT.jar --spring.profiles.active=daily -verbose:class &
说明:
nohup command &
nohup command >/dev/null 2>&1 &
/dev/null 2>&1。这条命令其实分为两命令,一个是>/dev/null,另一个是2>&1。
1. /dev/null
这条命令的作用是将标准输出1重定向到/dev/null中。/dev/null代表linux的空设备文件,所有往这个文件里面写入的内容都会丢失,俗称“黑洞”。那么执行了>/dev/null之后,标准输出就会不再存在,没有任何地方能够找到输出的内容。
2. 2>&1
这条命令用到了重定向绑定,采用&可以将两个输出绑定在一起。这条命令的作用是错误输出将和标准输出同用一个文件描述符,说人话就是错误输出将会和标准输出输出到同一个地方。
linux在执行shell命令之前,就会确定好所有的输入输出位置,并且从左到右依次执行重定向的命令,所以>/dev/null 2>&1的作用就是让标准输出重定向到/dev/null中(丢弃标准输出),然后错误输出由于重用了标准输出的描述符,所以错误输出也被定向到了/dev/null中,错误输出同样也被丢弃了。执行了这条命令之后,该条shell命令将不会输出任何信息到控制台,也不会有任何信息输出到文件中。
>/dev/null 2>&1 VS 2>&1 >/dev/null
乍眼看这两条命令貌似是等同的,但其实大为不同。刚才提到了,linux在执行shell命令之前,就会确定好所有的输入输出位置,并且从左到右依次执行重定向的命令。那么我们同样从左到右地来分析2>&1 >/dev/null:
2>&1,将错误输出绑定到标准输出上。由于此时的标准输出是默认值,也就是输出到屏幕,所以错误输出会输出到屏幕。
>/dev/null,将标准输出1重定向到/dev/null中。
我们用一个表格来更好地说明这两条命令的区别:
命令 | 标准输出 | 错误输出 |
---|---|---|
>/dev/null 2>&1 | 丢弃 | 丢弃 |
2>&1 >/dev/null | 丢弃 | 屏幕 |
1.nohup
用途:不挂断地运行命令。
语法:nohup Command [ Arg … ] [ & ]
无论是否将 nohup 命令的输出重定向到终端,输出都将附加到当前目录的 nohup.out 文件中。 如果当前目录的 nohup.out
文件不可写,输出重定向到 $HOME/nohup.out 文件中。 如果没有文件能创建或打开以用于追加,那么 Command
参数指定的命令不可调用。
退出状态:
该命令返回下列出口值:
126 可以查找但不能调用 Command 参数指定的命令。
127 nohup 命令发生错误或不能查找由 Command参数指定的命令。否则,nohup 命令的退出状态是 Command 参数指定命令的退出状态。
2.&
用途:在后台运行,一般两个一起用
#!/bin/bash
APPNAME=$2
ARTIFACT=$3
VERSION=$4
usage() {
echo "Usage: sh 执行脚本.sh [start|stop|restart|status] jar名称 开发环境(DEV,UAT, PRO)"
exit 1
}
#检查程序是否在运行
is_exist(){
pid=`ps -ef|grep $APPNAME/$ARTIFACT-$VERSION|grep -v grep|awk '{print $2}'`
#-z 判断pid是否为空
if [ -z "${pid}" ]; then
return 1
else
return 0
fi
}
#启动方法
start(){
is_exist
#$?上一次执行结果
if [ $? -eq "0" ]; then
echo "${ARTIFACT} is already running. pid=${pid} ."
else
nohup java -jar -Duser.timezone=GMT+8 $APPNAME/$ARTIFACT-$VERSION.jar --logging.config=config/logback.xml >> /dev/null 2>&1 &
fi
}
#停止方法
stop(){
is_exist
if [ $? -eq "0" ]; then
kill -9 $pid
echo "$ARTIFACT has been stoped"
else
echo "$ARTIFACT is not running"
fi
}
#输出运行状态
status(){
is_exist
if [ $? -eq "0" ]; then
echo "${ARTIFACT} is running. Pid is ${pid}"
else
echo "${ARTIFACT} is NOT running."
fi
}
#重启
restart(){
stop
start
}
#根据输入参数,选择执行对应方法,不输入则执行使用说明
case "$1" in
"start")
start
;;
"stop")
stop
;;
"status")
status
;;
"restart")
restart
;;
*)
usage
;;
esac
## 启动
sh webserver.sh start micro-serv-training-web micro-serv-training-web 0.0.1-SNAPSHOT
##停止
sh webserver.sh stop micro-serv-training-web micro-serv-training-web 0.0.1-SNAPSHOT
https://blog.csdn.net/baidu_35140444/article/details/82980139
https://blog.csdn.net/xrq0508/article/details/8
https://www.cnblogs.chtom/liaojie970/p/7852977.html0050119
https://blog.csdn.net/nimoyaoww/article/details/79108101