# 部署 Spring 引导应用程序

Spring 在部署应用程序时,Boot 的灵活打包选项提供了很多选择。你可以将 Spring 引导应用程序部署到各种云平台,部署到虚拟机/真机,或者使它们在 UNIX 系统中完全可执行。

本节将介绍一些更常见的部署场景。

# 1. 部署到云上

Spring Boot 的可执行 JAR 已经为大多数流行的云 PaaS(Platform-as-a-Service,即平台即服务)提供商准备好了。这些供应商往往要求你“带上自己的容器”。它们管理应用程序进程(而不是专门的 Java 应用程序),因此它们需要一个中间层,将你的应用程序适应于运行进程的Cloud’s概念。

Heroku 和 Cloud Foundry 这两家颇受欢迎的云供应商采用了一种“BuildPack”方法。BuildPack 将部署的代码封装在应用程序开始所需的任何内容中。它可能是一个 JDK 和对java的调用、一个嵌入式 Web 服务器或一个成熟的应用程序服务器。BuildPack 是可插入的,但在理想情况下,你应该能够通过尽可能少的自定义来实现它。这减少了不在你控制范围内的功能的占用。它最大限度地减少了开发环境和生产环境之间的差异。

理想情况下,你的应用程序,比如 Spring 可执行的引导程序 jar,包含了在其中运行所需的所有内容。

在这一部分中,我们将研究如何在“Getting Started”部分中获得我们开发的应用程序并在云中运行。

# 1.1.Cloud Foundry

Cloud Foundry 提供了默认的构建包,如果没有指定其他构建包,这些构建包就会发挥作用。Cloud FoundryJava BuildPack (opens new window)对 Spring 应用程序具有出色的支持,包括 Spring 启动。你可以部署独立的可执行应用程序以及传统的.war打包应用程序。

一旦你构建了你的应用程序(例如,通过使用mvn clean package)并[安装了cf命令行工具](https://DOCS.cloudfoundry.org/cf-cli/install-go-cli.html),就可以使用cf push命令部署你的应用程序,并替换到你编译的.jar的路径。在推送应用程序之前,一定要[用cf命令行客户端登录](https://DOCS.cloudfoundry.org/cf-cli/getting-started.html#login)。下面的一行显示了使用cf push命令部署应用程序的情况:

$ cf push acloudyspringtime -p target/demo-0.0.1-SNAPSHOT.jar
在前面的示例中,我们用acloudyspringtime替换你给出的任何值cf作为应用程序的名称。

有关更多选项,请参见[cf push文档](https://DOCS.cloudfoundry.org/cf-cli/getting-started.html#push)。如果在同一目录中存在一个 Cloud Foundry[manifest.yml](https://DOCS.cloudfoundry.org/devguide/deploy-apps/manifest.html)文件,则将考虑该文件。

此时,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 1.8.0_121 from https://java-buildpack.cloudfoundry.org/openjdk/trusty/x86_64/openjdk-1.8.0_121.tar.gz (found in cache)
       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 的多语种(任何语言和平台都可以作为 buildpack 支持)的特性。过程范围的环境变量与语言无关。

环境变量并不总是最简单的 API,因此 Spring 引导会自动提取它们,并将数据平坦化为可通过 Spring 的Environment抽象访问的属性,如以下示例所示:

import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

@Component
public class MyBean implements EnvironmentAware {

    private String instanceId;

    @Override
    public void setEnvironment(Environment environment) {
        this.instanceId = environment.getProperty("vcap.application.instance_id");
    }

    // ...

}

所有 Cloud Foundry 属性的前缀都是vcap。你可以使用vcap属性来访问应用程序信息(例如应用程序的公共 URL)和服务信息(例如数据库凭据)。有关完整的详细信息,请参见“CloudFoundryVCapEnvironmentPostProcessor” (opens new window)Javadoc。

Java CFEnv (opens new window)项目更适合于配置数据源等任务。

# 1.2.库贝内特斯

Spring 通过检查"*_SERVICE_HOST""*_SERVICE_PORT"变量的环境,引导自动检测 Kubernetes 部署环境。你可以使用spring.main.cloud-platform配置属性重写此检测。

Spring Boot 帮助你管理应用程序的状态并用使用致动器的 HTTP Kubernetes 探测导出它。

# 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 秒,这可能是因为你增加了spring.lifecycle.timeout-per-shutdown-phase,请确保通过在 POD YAML 中设置terminationGracePeriodSeconds选项来增加终止宽限期。

# 1.3.赫罗库

Heroku 是另一个流行的 PaaS 平台。为了定制 Heroku 构建,你提供了Procfile,它提供了部署应用程序所需的咒语。Heroku 为 Java 应用程序分配一个port,然后确保对外部 URI 的路由工作。

你必须配置你的应用程序以侦听正确的端口。下面的示例显示了我们的 Starter REST 应用程序的Procfile:

web: java -Dserver.port=$PORT -jar target/demo-0.0.1-SNAPSHOT.jar

Spring 引导使-D参数作为可从 Spring Environment实例访问的属性可用。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 1.8... done
-----> Installing Maven 3.3.1... 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 上启动并运行了。有关更多详细信息,请参见Deploying Spring Boot Applications to Heroku (opens new window)

# 1.4.OpenShift

OpenShift (opens new window)有许多资源描述如何部署 Spring 引导应用程序,包括:

# 1.5.亚马逊网络服务

Amazon Web Services 提供了多种方式来安装 Spring 基于启动的应用程序,既可以是传统的 Web 应用程序,也可以是带有嵌入式 Web 服务器的可执行文件 jar。这些选择包括:

  • AWS 弹性豆茎

  • AWS 代码部署

  • AWS Ops Works

  • AWS 云形成

  • AWS 容器注册表

每一种都有不同的特点和定价模式。在本文中,我们描述了使用 AWS 弹性豆茎的方法。

# 1.5.1.AWS 弹性豆茎

正如在官方Elastic Beanstalk Java 指南 (opens new window)中所描述的,部署 Java 应用程序有两个主要选项。你可以使用“ Tomcat 平台”或“Java SE 平台”。

# 使用 Tomcat 平台

此选项适用于生成 WAR 文件的 Spring 引导项目。不需要特殊配置。你只需要按照官方的指南去做就行了。

# 使用 Java SE 平台

此选项适用于生成 jar 文件并运行嵌入式 Web 容器的 Spring 引导项目。Elastic Beanstalk 环境在端口 80 上运行一个 Nginx 实例,以代理在端口 5000 上运行的实际应用程序。要配置它,请在application.properties文件中添加以下行:

server.port=5000
上传二进制文件,而不是源文件

默认情况下,Elastic Beanstalk 上传源文件并在 AWS 中进行编译。
但是,最好是上传二进制文件。
要做到这一点,在你的.elasticbeanstalk/config.yml文件中添加类似于以下的行:
<br/>deploy:<br/> artifact: target/demo-0.0.1-SNAPSHOT.jar<br/>
通过设置环境类型

来降低成本,默认情况下,弹性 Beanstalk 环境是负载平衡的,
负载平衡器有很大的成本,
为了避免这种成本,请将环境类型设置为“单实例”,如亚马逊文档 (opens new window)中所述,
还可以通过使用 CLI 和以下命令创建单个实例环境:

<br/>eb create -s<br/>

# 1.5.2.摘要

这是访问 AWS 的最简单的方法之一,但还有更多的事情要做,例如如何将 Elastic Beanstalk 集成到任何 CI/CD 工具中,使用 Elastic Beanstalk Maven 插件而不是 CLI,等等。有一个blog post (opens new window)更详细地介绍了这些主题。

# 1.6.CloudCaptain 和亚马逊网络服务

CloudCaptain (opens new window)的工作原理是将你的 Spring 引导可执行文件 jar 或 WAR 转换为一个最小的 VM 映像,该映像可以在 VirtualBox 或 AWS 上不变地部署。CloudCaptain 具有用于 Spring 引导的深度集成,并使用来自 Spring 引导配置文件的信息来自动配置端口和健康检查 URL。CloudCaptain 为它生成的映像以及它提供的所有资源(实例、安全组、弹性负载均衡器等)利用了这些信息。

一旦你创建了CloudCaptain 帐户 (opens new window),将其连接到你的 AWS 帐户,安装最新版本的 CloudCaptain 客户端,并确保该应用程序已由 Maven 或 Gradle 构建(例如,通过使用mvn clean package),你可以使用类似于以下的命令将 Spring 引导应用程序部署到 AWS:

$ boxfuse run myapp-1.0.jar -env=prod

有关更多选项,请参见[boxfuse run文档](https://cloudcaptain.sh/DOCS/commandline/run.html)。如果当前目录中存在[boxfuse.conf](https://cloudcaptain.sh/DOCS/commandline/#configuration)文件,则考虑该文件。

默认情况下,CloudCaptain 在启动时激活一个名为boxfuse的 Spring 配置文件。
如果你的可执行文件 jar 或战争包含一个[application-boxfuse.properties](https://cloudcaptain.sh/DOCS/payloads/springboot.html#configuration)文件,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 上运行。

请参阅deploying Spring Boot apps on EC2 (opens new window)上的博客文章以及documentation for the CloudCaptain Spring Boot integration (opens new window),以开始使用 Maven 构建来运行该应用程序。

# 1.7.天蓝色

入门指南 (opens new window)将引导你将 Spring 引导应用程序部署到Azure Spring Cloud (opens new window)Azure 应用程序服务 (opens new window)

# 1.8.谷歌云

Google Cloud 有几种可用于启动 Spring 启动应用程序的选项。最容易开始使用的可能是 App Engine,但你也可以找到在带有容器引擎的容器中或在带有计算引擎的虚拟机上运行 Spring boot 的方法。

要在 App Engine 中运行,你可以首先在 UI 中创建一个项目,该项目为你设置唯一的标识符,还可以设置 HTTP 路由。将一个 Java 应用程序添加到项目中,并将其保持为空,然后使用Google Cloud SDK (opens new window)将你的 Spring 启动应用程序从命令行或 CI 构建推入该插槽。

App Engine 标准要求你使用战争包装。按照这些步骤 (opens new window)将 App Engine 标准应用程序部署到 Google Cloud。

或者,App Engine Flex 要求你创建app.yaml文件来描述应用程序所需的资源。通常,将此文件放入src/main/appengine,它应该类似于以下文件:

service: "default"

runtime: "java"
env: "flex"

runtime_config:
  jdk: "openjdk8"

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>1.3.0</version>
    <configuration>
        <project>myproject</project>
    </configuration>
</plugin>

然后使用mvn appengine:deploy进行部署(如果需要首先进行身份验证,则生成失败)。

# 2. 安装 Spring 启动应用程序

Spring 除了通过使用java -jar运行启动应用程序外,还可以为 UNIX 系统制作完全可执行的应用程序。完全可执行的 jar 可以像任何其他可执行的二进制文件一样执行,也可以[注册为init.dsystemd](#deployment.installing.nix-services)。这有助于在公共生产环境中安装和管理 Spring 引导应用程序。

完全可执行的 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 配置:

bootJar {
    launchScript()
}

然后,你可以通过输入./my-application.jar(其中my-application是工件的名称)来运行应用程序。包含 jar 的目录用作应用程序的工作目录。

# 2.1.支持的操作系统

默认脚本支持大多数 Linux 发行版,并在 Centos 和 Ubuntu 上进行测试。其他平台,如 OS X 和 FreeBSD,需要使用自定义embeddedLaunchScript

# 2.2.Unix/Linux 服务

Spring 通过使用init.dsystemd,启动应用程序可以很容易地作为 UNIX/Linux 服务启动。

# 2.2.1.作为 init.d 服务(系统 V)安装

如果你将 Spring boot 的 Maven 或 Gradle 插件配置为生成fully executable jar,并且不使用自定义的embeddedLaunchScript,那么你的应用程序可以用作init.d服务。为此,将 jar 符号链接到init.d以支持标准startstoprestartstatus命令。

该脚本支持以下功能:

  • 作为 OWNS jar 文件的用户启动服务

  • 使用/var/run/<appname>/<appname>.pid跟踪应用程序的 PID

  • 将控制台日志写入/var/log/<appname>.log

假设在/var/myapp中安装了 Spring 引导应用程序,要将 Spring 引导应用程序安装为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 引导应用程序的一组指导原则。
它并不是要详尽列出所有应该做的事情,以加强应用程序及其运行的环境。

当作为 root 执行时,就像使用 root 启动 init.d 服务时一样,默认的可执行脚本以RUN_AS_USER环境变量中指定的用户的身份运行应用程序。当环境变量未被设置时,OWNS 该 jar 文件的用户被用来代替。永远不应该将 Spring 引导应用程序运行为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

这将阻止任何用户(包括根用户)修改 jar。

如果使用 root 来控制应用程序的服务,并且你[使用.conf文件](#deployment.installing.nix-services.script-customization.when-running.conf-file)来定制其启动,则根用户将读取.conf文件并对其进行评估。它应该得到相应的保护。使用chmod使文件只能由所有者读取,并使用chown使根用户成为所有者,如以下示例所示:

$ 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’service’脚本启动 Spring 启动应用程序。

假设在/var/myapp中安装了 Spring 引导应用程序,要将 Spring 引导应用程序安装为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
请记住更改应用程序的DescriptionUserExecStart字段。
ExecStart字段不声明脚本操作命令,这意味着默认情况下使用run命令。

请注意,与作为init.d服务运行不同,运行应用程序的用户、PID 文件和控制台日志文件由systemd本身管理,因此必须通过在“服务”脚本中使用适当的字段进行配置。有关更多详细信息,请咨询服务单元配置手册页 (opens new window)

要标记应用程序在系统启动时自动启动,请使用以下命令:

$ systemctl enable myapp.service

运行man systemctl获取更多详细信息。

# 2.2.3.自定义启动脚本

由 Maven 或 Gradle 插件编写的默认嵌入式启动脚本可以通过多种方式进行定制。对于大多数人来说,使用默认脚本并进行一些自定义通常就足够了。如果你发现无法自定义你需要的内容,请使用embeddedLaunchScript选项完全编写自己的文件。

# 在编写开始脚本时自定义

当开始脚本被写入 jar 文件时,定制它的元素通常是有意义的。例如,init.d 脚本可以提供一个“描述”。由于你预先知道描述(并且它不需要更改),因此在生成 jar 时也可以提供它。

要定制编写的元素,可以使用 Spring boot Maven 插件的embeddedLaunchScriptProperties选项或 Spring boot Gradle 插件的properties属性launchScript](https://DOCS. Spring.io/ Spring-boot/DOCS/2.6.4/ Gradle-plugin/reference/htmlsinger/#packaging-executable-configing-ling-launation-launch-script)。

默认脚本支持以下属性替换:

Name 说明 Gradle default Maven default
mode 脚本模式。 auto auto
initInfoProvides “init info”的Provides部分 ${task.baseName} ${project.artifactId}
initInfoRequiredStart Required-Start“init info”部分。 $remote_fs $syslog $network $remote_fs $syslog $network
initInfoRequiredStop Required-Stop“init info”部分。 $remote_fs $syslog $network $remote_fs $syslog $network
initInfoDefaultStart Default-Start“init info”部分。 2 3 4 5 2 3 4 5
initInfoDefaultStop Default-Stop“init info”部分。 0 1 6 0 1 6
initInfoShortDescription Short-Description“init info”部分。 Single-line version of ${project.description} (falling back to ${task.baseName}) ${project.name}
initInfoDescription Description“init info”部分。 ${project.description} (falling back to ${task.baseName}) ${project.description} (falling back to ${project.name})
initInfoChkconfig chkconfig“init info”部分 2345 99 01 2345 99 01
confFolder CONF_FOLDER的默认值 Folder containing the jar Folder containing the jar
inlinedConfScript 引用在默认启动脚本中应该内联的文件脚本。
在加载任何外部配置文件之前,这可以用于设置环境变量,例如JAVA_OPTS
logFolder LOG_FOLDER的默认值。
仅对init.d服务有效
logFilename LOG_FILENAME的默认值。
仅对init.d服务有效
pidFolder PID_FOLDER的默认值。
仅对init.d服务有效
pidFilename PID_FOLDER中 PID 文件名称的默认值。
仅对init.d服务有效
useStartStopDaemon start-stop-daemon命令可用时,是否应该使用它来控制进程 true true
stopWaitTime STOP_WAIT_TIME的默认值(以秒为单位)。
仅对init.d服务有效
60 60
# 在脚本运行时自定义脚本

对于需要自定义之后 jar 已编写的脚本的项,可以使用环境变量或配置文件

默认脚本支持以下环境属性:

Variable 说明
MODE 操作的“模式”。
默认值取决于构建 jar 的方式,但通常是auto(这意味着它试图通过检查来猜测它是否是一个 init 脚本)如果它是一个名为init.d的目录中的符号链接)。
你可以显式地将它设置为service,这样 stop|start|status|restart commands work or to run if you want to run the script in the foreground.
RUN_AS_USER 将用于运行该应用程序的用户。
当未设置时,将使用 OWNS jar 文件的用户。
USE_START_STOP_DAEMON 是否应该使用start-stop-daemon命令来控制进程。
默认为true
PID_FOLDER PID 文件夹的根名(默认情况下/var/run)。
LOG_FOLDER 将日志文件放入其中的文件夹名称(默认情况下/var/log)。
CONF_FOLDER 读取.conf 文件的文件夹的名称(默认情况下与 jar-file 文件相同)。
LOG_FILENAME LOG_FOLDER(默认情况下<appname>.log)中的日志文件的名称。
APP_NAME 应用程序的名称。
如果 jar 是从符号链接运行的,则脚本将猜测应用程序的名称。
如果不是符号链接,或者你希望显式设置应用程序名称,这将非常有用。
RUN_ARGS 要传递给程序( Spring 引导应用程序)的参数。
JAVA_HOME 默认情况下,java可执行文件的位置是通过使用PATH发现的,但是如果在$JAVA_HOME/bin/java处有一个可执行文件,则可以显式地设置它。
JAVA_OPTS 在 JVM 启动时传递给它的选项。
JARFILE jar 文件的明确位置,以防该脚本被用来启动一个 jar 文件,该 jar 文件实际上并未被嵌入。
DEBUG 如果不是空的,则在 shell 进程上设置-x标志,允许你查看脚本中的逻辑。
STOP_WAIT_TIME 在强制关机之前停止应用程序所需的等待时间(默认情况下60)。
PID_FOLDERLOG_FOLDER,和LOG_FILENAME变量仅对init.d服务有效。
对于systemd,通过使用’service’脚本进行等效的定制。有关更多详细信息,请参见<234r="232"/>。

除了JARFILEAPP_NAME之外,可以使用.conf文件配置上一节中列出的设置。该文件预计将位于 jar 文件的旁边,并且具有相同的名称,但后缀为.conf,而不是.jar。例如,名为/var/myapp/myapp.jar的 jar 使用名为/var/myapp/myapp.conf的配置文件,如以下示例所示:

myapp.conf

JAVA_OPTS=-Xmx1024M
LOG_FOLDER=/custom/log/folder
如果不喜欢将配置文件放在 jar 文件旁边,则可以设置CONF_FOLDER环境变量来定制配置文件的位置。

要了解如何适当地保护此文件,请参见获得 init.d 服务的指导方针

# 2.3.Microsoft Windows 服务

Spring 启动应用程序可以通过使用[winsw]作为 Windows 服务启动。

a(单独维护的样本 (opens new window))逐步描述了如何为 Spring 引导应用程序创建 Windows 服务。

# 3. 接下来要读什么?

有关 PaaS 可以提供的特性的更多信息,请参见Cloud Foundry (opens new window)Heroku (opens new window)OpenShift (opens new window)Boxfuse (opens new window)网站。这些只是最受欢迎的 Java PaaS 提供商中的四个。由于 Spring 启动非常适合基于云的部署,因此你也可以自由地考虑其他提供商。

下一节继续介绍 Spring Boot CLI,或者你可以提前阅读有关 构建工具插件 的内容。