baeldung 2024-01-24
1. 概述
本文探讨了将 Spring Boot 应用程序作为系统服务运行的几种可选方案。
首先,我们将介绍 Web 应用程序的打包方式以及系统服务的基本概念。随后,我们将分别针对 Linux 和 Windows 系统,详细说明配置服务的不同方法。
最后,我们会提供一些额外参考资料的链接,供进一步学习。
2. 项目设置与构建说明
2.1 打包方式
传统上,Web 应用程序被打包为 Web Application aRchive(WAR) 文件,并部署到 Web 服务器中。
而 Spring Boot 应用程序既可以打包为 WAR,也可以打包为 JAR 文件。后者将 Web 服务器内嵌在 JAR 文件中,使得你无需安装和配置独立的应用服务器即可直接运行应用程序。
2.2 Maven 配置
我们从 pom.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。 - 本文撰写时使用的是 Spring Boot 的最新稳定版本,但任何 1.3 之后的版本都适用。你可以在此处查看可用版本信息。
- 注意:我们在
spring-boot-maven-plugin中设置了<executable>true</executable>。这会确保生成的 JAR 包含一个MANIFEST.MF文件,其中包含Main-Class条目,用于指定应用程序的主类(即包含main方法的类)。
2.3 构建应用程序
在应用程序根目录下执行以下命令:
$ mvn clean package
构建完成后,可执行的 JAR 文件将位于 target/ 目录下。你可以通过以下命令启动应用:
$ java -jar your-app.jar
此时,你仍需通过 java -jar 命令手动启动应用。但在生产环境中,更理想的方式是将应用配置为系统服务,以便实现自动启动、后台运行和集中管理。
3. 在 Linux 上运行
虽然可以使用 Unix 的 nohup 命令将程序作为后台进程运行,但这并不是推荐的做法(原因详见此讨论帖)。
更好的做法是将应用守护进程化(daemonize)。在 Linux 中,你可以选择使用传统的 System V init 脚本,或更现代的 systemd 配置文件。前者较为传统,后者正逐步成为主流。
更多关于 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
Spring Boot 的可执行 JAR 文件极大简化了服务配置过程:
$ sudo ln -s /path/to/your-app.jar /etc/init.d/your-app
注意:必须使用 JAR 文件的完整路径,否则符号链接将无法正常工作。
创建符号链接后,即可像普通服务一样管理应用:
$ sudo service your-app start
该脚本支持标准的 start、stop、restart 和 status 命令。此外:
- 服务将以我们刚创建的
baeldung用户身份运行; - 进程 ID(PID)将记录在
/var/run/your-app/your-app.pid; - 控制台日志将写入
/var/log/your-app.log,若应用启动失败,可在此查看日志。
3.2 systemd
使用 systemd 配置服务同样非常简单。首先,在 /etc/systemd/system/ 目录下创建一个名为 your-app.service 的文件,内容如下:
[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
请根据你的实际情况修改 Description、User 和 ExecStart 字段。
与 System V init 不同,systemd 不会自动创建 PID 文件或日志文件。如需这些功能,必须在服务配置中显式指定(例如使用 PIDFile= 或重定向日志)。完整的配置选项列表请参见 systemd.service 文档。
配置完成后,即可使用标准服务命令:
$ sudo systemctl daemon-reload
$ sudo systemctl start your-app
$ sudo systemctl enable your-app # 开机自启
3.3 Upstart
Upstart 是一种基于事件的服务管理器,曾被视为 System V init 的替代方案,能对守护进程行为提供更精细的控制。
大多数 Linux 发行版已不再默认使用 Upstart,但在 Ubuntu 较旧版本中可能仍存在(可检查 /etc/init/ 下是否有以 “upstart” 开头的作业)。
要使用 Upstart 启动 Spring Boot 应用,可在 /etc/init/(或用户目录下的 ~/.config/upstart/)创建一个 your-app.conf 文件:
description "Some Spring Boot application"
respawn # 若服务意外终止,则自动重启
exec java -jar /path/to/your-app.jar
然后执行:
$ start your-app
Upstart 提供丰富的作业配置选项,详情请参阅 Upstart Cookbook。
4. 在 Windows 上运行
本节介绍几种在 Windows 上将 Java JAR 文件作为服务运行的方法。
4.1 Windows Service Wrapper(WinSW)
由于 Java Service Wrapper 采用 GPL 许可证,与某些开源项目(如 MIT 许可的 Jenkins)存在兼容性问题,因此诞生了 Windows Service Wrapper(简称 WinSW)项目。
WinSW 不仅支持 Java 应用,还可将任意可执行程序包装为 Windows 服务,并提供编程接口用于安装、卸载、启动和停止服务。
使用步骤如下:
- 从 GitHub Releases 下载 WinSW 二进制文件。
- 创建配置文件
MyApp.xml:
<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,使其与 XML 配置文件名一致。 - 安装服务:
C:\path\to> MyApp.exe install
之后即可使用 MyApp.exe start、stop、uninstall 等命令管理服务。
4.2 Java Service Wrapper
如果你不介意 GPL 许可证的限制,Java Service Wrapper 也是一个成熟的选择。它同样通过配置文件定义如何将 JAR 作为 Windows 服务运行。
关于具体配置方法,已有大量详细教程(例如此文),此处不再赘述。
5. 补充参考资料
- 你还可以使用 Apache Commons Daemon 项目中的 Procrun 将 Spring Boot 应用注册为 Windows 服务。Procrun 支持服务随系统启动,并在无用户登录时持续运行。
- 关于在 Unix 系统上运行 Spring Boot 应用的更多细节,请参阅 Spring Boot 官方文档。
- Red Hat 系列系统中 systemd 单元文件的定制方法也有详细指南。
- 此外,还有一种技巧:可将 Bash 脚本嵌入 JAR 文件头部,使 JAR 本身成为一个可直接执行的脚本!详见 Spring Boot 可执行 JAR 技巧。
6. 结论
将应用程序配置为系统服务,能极大地提升其生命周期管理效率。正如我们所见,Spring Boot 对服务部署的支持已变得前所未有的简单。
切记: 务必遵循基本的安全实践——为服务创建专用用户,并合理设置文件权限,避免以 root 或 Administrator 身份运行应用。