spring boot应用程序在Linux下注册成系统服务
通常,将一个Java程序打包成jar之后,可通过java -jar xxx.jar
命令运行,但若是以此方式进行部署,则会发现一些不人性化的地方,例如此程序将会一直在前台运行,终端关闭该Java进程也会停止,即便使用nohup
或是screen
将程序转入后台运行,在需要对Java程序进行关闭、重启、设置开机自启等管理操作时,都需要繁琐的操作,于是,就有了更简便的方式:将该Java服务注册成Linux系统中的服务,使用Linux系统的服务管理机制来管理Java程序。
spring boot项目中的设置
只需在maven的pom文件中,设置spring-boot-maven-plugin的executable为true即可:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
</build>
Linux系统上的设置
Linux系统的启动和管理(包括系统服务)在历史上一直采用init
进程,关于init
,摘录了一段维基百科上的简介:
init(为英语:initialization的简写)是 Unix 和 类Unix 系统中用来产生其它所有进程的程序。它以守护进程的方式存在,其进程号为1。Linux系统在引导时加载Linux内核后,便由Linux内核加载init程序,由init程序完成余下的引导过程,比如加载运行级别,加载服务,引导Shell/图形化界面等等。
Unix 系列中(如 System III 和 System V)init的作用,和研究中的 Unix 和 BSD 派生版本相比,发生了一些变化。大多数Linux发行版是和 System V 相兼容的,但是一些发行版如Slackware 采用的是BSD风格,其它的如 Gentoo 是自己定制的。后来Ubuntu[1][2] 和其他一些发行版采用 Upstart[3] 来代替[4] 传统的 init 进程。至2015年,大部分Linux发行版都已采用新的systemd替代System V和Upstart,但systemd向下兼容System V。
使用init进程来启动服务有两个缺点:
一是启动时间长。init
进程是串行启动,只有前一个进程启动完,才会启动下一个进程。
二是启动脚本复杂。init
进程只是执行启动脚本,不管其他事情。脚本需要自己处理各种情况,这往往使得脚本变得很长。
于是,就有了维基百科关于init
的简介中所说到的,现目前大部分发行版用来代替init
的systemd
,在使用了systemd
的Linux发行版系统中,系统的第一个进程(PID 等于 1)从init
变成了systemd
,其他进程都是它的子进程,关于systemd
的简介:
systemd是Linux电脑操作系统之下的一套中央化系统及设置管理程序(init),包括有守护进程、程序库以及应用软件,由Lennart Poettering带头开发。其开发目标是提供更优秀的框架以表示系统服务间的依赖关系,并依此实现系统初始化时服务的并行启动,同时达到降低Shell的系统开销的效果,最终代替现在常用的System V与BSD风格init程序。
回到本文的目的中来,将spring boot注册成Linux系统的服务,对应Linux系统的两种启动和管理机制,也有两种方式。
init的方式
在使用init
启动和管理的Linux上,将springboot注册成系统服务只需将可执行jar使用符号链接链接到系统的/etc/init.d/
目录中即可,对应的命令:
ln -s /jar包的路径/jar文件名称.jar /etc/init.d/服务名称
之后,即可通过service 服务名称 {start|stop|force-stop|restart|force-reload|status|run}
等命令来对Java程序进行管理操作。
综合上面关于init
和systemd
的介绍,以及使用此种方式若想设置服务开机自启还需另外编写脚本的繁杂操作,本文更推荐在已引入systemd
的Linux中使用下面的方式注册服务(绝大部分新的Linux发行版都已引入systemd
,但仍保留着init
)。
systemd的方式
systemd
管理的服务文件位于/etc/systemd/system/
下,以.service
结尾,要将spring boot程序使用此种方式注册成系统服务,则需在此文件夹中创建相应的服务文件xxx.service
,在文件中写入如下内容:
[Unit]
Description=myapp
After=syslog.target
[Service]
User=myapp
ExecStart=/var/myapp/myapp.jar
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
其中需要修改的是Description
的值以及将/var/myapp/myapp.jar
替换成自己的jar文件路径,之后即可通过systemctl {start|stop|restart|status|kill|enable|disable} 服务名称
命令或是service 服务名称 {start|stop|restart|status}
命令来管理spring boot服务。
上述配置文件示例来自springboot官方文档,关于systemd
的服务配置文件,还有很多可配置的选项内容,例如失败重启、服务启动需要的前置和后置服务等等等配置项,是另外一门独立的知识点。
配置文件中可供配置的选项可参考systemd官方文档
配置文件
在jar所在文件夹中创建与jar名称相同但文件后缀为.conf的文件,例如jar名称为myapp.jar
,则在同一目录下创建myapp.conf
文件,springboot服务启动时会读取该配置文件,配置文件中主要配置的配置项:
选项名称 | 描述 |
---|---|
RUN_AS_USER | 程序运行时使用的Linux用户,未设置时默认为此jar文件所属用户。 |
LOG_FOLDER | 主日志文件存放路径,默认为/var/log |
RUN_ARGS | 传递给springboot的启动参数。 |
JAVA_OPTS | 传递给jvm的参数(最重要的就是这个,jvm调优时的参数通过此项设置) |
完整可配置的选项参考springboot官方文档