|
此版本仍在开发中,尚未视为稳定版。如需最新稳定版本,请使用 Spring Boot 4.0.4! |
安装 Spring Boot 应用程序
除了直接使用 java -jar 运行 Spring Boot 应用程序外,还可以将其作为 systemd、init.d 或 Windows 服务来运行。
作为 systemd 服务进行安装
systemd 是 System V init 系统的继任者,如今已被许多现代 Linux 发行版所采用。
Spring Boot 应用程序可以通过使用 systemd 的“服务”脚本来启动。
假设你有一个 Spring Boot 应用程序,已打包为一个包含所有依赖的 uber jar 文件,并位于 /var/myapp 目录下。要将其安装为 systemd 服务,请创建一个名为 myapp.service 的脚本,并将其放置在 /etc/systemd/system 目录中。
以下脚本提供了一个示例:
[Unit]
Description=myapp
After=syslog.target network.target
[Service]
User=myapp
Group=myapp
Type=exec
ExecStart=/path/to/java/home/bin/java -jar /var/myapp/myapp.jar
WorkingDirectory=/var/myapp
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
记得根据你的应用程序修改 Description、User、Group、ExecStart 和 WorkingDirectory 字段。 |
ExecStart 字段未声明脚本操作命令,这意味着默认使用 run 命令。 |
运行应用程序的用户、PID 文件和控制台日志文件由 systemd 自身管理,因此必须在“service”脚本中使用相应的字段进行配置。
更多详细信息,请参阅服务单元配置手册页。
要将应用程序标记为在系统启动时自动启动,请使用以下命令:
$ systemctl enable myapp.service
运行 man systemctl 以获取更多详细信息。
作为 init.d 服务进行安装(System V)
要将您的应用程序用作 init.d 服务,请配置其构建过程以生成一个完全可执行的 jar。
完全可执行的 JAR 文件通过在文件开头嵌入一段额外的脚本来实现。
目前,某些工具尚不支持这种格式,因此你可能无法始终使用此技术。
例如,jar -xf 在解压一个已被设为完全可执行的 JAR 或 WAR 文件时,可能会静默失败。
建议仅在你打算直接执行该 JAR 或 WAR 文件(而不是使用 java -jar 运行或将它部署到 Servlet 容器中)时,才将其设为完全可执行。 |
无法将 zip64 格式的 JAR 文件制作成完全可执行的文件。
尝试这样做会导致生成的 JAR 文件在直接执行或使用 java -jar 命令运行时被报告为已损坏。
包含一个或多个 zip64 格式嵌套 JAR 文件的标准格式 JAR 文件则可以被制作成完全可执行的文件。 |
要使用 Maven 创建一个“完全可执行”的 JAR 文件,请使用以下插件配置:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
以下示例展示了等效的 Gradle 配置:
tasks.named('bootJar') {
launchScript()
}
然后可以将其创建符号链接到 init.d,以支持标准的 start、stop、restart 和 status 命令。
添加到完全可执行 JAR 文件中的默认启动脚本支持大多数 Linux 发行版,并已在 CentOS 和 Ubuntu 上经过测试。 其他平台(如 macOS 和 FreeBSD)则需要使用自定义脚本。 默认脚本支持以下功能:
-
以拥有该 jar 文件的用户身份启动服务
-
通过使用
/var/run/<appname>/<appname>.pid来跟踪应用程序的 PID -
将控制台日志写入
/var/log/<appname>.log
假设你已将一个 Spring Boot 应用程序安装在 /var/myapp 目录下,若要将其作为 init.d 服务安装,请创建一个符号链接,如下所示:
$ sudo ln -s /var/myapp/myapp.jar /etc/init.d/myapp
安装完成后,您可以按照常规方式启动和停止该服务。 例如,在基于 Debian 的系统上,您可以使用以下命令启动它:
$ service myapp start
如果你的应用程序启动失败,请检查写入到 /var/log/<appname>.log 的日志文件以查找错误。 |
您也可以使用标准的操作系统工具将应用程序标记为自动启动。 例如,在 Debian 系统上,您可以使用以下命令:
$ update-rc.d myapp defaults <priority>
保护 init.d 服务
| 以下是一组关于如何保护以 init.d 服务方式运行的 Spring Boot 应用程序的安全指南。 本文并非旨在详尽列出加固应用程序及其运行环境所需采取的所有措施。 |
当以 root 用户身份执行时(例如使用 root 启动 init.d 服务的情况),默认的可执行脚本会以 RUN_AS_USER 环境变量中指定的用户身份运行应用程序。
如果未设置该环境变量,则会改用 JAR 文件的所有者用户。
你不应以 root 用户身份运行 Spring Boot 应用程序,因此 RUN_AS_USER 不应设为 root,且你的应用程序 JAR 文件也不应由 root 用户拥有。
相反,应创建一个专用用户来运行你的应用程序,并设置 RUN_AS_USER 环境变量,或者使用 chown 命令将该用户设为 JAR 文件的所有者,如下例所示:
$ chown bootapp:bootapp your-app.jar
在这种情况下,默认的可执行脚本会以 bootapp 用户身份运行应用程序。
为了降低应用程序用户账户被攻破的风险,您应考虑禁止该账户使用登录 shell。
例如,您可以将该账户的 shell 设置为 /usr/sbin/nologin。 |
您还应采取措施防止对应用程序的 JAR 文件进行修改。 首先,配置其权限,使其不可被写入,并且仅可由其所有者读取或执行,如下例所示:
$ chmod 500 your-app.jar
其次,如果您的应用程序或运行该程序的账户遭到入侵,您还应采取措施限制可能造成的损害。
如果攻击者确实获得了访问权限,他们可能会使 JAR 文件可写并修改其内容。
一种防范方法是使用 chattr 命令将其设为不可变,如下例所示:
$ sudo chattr +i your-app.jar
这将阻止任何用户(包括 root 用户)修改该 JAR 文件。
如果使用 root 用户来控制应用程序的服务,并且您使用.conf文件来自定义其启动,那么.conf文件将由 root 用户读取和评估。
应相应地对其进行保护。
使用chmod以便该文件只能由所有者读取,并使用chown将 root 设置为所有者,如下例所示:
$ chmod 400 your-app.conf
$ sudo chown root:root your-app.conf
自定义启动脚本
Maven 或 Gradle 插件生成的默认内嵌启动脚本可以通过多种方式进行自定义。
对大多数人来说,使用默认脚本并进行少量自定义通常就足够了。
如果你发现某些需要自定义的内容无法实现,请使用 embeddedLaunchScript 选项完全编写自己的脚本文件。
自定义启动脚本的写入过程
通常,在将启动脚本写入 JAR 文件时,对其某些元素进行自定义是有意义的。 例如,init.d 脚本可以提供一个“description”(描述)。 由于你事先就知道该描述(而且它无需更改),因此最好在生成 JAR 文件时就提供它。
要自定义写入的元素,请使用 Spring Boot Maven 插件的 embeddedLaunchScriptProperties 选项,或 Spring Boot Gradle 插件的 launchScript 的 properties 属性。
默认脚本支持以下属性替换:
| 姓名 | <description> </description> | Gradle 默认 | Maven 默认 |
|---|---|---|---|
|
脚本模式。 |
|
|
|
“INIT INFO”部分中的 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
包含 jar 文件的文件夹 |
包含 jar 文件的文件夹 |
|
对一个文件脚本的引用,该脚本应内联到默认的启动脚本中。
这可用于在加载任何外部配置文件之前设置环境变量,例如 |
||
|
|
||
|
|
||
|
|
||
|
|
||
|
当 |
|
|
|
|
60 |
60 |
自定义脚本运行时的行为
对于需要在 jar 文件写入之后进行自定义的脚本项,您可以使用环境变量或配置文件。
默认脚本支持以下环境属性:
| 变量 | <description> </description> |
|---|---|
|
操作“模式”。
默认值取决于 JAR 文件的构建方式,但通常为 |
|
用于运行应用程序的用户。 如果未设置,将使用拥有该 JAR 文件的用户。 |
|
当 |
|
pid 文件夹的根目录名称(默认为 |
|
用于存放日志文件的文件夹名称(默认为 |
|
用于读取 .conf 文件的文件夹名称(默认为与 jar 文件相同的文件夹)。 |
|
日志文件在 |
|
应用程序的名称。 如果通过符号链接运行该 jar 文件,脚本会自动推断应用程序名称。 如果不是符号链接,或者您希望显式设置应用程序名称,此选项将非常有用。 |
|
要传递给程序(Spring Boot 应用)的参数。 |
|
|
|
启动 JVM 时传递给它的选项。 |
|
在脚本用于启动一个并未实际嵌入其中的 JAR 文件时,该 JAR 文件的显式位置。 |
|
如果非空,则在 shell 进程上设置 |
|
在停止应用程序时,强制关闭前等待的秒数(默认为 |
PID_FOLDER、LOG_FOLDER 和 LOG_FILENAME 变量仅对 init.d 服务有效。
对于 systemd,相应的自定义配置应通过使用“service”脚本来实现。
更多详情请参阅服务单元配置手册页。 |
使用配置文件
除了 JARFILE 和 APP_NAME 之外,前一节列出的设置均可通过使用 .conf 文件进行配置。
该文件应与 jar 文件位于同一目录下,并且具有相同的名称,但后缀应为 .conf 而非 .jar。
例如,名为 /var/myapp/myapp.jar 的 jar 文件会使用名为 /var/myapp/myapp.conf 的配置文件,如下例所示:
JAVA_OPTS=-Xmx1024M
LOG_FOLDER=/custom/log/folder
如果你不喜欢将配置文件放在 JAR 文件旁边,可以设置一个 CONF_FOLDER 环境变量来自定义配置文件的位置。 |
要了解如何恰当地保护此文件,请参阅保护 init.d 服务的指南。