分类
DevOps spring-boot

SpringBoot应用作为服务运行

Spring Boot Application as a Service

译者注

原文

https://www.baeldung.com/spring-boot-app-as-a-service

1、 前言

本文中,我们探讨把SpringBoot应用作为服务运行的一些方案。
首先,我们将会去解释web程序的打包选项和系统服务。
然后,当需要同时运行在linux和Windows系统时,我们有哪些办法来实现这个目的。
最后,我们将会总结一些引用文章,以便帮助读者获取更多信息。

2、项目设置和构建说明

2.1 打包

Web应用以传统方式被打包成web应用存档(Application aRchives,WAR),然后部署到一个web服务器。
SpringBoot应用既可以被打包成WAR也可以被打包成Jar文件,具体如何打包取决于你的应用服务是否需要安装配置的过程。

2.2 Maven配置

我们先从定义Maven的配置文件pox.xml开始:

<packaging>jar</packaging>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.0.RELEASE</version>
</parent>

<dependencies>
    ....
</dependencies>

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

打包一定要设置为jar,在本文编写时,我们使用的是最新的SpringBoot稳定版,但实际上只要版本高于1.3就可以了。
你可以在这篇文章中找到可行的版本。

2.3 构建你的应用程序

在应用程序根目录执行这条命令来完成构建:

$ mvn clean package

然后,就可以在target目录中找到可执行的JAR文件。
如果要执行这个文件,需要在命令行中执行这条命令:

$ java -jar your-app.jar

此外,你仍然需要通过-jar选项来调用Java解释器。
有许多原因可以解释,为什么通过服务运行应用程序是一个好的办法。

3. 在linux中运行

为了作为一个后台进程运行这个程序,我们需要使用UNIX命令nohup,但出于某些原因,这并不是最好的办法。在这篇文章中给了很好的解释。
我们需要为我们的进程生成一个守护进程。在Linux下,我们需要选择:使用传统的System V初始化脚本还是使用Systemd配置文件,来配置守护进程。前者是被人们普遍认可的,但它逐渐被后者取代。

你可以在这篇文章中找到二者的详细区别。

为了加强安全性。我们先创建一个特殊用户,来运行这个服务,并且改变这个JAR文件的权限:

$ sudo useradd baeldung
$ sudo passwd baeldung
$ sudo chown baeldung:baeldung your-app.jar
$ sudo chmod 500 your-app.jar

3.1 System V init

SpringBoot可执行JAR文件使得服务启动进程十分简单:

$ sudo ln -s /path/to/your-app.jar /etc/init.d/your-app

上面的代码对你的可执行JAR文件创建了一个符号连接。必须使用到这个JAR文件的完整路径才能正确执行,否则符号连接无法正常工作。这个连接使得你可以让这个应用程序作为服务来启动:

$ sudo service your-app start

这个脚本支持标准服务的启动(start)、终止(stop)、重启(restart)、状态(status)命令,此外:

  • 它使用我们刚刚创建的“baeldung”用户来运行这个服务
  • 它在/var/run/your-app/your-app.pid文件中追踪这个程序的进程
  • 它写入控制命令到/var/log/your-app.log进程,以便我们可以查看程序的运行状态

3.2 systemd

systemd服务设置起来非常的简单。首先我们创建一个名为your-app.service的文件,并且填入下面的示例代码,然后把它放到/etc/systemd/system目录中:

[Unit]
Description=A Spring Boot application
After=syslog.target

[Service]
User=baeldung
ExecStart=/path/to/your-app.jar SuccessExitStatus=143 

[Install] 
WantedBy=multi-user.target

我们需要根据应用程序的实际情况来更新字段DescriptionUserExecStart。你需要能够执行前面提到的运行一个服务的基本命令。

3.3 Upstart

Upstart是一个基于时间的服务管理器,它是System V init的潜在替代者,它可以更好的控制不同守护进程的行为。

这篇安装教程十分有用,它对于几乎所有的Linux发行版都是可用的。
当使用Ubuntu时,你可能已经安装和配置好了,请检查/etc/init文件中是否以upstart开头的任务。

我们创建一个名为your-app.conf的任务,来启动我们的SpringBoot程序:

# Place in /home/{user}/.config/upstart

description "Some Spring Boot application"

respawn # attempt service restart if stops abruptly

exec java -jar /path/to/your-app.jar

现在运行start your-app,你的服务就可以启动了。

Upstart提供了许多任务配置选项,你可以在这个地址中找到大多数信息。

4. 在Windows中

本小节中,我们有几种不同的办法来使用Windows服务运行Java JAR包。

4.1 Windows服务装饰器(Windows Service Wrapper

由于Java服务装饰器使用的GPL协议和Jenkins使用的MIT协议在兼容上存在困难,人们开启了Windows服务装饰器项目,也称为“winsw”。

Winsw提供了安装、卸载、启动、停止服务的方法。
它可以在Windows平台运行任何类型的可执行服务,而不是像Java Service Wrapper只能运行Java的程序。

首先从这里下载二进制文件。然后编辑用来定义我们的Windows服务的配置文件:

<service>
    <id>MyApp</id>
    <name>MyApp</name>
    <description>This runs Spring Boot as a Service.</description>
    <env name="MYAPP_HOME" value="%BASE%"/>
    <executable>java</executable>
    <arguments>-Xmx256m -jar "%BASE%\MyApp.jar"</arguments>
    <logmode>rotate</logmode>
</service>

最后,把winsw.exe重命名为MyApp.exe,以便和配置文件MyApp.xml匹配。然后就可以安装服务:

$ MyApp.exe install

相似的,也可以卸载(stop)、启动(start)、停止(stop),等等。

4.2 Java服务装饰器

如果你不介意Java服务装饰器项目的GPL许可协议,有一个可替代的方式来配置你的JAR文件作为Windows服务。
Java服务装饰器也需要你去定制一个配置文件,来声明如何把你的程序作为服务在Windows上运行。

这篇文章详细阐述了在Windows下如何配置一个JAR可执行文件作为服务运行,因此无需再重复之前的内容。

5. 额外的引用

我们也可以使用Apache Commons Daemon
项目的 Procrun来让SpringBoot应用程序作为Windows服务启动。
Procrun是一个应用程序集合,它允许Windows用户把Java应用程序装饰成为一个Windows服务。这样的服务可以在机器启动时自动启动,并且即使没有用户登录也会持续运行。

这里可以找到关于SpringBoot程序在Unix下运行的更多信息。
这篇文章也介绍了如何编辑Redhat的Systemd系统单元文件

最后,这篇快速指南描述了如何为你的JAR文件创建一个Bash脚本,以便让它自己运行。

6.结论

服务是的我们可以更高效地管理我们的应用程序,正如我们看到的,把SpringBoot设置为一个服务的过程比以往更简单了。

需要注意的是,在用户权限方面,我们应该遵循重要而简单的安全措施,来运行你的服务。