Spring Boot 灵活的打包选项在部署应用程序时提供了大量选择。您可以将 Spring Boot 应用程序部署到各种云平台、虚拟机/真实机,或者使它们在 Unix 系统上完全可执行。
本节介绍一些更常见的部署场景。
1. 部署到云端
Spring Boot 的可执行 jar 是为最流行的云 PaaS(平台即服务)提供商准备的。这些提供商往往要求您“自带容器”。它们管理应用程序进程(不是专门的 Java 应用程序),因此需要一个中间层来使您的应用程序适应云运行进程的概念。
两个流行的云提供商 Heroku 和 Cloud Foundry 采用“buildpack”方法。构建包将您部署的代码包装在启动应用程序所需的任何内容中。它可能是一个 JDK 和对 的调用java
、嵌入式 Web 服务器或成熟的应用程序服务器。构建包是可插入的,但理想情况下,您应该能够对其进行尽可能少的自定义。这减少了不受您控制的功能的占用空间。它最大限度地减少了开发和生产环境之间的差异。
理想情况下,您的应用程序(如 Spring Boot 可执行 jar)将运行所需的所有内容打包在其中。
在本节中,我们将了解如何使我们在“入门”部分中开发的应用程序在云中启动并运行。
1.1. 云铸造厂
Cloud Foundry 提供默认构建包,如果未指定其他构建包,这些构建包就会发挥作用。Cloud Foundry Java 构建包对 Spring 应用程序(包括 Spring Boot)具有出色的支持。您可以部署独立的可执行 jar 应用程序以及传统的.war
打包应用程序。
一旦您构建了应用程序(例如,使用mvn clean package
)并安装了cf
命令行工具,就可以使用该cf push
命令部署您的应用程序,并将路径替换为已编译的.jar
. 在推送应用程序之前,请确保已使用命令行客户端登录。cf
以下行显示了使用cf push
命令来部署应用程序:
$ cf push acloudyspringtime -p target/demo-0.0.1-SNAPSHOT.jar
在前面的示例中,我们将替换acloudyspringtime 您提供的任何值cf 作为应用程序的名称。
|
有关更多选项,请参阅cf push
文档。如果manifest.yml
同一目录中存在 Cloud Foundry 文件,则会考虑该文件。
此时,cf
开始上传您的应用程序,生成类似于以下示例的输出:
Uploading acloudyspringtime... OK Preparing to start acloudyspringtime... OK -----> Downloaded app package (8.9M) -----> Java Buildpack Version: v3.12 (offline) | https://github.com/cloudfoundry/java-buildpack.git#6f25b7e -----> Downloading Open Jdk JRE Expanding Open Jdk JRE to .java-buildpack/open_jdk_jre (1.6s) -----> Downloading Open JDK Like Memory Calculator 2.0.2_RELEASE from https://java-buildpack.cloudfoundry.org/memory-calculator/trusty/x86_64/memory-calculator-2.0.2_RELEASE.tar.gz (found in cache) Memory Settings: -Xss349K -Xmx681574K -XX:MaxMetaspaceSize=104857K -Xms681574K -XX:MetaspaceSize=104857K -----> Downloading Container Certificate Trust Store 1.0.0_RELEASE from https://java-buildpack.cloudfoundry.org/container-certificate-trust-store/container-certificate-trust-store-1.0.0_RELEASE.jar (found in cache) Adding certificates to .java-buildpack/container_certificate_trust_store/truststore.jks (0.6s) -----> Downloading Spring Auto Reconfiguration 1.10.0_RELEASE from https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-1.10.0_RELEASE.jar (found in cache) Checking status of app 'acloudyspringtime'... 0 of 1 instances running (1 starting) ... 0 of 1 instances running (1 starting) ... 0 of 1 instances running (1 starting) ... 1 of 1 instances running (1 running) App started
恭喜!该应用程序现已上线!
应用程序上线后,您可以使用命令验证已部署应用程序的状态cf apps
,如以下示例所示:
$ cf apps
Getting applications in ...
OK
name requested state instances memory disk urls
...
acloudyspringtime started 1/1 512M 1G acloudyspringtime.cfapps.io
...
一旦 Cloud Foundry 确认您的应用程序已部署,您应该能够在给定的 URI 中找到该应用程序。在前面的示例中,您可以在 找到它https://acloudyspringtime.cfapps.io/
。
1.1.1. 绑定到服务
默认情况下,有关正在运行的应用程序的元数据以及服务连接信息将作为环境变量公开给应用程序(例如:)$VCAP_SERVICES
。此架构决策是由于 Cloud Foundry 的多语言特性(任何语言和平台都可以作为构建包支持)。进程范围的环境变量与语言无关。
环境变量并不总是最简单的 API,因此 Spring Boot 会自动提取它们并将数据扁平化为可通过 SpringEnvironment
抽象访问的属性,如以下示例所示:
@Component
public class MyBean implements EnvironmentAware {
private String instanceId;
@Override
public void setEnvironment(Environment environment) {
this.instanceId = environment.getProperty("vcap.application.instance_id");
}
// ...
}
@Component
class MyBean : EnvironmentAware {
private var instanceId: String? = null
override fun setEnvironment(environment: Environment) {
instanceId = environment.getProperty("vcap.application.instance_id")
}
// ...
}
所有 Cloud Foundry 属性均以vcap
. 您可以使用vcap
属性来访问应用程序信息(例如应用程序的公共 URL)和服务信息(例如数据库凭据)。有关完整详细信息,请参阅CloudFoundryVcapEnvironmentPostProcessor
Javadoc。
Java CFEnv项目更适合配置数据源等任务。 |
1.2. 库伯内斯
Spring Boot 通过检查环境"*_SERVICE_HOST"
和"*_SERVICE_PORT"
变量来自动检测 Kubernetes 部署环境。您可以使用配置属性覆盖此检测spring.main.cloud-platform
。
Spring Boot 可帮助您管理应用程序的状态,并使用 Actuator 通过 HTTP Kubernetes Probes导出它。
1.2.1. Kubernetes 容器生命周期
当 Kubernetes 删除应用程序实例时,关闭过程会同时涉及多个子系统:关闭钩子、取消注册服务、从负载均衡器中删除实例......因为此关闭处理是并行发生的(并且由于分布式系统的性质),有一个窗口,在此期间流量可以路由到也已开始关闭处理的 Pod。
您可以在 preStop 处理程序中配置睡眠执行,以避免请求被路由到已经开始关闭的 Pod。此睡眠时间应该足够长,以便新请求停止路由到 Pod,并且其持续时间因部署而异。可以使用 Pod 配置文件中的 PodSpec 配置 preStop 处理程序,如下所示:
spec:
containers:
- name: "example-container"
image: "example-image"
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 10"]
一旦预停止挂钩完成,SIGTERM 将被发送到容器,并且将开始正常关闭,从而允许完成任何剩余的正在进行的请求。
当 Kubernetes 向 pod 发送 SIGTERM 信号时,它会等待指定的时间,称为终止宽限期(默认为 30 秒)。如果容器在宽限期后仍在运行,则会向它们发送 SIGKILL 信号并强制删除。如果 Pod 关闭时间超过 30 秒(这可能是因为您增加了 ) ,请确保通过在 Pod YAML 中
spring.lifecycle.timeout-per-shutdown-phase 设置选项来增加终止宽限期。terminationGracePeriodSeconds |
1.3. 赫罗库
Heroku 是另一个流行的 PaaS 平台。要自定义 Heroku 构建,您需要提供一个Procfile
,它提供了部署应用程序所需的咒语。Heroku 分配一个port
供 Java 应用程序使用,然后确保到外部 URI 的路由有效。
您必须将应用程序配置为侦听正确的端口。以下示例显示了Procfile
我们的入门 REST 应用程序:
web: java -Dserver.port=$PORT -jar target/demo-0.0.1-SNAPSHOT.jar
Spring Boot 使-D
参数可作为可从 SpringEnvironment
实例访问的属性。配置server.port
属性被提供给嵌入式 Tomcat、Jetty 或 Undertow 实例,然后该实例在启动时使用该端口。环境$PORT
变量是由 Heroku PaaS 分配给我们的。
这应该就是您需要的一切。Heroku 部署最常见的部署工作流程是将git push
代码部署到生产环境,如以下示例所示:
$ git push heroku main
这将导致以下结果:
Initializing repository, done. Counting objects: 95, done. Delta compression using up to 8 threads. Compressing objects: 100% (78/78), done. Writing objects: 100% (95/95), 8.66 MiB | 606.00 KiB/s, done. Total 95 (delta 31), reused 0 (delta 0) -----> Java app detected -----> Installing OpenJDK... done -----> Installing Maven... done -----> Installing settings.xml... done -----> Executing: mvn -B -DskipTests=true clean install [INFO] Scanning for projects... Downloading: https://repo.spring.io/... Downloaded: https://repo.spring.io/... (818 B at 1.8 KB/sec) .... Downloaded: https://s3pository.heroku.com/jvm/... (152 KB at 595.3 KB/sec) [INFO] Installing /tmp/build_0c35a5d2-a067-4abc-a232-14b1fb7a8229/target/... [INFO] Installing /tmp/build_0c35a5d2-a067-4abc-a232-14b1fb7a8229/pom.xml ... [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 59.358s [INFO] Finished at: Fri Mar 07 07:28:25 UTC 2014 [INFO] Final Memory: 20M/493M [INFO] ------------------------------------------------------------------------ -----> Discovering process types Procfile declares types -> web -----> Compressing... done, 70.4MB -----> Launching... done, v6 https://agile-sierra-1405.herokuapp.com/ deployed to Heroku To [email protected]:agile-sierra-1405.git * [new branch] main -> main
您的应用程序现在应该已在 Heroku 上启动并运行。有关更多详细信息,请参阅将 Spring Boot 应用程序部署到 Heroku。
1.4. 开放式班次
OpenShift有许多资源描述如何部署 Spring Boot 应用程序,包括:
1.5. 亚马逊网络服务 (AWS)
Amazon Web Services 提供了多种安装基于 Spring Boot 的应用程序的方法,既可以作为传统的 Web 应用程序 (war),也可以作为具有嵌入式 Web 服务器的可执行 jar 文件。选项包括:
-
AWS 弹性豆茎
-
AWS 代码部署
-
AWS OPS 有效
-
AWS云组建
-
AWS 容器注册表
每个都有不同的功能和定价模型。在本文档中,我们描述了使用 AWS Elastic Beanstalk 的方法。
1.5.1. AWS 弹性豆茎
正如官方Elastic Beanstalk Java 指南中所述,部署 Java 应用程序有两个主要选项。您可以使用“Tomcat 平台”或“Java SE 平台”。
使用 Java SE 平台
此选项适用于生成 jar 文件并运行嵌入式 Web 容器的 Spring Boot 项目。Elastic Beanstalk 环境在端口 80 上运行 nginx 实例来代理在端口 5000 上运行的实际应用程序。要配置它,请将以下行添加到您的application.properties
文件中:
server.port=5000
上传二进制文件而不是源文件
默认情况下,Elastic Beanstalk 上传源并在 AWS 中编译它们。但是,最好改为上传二进制文件。为此,请将类似于以下内容的行添加到您的
|
通过设置环境类型降低成本
默认情况下,Elastic Beanstalk 环境是负载平衡的。负载均衡器的成本很高。为了避免这种成本,请将环境类型设置为“单实例”,如Amazon 文档中所述。您还可以使用 CLI 和以下命令创建单实例环境: eb create -s |
1.5.2. 概括
这是访问 AWS 的最简单方法之一,但还有更多内容需要涵盖,例如如何将 Elastic Beanstalk 集成到任何 CI/CD 工具中、使用 Elastic Beanstalk Maven 插件而不是 CLI 等等。有一篇博客文章更详细地介绍了这些主题。
1.6. CloudCaptain 和 Amazon Web 服务
CloudCaptain 的工作原理是将 Spring Boot 可执行 jar 或 war 转换为最小的 VM 映像,该映像可以在 VirtualBox 或 AWS 上不加更改地部署。CloudCaptain 与 Spring Boot 深度集成,并使用 Spring Boot 配置文件中的信息自动配置端口和运行状况检查 URL。CloudCaptain 将这些信息用于其生成的映像以及其提供的所有资源(实例、安全组、弹性负载均衡器等)。
创建CloudCaptain 帐户、将其连接到您的 AWS 帐户、安装最新版本的 CloudCaptain 客户端并确保应用程序已由 Maven 或 Gradle 构建(例如,使用 )后,您就可以部署mvn clean package
Spring使用类似于以下内容的命令将应用程序启动到 AWS:
$ boxfuse run myapp-1.0.jar -env=prod
有关更多选项,请参阅boxfuse run
文档。boxfuse.conf
如果当前目录中存在文件,则考虑该文件。
默认情况下,CloudCaptain 会激活一个boxfuse 在启动时命名的 Spring 配置文件。如果您的可执行 jar 或 war 包含application-boxfuse.properties 文件,CloudCaptain 会根据其包含的属性进行配置。
|
此时,CloudCaptain 会为您的应用程序创建一个映像,上传该映像,并在 AWS 上配置和启动必要的资源,从而产生类似于以下示例的输出:
Fusing Image for myapp-1.0.jar ... Image fused in 00:06.838s (53937 K) -> axelfontaine/myapp:1.0 Creating axelfontaine/myapp ... Pushing axelfontaine/myapp:1.0 ... Verifying axelfontaine/myapp:1.0 ... Creating Elastic IP ... Mapping myapp-axelfontaine.boxfuse.io to 52.28.233.167 ... Waiting for AWS to create an AMI for axelfontaine/myapp:1.0 in eu-central-1 (this may take up to 50 seconds) ... AMI created in 00:23.557s -> ami-d23f38cf Creating security group boxfuse-sg_axelfontaine/myapp:1.0 ... Launching t2.micro instance of axelfontaine/myapp:1.0 (ami-d23f38cf) in eu-central-1 ... Instance launched in 00:30.306s -> i-92ef9f53 Waiting for AWS to boot Instance i-92ef9f53 and Payload to start at https://52.28.235.61/ ... Payload started in 00:29.266s -> https://52.28.235.61/ Remapping Elastic IP 52.28.233.167 to i-92ef9f53 ... Waiting 15s for AWS to complete Elastic IP Zero Downtime transition ... Deployment completed successfully. axelfontaine/myapp:1.0 is up and running at https://myapp-axelfontaine.boxfuse.io/
您的应用程序现在应该已在 AWS 上启动并运行。
请参阅有关在 EC2 上部署 Spring Boot 应用程序的博客文章以及CloudCaptain Spring Boot 集成的文档,以开始使用 Maven 构建来运行应用程序。
1.7. 天蓝色
本入门指南将引导您完成将 Spring Boot 应用程序部署到Azure Spring Cloud或Azure App Service 的过程。
1.8. 谷歌云
Google Cloud 有多个可用于启动 Spring Boot 应用程序的选项。最容易上手的可能是 App Engine,但您也可以找到在具有 Container Engine 的容器中或具有 Compute Engine 的虚拟机上运行 Spring Boot 的方法。
要将您的第一个应用程序部署到 App Engine 标准环境,请按照本教程进行操作。
或者,App Engine Flex 要求您创建一个app.yaml
文件来描述您的应用程序所需的资源。通常,您将此文件放入 中src/main/appengine
,它应类似于以下文件:
service: "default"
runtime: "java17"
env: "flex"
handlers:
- url: "/.*"
script: "this field is required, but ignored"
manual_scaling:
instances: 1
health_check:
enable_health_check: false
env_variables:
ENCRYPT_KEY: "your_encryption_key_here"
您可以通过将项目 ID 添加到构建配置来部署应用程序(例如,使用 Maven 插件),如以下示例所示:
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>2.4.4</version>
<configuration>
<project>myproject</project>
</configuration>
</plugin>
然后部署mvn appengine:deploy
(需要先进行身份验证,否则构建失败)。
2.安装Spring Boot应用程序
除了使用 Spring Boot 应用程序运行之外java -jar
,还可以为 Unix 系统制作完全可执行的应用程序。完全可执行的 jar 可以像任何其他可执行二进制文件一样执行,也可以使用或注册init.d
systemd
。这有助于在常见生产环境中安装和管理 Spring Boot 应用程序。
完全可执行的 jar 通过在文件前面嵌入额外的脚本来工作。目前,某些工具不接受此格式,因此您可能并不总是能够使用此技术。例如,jar -xf 可能会默默地无法提取已完全可执行的 jar 或 war。建议仅当您打算直接执行 jar 或 war 时才使其完全可执行,而不是使用java -jar servlet 容器运行它或将其部署到 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()
}
然后,您可以通过键入./my-application.jar
(其中my-application
是您的工件的名称)来运行您的应用程序。包含 jar 的目录用作应用程序的工作目录。
2.1. 支持的操作系统
默认脚本支持大多数 Linux 发行版,并在 CentOS 和 Ubuntu 上进行了测试。其他平台,例如 OS X 和 FreeBSD,需要使用自定义的embeddedLaunchScript
.
2.2. Unix/Linux 服务
init.d
Spring Boot 应用程序可以通过使用或轻松启动为 Unix/Linux 服务systemd
。
2.2.1. 作为 init.d 服务安装(系统 V)
如果您配置了 Spring Boot 的 Maven 或 Gradle 插件来生成完全可执行的 jar,并且您不使用自定义embeddedLaunchScript
,则您的应用程序可以用作服务init.d
。为此,请将 jar 符号链接到init.d
以支持标准start
、stop
、restart
和status
命令。
该脚本支持以下功能:
-
以拥有 jar 文件的用户身份启动服务
-
使用以下方式跟踪应用程序的 PID
/var/run/<appname>/<appname>.pid
-
将控制台日志写入
/var/log/<appname>.log
假设您已经安装了 Spring Boot 应用程序/var/myapp
,要将 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 应用程序root
,因此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
2.2.2. 作为 systemd 服务安装
systemd
是 System V init 系统的后继者,现在被许多现代 Linux 发行版所使用。尽管您可以继续使用init.d
脚本systemd
,但也可以使用systemd
“服务”脚本启动 Spring Boot 应用程序。
假设您在 中安装了 Spring Boot 应用程序/var/myapp
,要将 Spring Boot 应用程序安装为systemd
服务,请创建一个名为 的脚本myapp.service
并将其放置在/etc/systemd/system
目录中。以下脚本提供了一个示例:
[Unit] Description=myapp After=syslog.target [Service] User=myapp ExecStart=/var/myapp/myapp.jar SuccessExitStatus=143 [Install] WantedBy=multi-user.target
请记住更改您的应用程序的Description 、User 和ExecStart 字段。
|
该ExecStart 字段没有声明脚本动作命令,即run 默认使用该命令。
|
请注意,与作为服务运行时不同init.d
,运行应用程序的用户、PID 文件和控制台日志文件由其自身管理systemd
,因此必须使用“service”脚本中的适当字段进行配置。有关更多详细信息,请参阅服务单元配置手册页。
要将应用程序标记为在系统启动时自动启动,请使用以下命令:
$ systemctl enable myapp.service
运行man systemctl
以获取更多详细信息。
2.2.3. 自定义启动脚本
Maven 或 Gradle 插件编写的默认嵌入式启动脚本可以通过多种方式进行自定义。对于大多数人来说,使用默认脚本和一些自定义通常就足够了。如果您发现无法自定义所需的内容,请使用该embeddedLaunchScript
选项完全编写自己的文件。
编写启动脚本时对其进行自定义
当启动脚本写入 jar 文件时,自定义启动脚本的元素通常是有意义的。例如,init.d 脚本可以提供“描述”。由于您预先知道描述(并且不需要更改),因此您也可以在生成 jar 时提供它。
要自定义编写的元素,请使用embeddedLaunchScriptProperties
Spring Boot Maven 插件的选项或properties
Spring Boot Gradle 插件的launchScript
.
默认脚本支持以下属性替换:
姓名 | 描述 | Gradle 默认值 | Maven默认值 |
---|---|---|---|
|
脚本模式。 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
单行版本 |
|
|
|
|
|
|
|
|
|
|
默认值为 |
包含 jar 的文件夹 |
包含 jar 的文件夹 |
|
对应内联到默认启动脚本中的文件脚本的引用。这可用于设置环境变量,例如 |
||
|
的默认值 |
||
|
的默认值 |
||
|
的默认值 |
||
|
中 PID 文件名称的默认值 |
||
|
当该命令可用时,是否 |
|
|
|
默认值以 |
60 |
60 |
在脚本运行时自定义脚本
对于编写jar后需要自定义的脚本项目,可以使用环境变量或配置文件。
默认脚本支持以下环境属性:
多变的 | 描述 |
---|---|
|
操作的“模式”。默认值取决于 jar 的构建方式,但通常是 |
|
将用于运行应用程序的用户。如果未设置,将使用拥有 jar 文件的用户。 |
|
当该 |
|
pid 文件夹的根名称( |
|
放置日志文件的文件夹的名称( |
|
从中读取 .conf 文件的文件夹的名称(默认情况下与 jar 文件相同的文件夹)。 |
|
中的日志文件的名称 |
|
应用程序的名称。如果 jar 是从符号链接运行的,则脚本会猜测应用程序名称。如果它不是符号链接或者您想显式设置应用程序名称,这可能很有用。 |
|
要传递给程序(Spring Boot 应用程序)的参数。 |
|
|
|
启动 JVM 时传递给 JVM 的选项。 |
|
jar 文件的显式位置,以防脚本用于启动实际上未嵌入的 jar。 |
|
如果不为空,则 |
|
在强制关闭之前停止应用程序时等待的时间(以秒 |
PID_FOLDER 、LOG_FOLDER 和
变量LOG_FILENAME 仅对init.d 服务有效。对于systemd ,通过使用“service”脚本进行等效的自定义。有关更多详细信息,
请参阅服务单元配置手册页。 |
除JARFILE
和之外APP_NAME
,上一节中列出的设置都可以使用.conf
文件进行配置。该文件预计位于 jar 文件旁边,并且具有相同的名称,但后缀为.conf
而不是.jar
. 例如,名为 的 jar/var/myapp/myapp.jar
使用名为 的配置文件/var/myapp/myapp.conf
,如以下示例所示:
JAVA_OPTS=-Xmx1024M LOG_FOLDER=/custom/log/folder
如果您不喜欢将配置文件放在 jar 文件旁边,可以设置CONF_FOLDER 环境变量来自定义配置文件的位置。
|
要了解如何适当地保护此文件,请参阅保护 init.d 服务的指南。
3. 高效部署
3.1. 解压可执行 JAR
如果您从容器运行应用程序,则可以使用可执行 jar,但分解它并以不同的方式运行它通常也是一个优势。某些 PaaS 实现也可能选择在运行之前解压存档。例如,Cloud Foundry 就是这样运作的。运行解压存档的一种方法是启动适当的启动器,如下所示:
$ jar -xf myapp.jar
$ java org.springframework.boot.loader.JarLauncher
这实际上比从未分解的存档运行要快一些(取决于 jar 的大小)。启动后,您不应期望出现任何差异。
解压 jar 文件后,您还可以通过使用其“自然”main 方法而不是JarLauncher
. 例如:
$ jar -xf myapp.jar
$ java -cp "BOOT-INF/classes:BOOT-INF/lib/*" com.example.MyApplication
在应用程序的 main 方法上使用JarLauncher 具有可预测的类路径顺序的额外好处。该 jar 包含一个在构造类路径时classpath.idx 使用的文件JarLauncher 。
|
3.2. 使用 JVM 进行提前处理
使用 AOT 生成的初始化代码运行应用程序有利于启动时间。首先,您需要确保正在构建的 jar 包含 AOT 生成的代码。
对于 Maven,这意味着您应该构建-Pnative
以激活native
配置文件:
$ mvn -Pnative package
对于 Gradle,您需要确保您的构建包含该org.springframework.boot.aot
插件。
构建 JAR 后,将spring.aot.enabled
系统属性设置为 来运行它true
。例如:
$ java -Dspring.aot.enabled=true -jar myapplication.jar
........ Starting AOT-processed MyApplication ...
请注意,使用提前处理有缺点。它意味着以下限制:
-
类路径是固定的,并在构建时完全定义
-
应用程序中定义的 bean 不能在运行时更改,这意味着:
-
Spring
@Profile
注释和特定于配置文件的配置有局限性。 -
不支持在创建 bean 时更改的属性(例如
@ConditionalOnProperty
和.enable
属性)。
-
要了解有关提前处理的更多信息,请参阅了解 Spring 提前处理部分。
4. 接下来读什么
有关 PaaS 可以提供的功能类型的更多信息,请参阅Cloud Foundry、Heroku、OpenShift和Boxfuse网站。这些只是四个最流行的 Java PaaS 提供商。由于 Spring Boot 非常适合基于云的部署,因此您也可以自由考虑其他提供商。
下一节将继续介绍GraalVM 本机映像,或者您可以直接阅读有关Spring Boot CLI或我们的构建工具插件的内容。