安装 Spring Boot 应用程序
除了使用java -jar
直接运行 Spring Boot 应用程序外,还可以将其作为systemd
、init.d
或 Windows 服务运行。
作为 systemd 服务安装
systemd
是 System V init 系统的后继者,现在被许多现代 Linux 发行版使用。可以使用systemd
的“服务”脚本启动 Spring Boot 应用程序。
假设您有一个作为 uber jar 打包在/var/myapp
中的 Spring Boot 应用程序,要将其作为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上进行了测试。其他平台(如OS X和FreeBSD)需要使用自定义脚本。默认脚本支持以下功能
-
以拥有jar文件的用户身份启动服务
-
使用
/var/run/<appname>/<appname>.pid
跟踪应用程序的PID -
将控制台日志写入
/var/log/<appname>.log
假设您在/var/myapp
中安装了一个Spring Boot应用程序,要将Spring Boot应用程序作为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脚本可以提供“描述”。由于您事先知道描述(并且它不需要更改),因此您不妨在生成jar文件时提供它。
要自定义写入的元素,请使用Spring Boot Maven插件的embeddedLaunchScriptProperties
选项或Spring Boot Gradle插件的launchScript
的properties
属性。
默认脚本支持以下属性替换
名称 | 描述 | Gradle默认值 | Maven默认值 |
---|---|---|---|
|
脚本模式。 |
|
|
|
“INIT INFO”的 |
|
|
|
“INIT INFO”的 |
|
|
|
“INIT INFO”的 |
|
|
|
“INIT INFO”的 |
|
|
|
“INIT INFO”的 |
|
|
|
“INIT INFO”的 |
|
|
|
“INIT INFO”的 |
|
|
|
“INIT INFO”的 |
|
|
|
|
包含jar文件的文件夹 |
包含jar文件的文件夹 |
|
对应一个应该内联到默认启动脚本中的文件脚本的引用。这可用于在加载任何外部配置文件之前设置环境变量(例如 |
||
|
|
||
|
|
||
|
|
||
|
|
||
|
是否应使用 |
|
|
|
|
60 |
60 |
在运行时自定义脚本
对于需要在jar文件写入之后进行自定义的脚本项,您可以使用环境变量或配置文件。
默认脚本支持以下环境属性
变量 | 描述 |
---|---|
|
操作的“模式”。默认值取决于jar文件的构建方式,但通常为 |
|
将用于运行应用程序的用户。未设置时,将使用拥有jar文件的用户。 |
|
是否应使用 |
|
pid文件夹的根名称(默认为 |
|
放置日志文件的文件夹的名称(默认为 |
|
读取.conf文件的文件夹的名称(默认为与jar文件相同的文件夹)。 |
|
|
|
应用程序的名称。如果从符号链接运行jar文件,则脚本会猜测应用程序名称。如果它不是符号链接或您要显式设置应用程序名称,则这很有用。 |
|
传递给程序(Spring Boot应用程序)的参数。 |
|
|
|
启动JVM时传递给JVM的选项。 |
|
jar文件的显式位置,以防脚本用于启动它实际上未嵌入的jar文件。 |
|
如果非空,则在shell进程上设置 |
|
在停止应用程序之前等待强制关闭的时间(以秒为单位)(默认为 |
PID_FOLDER 、LOG_FOLDER 和LOG_FILENAME 变量仅对init.d 服务有效。对于systemd ,等效的自定义是使用“service”脚本进行的。有关更多详细信息,请参阅服务单元配置手册页。 |
使用Conf文件
除了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 服务的指南。