SpringBoot在Centos(Linux)系统上以init.d即SysVinit(SystemV)守护进程的方式部署项目Jar包

一.引言

在linux系统中,我们通常使用下面指令来部署springboot项目:

nohup java -jar appname.jar --spring.profiles.active=qa > /dev/null 2>&1 & echo $! >"appname.pid"

除了上述使用java -jar的方式部署springboot项目之外,springboot官方文档还提供了另外一种部署方式:使用init.d 或者systemd的方式部署Springboot项目。

使用这种方式部署项目有什么好处呢,可以使用SysVinit/Systemd的管理指令,start,stop,restart,status管理springboot项目,还有提供开机自启的功能,方便在机房停电,或者服务器异常重启后不用手工执行脚本或指令重启服务,使Springboot程序真正意义的安装在linux机器上,作为守护进程运行。

官方文档关于linux上的部署,有专门的篇幅来描述,官方文档链接:https://docs.spring.io/spring-boot/docs/2.2.2.RELEASE/reference/htmlsingle/#deployment-install

 

如文档所述,有init.d以及systemd两种部署方式。本文只讲第一种,以inid.d/System V/SysVinit的方式部署。

二.说明

1.使用这种方式部署springboot项目,实际上是在文件的开头内嵌了额外的脚本,某些工具可能不支持这种格式。这样可能会导致你打包好的jar包无法使用java -jar运行,或者打包好的Jar包无法跑在servlet容器上,例如tomcat。所以,只有当你只打算使用init.d、Systemd部署springboot程序时,才使用这种方式来打包。当然,在某些情况下是支持的,不过风险还是很大,笔者在公司实际运行的项目使用了这种方式打包,结果使用java -jar华丽丽的就跑不起来,但是使用本文中的demo springboot项目却完完全全没问题。

2.这种内嵌的脚本支持大多数的linux发行版,springboot官方在centos和ubuntu上做了测试。本文在centos7.5测试通过。其他平台需要使用embeddedLaunchScript。

三.实战步骤

这里详解官方文档介绍的第一种部署方式:init.d服务(System V)

1.如果你使用maven或者gradle把springboot项目打包成可执行程序,你可以在linux上把它安装成init.d服务,支持标准的start、stop、restart、status命令。

所以首先,需要借助maven,把springboot项目打包成为可执行程序,配置如下

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <executable>true</executable>
    </configuration>
</plugin>

如果使用gradle,等效于

bootJar {
    launchScript()
}

 

2.详细演示:

本文以下述条件在centos7.5的linux机器上做了实验,所以对情景做以下假设:

(1)部署服务器的目录为/data/project/demo

(2)打包后的jar包名称为demo-0.0.1-SNAPSHOT.jar

(3)部署的appname为demo-0.0.1-SNAPSHOT

  (4)  SpringBoot的版本为2.2.2.RELEASE,使用Maven打包,理论上与springboot版本无关,只跟maven打包有关系

init.d部署的步骤如下:

第一步,把第1点列出的maven的配置,配置在springboot的pom文件上,然后执行

mvn clean install

上述maven指令将springboot程序打包(打包指令自己决定即可,以上只是一个例子),本文打包生成了一个demo-0.0.1-SNAPSHOT.jar文件,最后将这个打包后的文件demo-0.0.1-SNAPSHOT.jar文件上传到linux部署服务器上。

上传可以使用scp指令,也可以借助xftp等文件传输工具,详见百度。

第二步,登录服务器,cd /data/project/demo进入文件上传的目录,并确保该jar包权限可以执行,

chmod +x /data/project/demo/demo-0.0.1-SNAPSHOT.jar

执行以上命令赋予jar文件执行权限

第三步,设置短链接

sudo ln -s /data/project/demo/demo-0.0.1-SNAPSHOT.jar /etc/init.d/demo-0.0.1-SNAPSHOT

第四步,这时候已经安装好了,启动服务:

service demo-0.0.1-SNAPSHOT start

第五步,设置开机自动启动服务:

centos系统使用以下指令设置开机自启 :

 chkconfig demo-0.0.1-SNAPSHOT on

关闭开机自启指令:

chkconfig demo-0.0.1-SNAPSHOT off

ubuntu系统使用以下指令开机自启:

update-rc.d demo-0.0.1-SNAPSHOT defaults <priority>

(<priority>是一个优先级,自己设定,没有使用过ubuntu进行过测试,centos指令笔者在centos7.5执行并验证成功)

 

注意:

(1)执行完第三步,springboot程序已经安装好了,这时候已经可以使用init.d服务的指令start,stop,restart,status管理springboot程序的启动,停止,重启,和查看服务的运行状态,并且使用chkconfig指令管理是否开机自启

(2)执行第五步时,如果这时候你同时安装了systemd,会自动转发使用systemd的enable,如果没有安装,则使用chkconfig

(3)如果启动失败,请在默认的控制台输出文件/var/log/demo-0.0.1-SNAPSHOT.log查看错误日志。

 

使用这种方式默认的pid和控制台输出文件:

(1)pid存放位置: /var/run/<appname>/<appname>.pid

(2)控制台输出文件路径:/var/log/<appname>.log

(3)默认读取的配置文件为jar包存放位置的同目录下的<appname>.conf,这里为/data/project/demo/demo-0.0.1-SNAPSHOT.conf,如果需要配置,请自己在该目录创建demo-0.0.1-SNAPSHOT.conf

 

3.相关配置

该init.d服务的配置有以下两种方式,一种是在springboot项目的pom文件里面配置,一种是在<appname>.conf中配置,支持的所有详细配置参见官方文档:https://docs.spring.io/spring-boot/docs/2.2.2.RELEASE/reference/htmlsingle/#deployment-install

英文The following property substitutions are supported with the default script下面的两个表格,第一个表格是maven配置,第二个表格是conf支持的配置。

 

(1)其中maven配置如下

<plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <executable>true</executable>
                    <embeddedLaunchScriptProperties>
                        <!--控制台日志存放的位置,如果配置不存在的目录,则会输出到/tmp目录,
如果想丢弃控制台日志,则logFolder设为/dev,logFilename设为null-->
                        <logFolder>/data/project/demo/log</logFolder>
                        <!--控制台日志文件名-->
                        <logFilename>test.log</logFilename>
                        <!--pid文件存放的位置,实际上存放的目录为/var/run/<appname>,如果目录不存在,则会到/tmp目录
                            会自动创建多一级以项目名命名的目录
                            另外,值得注意的一点就是使用service <appname> stop/restart时
                            会直接读取这个值,如果直接改变,会导致该指令按照该目录+项目名和文件名的位置去查找,
                            找不到pid,导致停止或者重启失败,这时候要么手动执行kill命令,
要么把原先的pid文件拷贝到新指定的目录和文件
                            -->
                        <pidFolder>/var/run</pidFolder>
                        <!--pid文件名-->
                        <pidFilename>demo-0.0.1-SNAPSHOT.pid</pidFilename>
                        <!--指定配置文件的位置,最终读取配置文件的位置为/data/file/<appname>.conf-->
                        <confFolder>/data/file</confFolder>
                        <!--还有一个有用的参数为inlinedConfScript,该参数只接受脚本路径
,不直接支持脚本内容,这里没有去测试-->
                    </embeddedLaunchScriptProperties>
                </configuration>
            </plugin>

 

(2)conf配置

另外还有conf的配置,默认需要配置在jar包的同级目录下,如果使用maven重新指定,就读取maven配置的目录下的<appname>.conf

注意,如果maven的配置与conf的配置冲突,则优先使用conf的配置,两者的配置是取并集,即合集。

如果使用init.d的方式部署服务,则这个配置一定少不了,因为使用这种方式部署springboot服务,java的自定义参数只能在这里定义和配置。如JVM的参数,如Java程序的启动参数,maven方式并不支持,除非自定义内嵌脚本,这种需要自己写脚本,在本文中并没有尝试。

 

demo-0.0.1-SNAPSHOT.conf如下配置:

#jvm启动参数

JAVA_OPTS="-Xmx1024M -Xms1024M"

#springboot java程序启动参数

RUN_ARGS="--spring.profiles.active=pd"

#pid的存放目录,同maven配置描述的,实际目录为PID_FOLDER/<appname>,不配置默认为/var/run

PID_FOLDER=/var/run

#控制台输出日志存放目录,不配置默认为/var/log,如果想丢弃控制台文件,请设置为/dev,LOG_FOLDER设置为null

LOG_FOLDER=/data/project/demo/log

#控制台输出日志文件名

LOG_FILENAME=demo-0.0.1-SHAPSHOT.log

#java指令的位置,默认使用PATH路径来发现,也可以显示指定为$JAVA_HOME/bin/java,以下直接配置真实路径

JAVA_HOME=/usr/java/default/bin/java

其他参数详见官方文档,以上的配置如果与maven冲突,conf配置优先级最高

 

关于卸载init.d,其实就是删除init.d的软链接,如果设置了开机自启,再执行systemctl daemon-reload重载一下自启配置

 

四.写在最后

在linux系统上执行 vi demo-0.0.1-SNAPSHOT.jar,会发现里面的内容由shell脚本 + jar包实际内容二进制 组成,如下图所示

 

如上图,exit 0 之后,后面的为jar包二进制。

因为文件前内嵌了shell脚本,因此可以使用 sh ./demo-0.0.1-SNAPSHOT.jar来直接执行。

然后神奇的发现,可以使用360压缩打开,不影响jar包,或许这就是可以继续使用java -jar执行的原因,大胆的猜测,当不能使用360压缩打开时,java -jar就无效了,因为java -xf已经不能提取出来jar/war了

 

由上面的脚本,不难发现init.d的实现原理其实就是这一小戳精髓的shell脚本内容。由此可以自己实现一个自己的init.d。

 

以上的所有内容都是经过本人一一测试的,如果内容有误,欢迎评论,看到会回。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章