本站(springdoc.cn)中的内容来源于 spring.io ,原始版权归属于 spring.io。由 springdoc.cn 进行翻译,整理。可供个人学习、研究,未经许可,不得进行任何转载、商用或与之相关的行为。 商标声明:Spring 是 Pivotal Software, Inc. 在美国以及其他国家的商标。

Spring Boot灵活的打包选项在部署应用程序时提供了大量的选择。 你可以将Spring Boot应用程序部署到各种云平台、虚拟/真实机器上,或者让它们在Unix系统上完全可执行。

本节涵盖了一些比较常见的部署场景。

1. 部署到云

Spring Boot的可执行jar是为大多数流行的云PaaS(平台即服务)提供商准备的。这些供应商往往要求你 "自带容器"。他们管理应用进程(而不是具体的Java应用),所以他们需要一个中间层,使你的应用适应云的运行进程的概念。

两个流行的云供应商,Heroku和Cloud Foundry,采用了 “buildpack” (构建包)方法。构建包将你部署的代码包裹在启动你的应用程序所需的任何东西中。它可能是一个JDK和对 java 的调用,一个嵌入式Web服务器,或一个成熟的应用服务器。构建包是可插拔的,但理想情况下,你应该能够尽可能少地对它进行定制。这可以减少不在你控制范围内的功能的足迹。它最大限度地减少了开发和生产环境之间的差异。

理想情况下,你的应用程序就像Spring Boot可执行的jar一样,有它需要运行的所有东西被打包在里面。

在这一节中,我们将看看如何使我们在 “Getting Started” 部分开发的应用程序在云中运行。

1.1. Cloud Foundry

Cloud Foundry 提供了默认的构建包,如果没有指定其他构建包,这些构建包就会发挥作用。Cloud Foundry Java buildpack 对 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 文档。如果同一目录中存在 Cloud Foundry manifest.yml 文件,则会考虑该文件。

此时,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 的 polyglot(任何语言和平台都可以作为构建包得到支持)性质。 进程范围内的环境变量是不分语言的。

环境变量并不总是最简单的API,所以Spring Boot会自动提取它们,并将数据扁平化为可以通过Spring的 Environment 抽象来访问的属性,如下面的例子所示。

Java
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");
    }

    // ...

}
Kotlin
import org.springframework.context.EnvironmentAware
import org.springframework.core.env.Environment
import org.springframework.stereotype.Component

@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. Kubernetes

Spring Boot通过检查环境中的 "*_SERVICE_HOST" 和 "*_SERVICE_PORT" 变量,自动检测Kubernetes部署环境。 你可以用 spring.main.cloud-platform 配置属性覆盖这种检测。

1.2.1. Kubernetes容器的生命周期

当Kubernetes删除一个应用实例时,关闭过程同时涉及几个子系统:关闭hook、取消注册服务、从负载均衡器中移除实例…​…​ 由于这种关闭处理是平行发生的(并且由于分布式系统的性质),有一个窗口,在此期间,流量可以被路由到也已经开始其关闭处理的pod。

你可以在preStop处理程序中配置一个sleep 执行,以避免请求被路由到一个已经开始关闭的pod。 这个睡眠时间应该足够长,以便新的请求不再被路由到pod,其持续时间将因部署而异。 preStop处理程序可以通过在pod的配置文件中使用PodSpec来配置,如下所示。

spec:
  containers:
  - name: "example-container"
    image: "example-image"
    lifecycle:
      preStop:
        exec:
          command: ["sh", "-c", "sleep 10"]

一旦预停止钩子(pre-stop hook)完成,SIGTERM将被发送到容器,优雅的关闭将开始,允许任何剩余的执行中的请求完成。

当Kubernetes向pod发送一个SIGTERM信号时,它会等待一个指定的时间,称为终止宽限期(默认为30秒)。如果容器在宽限期过后仍在运行,它们会被发送SIGKILL信号并被强制删除。如果pod的关闭时间超过30秒,这可能是因为你增加了 spring.lifecycle.timeout-per-shutdown-phase ,确保通过设置Pod YAML中的 terminationGracePeriodSeconds 选项来增加终止宽限期。

1.3. Heroku

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

你必须配置你的应用程序以监听正确的端口。 下面的例子显示了我们的入门REST应用程序的 Procfile。

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

Spring Boot将 -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... 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 git@heroku.com:agile-sierra-1405.git
 * [new branch]      main -> main

你的应用程序现在应该已经在Heroku上运行了。更多细节,请参见 将Spring Boot应用部署到Heroku。

1.4. OpenShift

OpenShift 有很多资源介绍了如何部署Spring Boot应用程序,包括。

1.5. Amazon Web Services (AWS)

亚马逊网络服务提供了多种方式来安装基于Spring Boot的应用程序,可以是传统的网络应用程序(war),也可以是嵌入网络服务器的可执行jar文件。 这些选项包括。

  • AWS Elastic Beanstalk

  • AWS Code Deploy

  • AWS OPS Works

  • AWS Cloud Formation

  • AWS Container Registry

每一种都有不同的功能和定价模式。 在这份文件中,我们描述了使用 AWS Elastic Beanstalk 的方法。

1.5.1. AWS Elastic Beanstalk

正如官方 Elastic Beanstalk Java指南 中所描述的那样,有两个主要的选择来部署Java应用程序。你可以使用 “Tomcat Platform” 或 “Java SE platform”。

使用 Tomcat Platform

该选项适用于产生war文件的Spring Boot项目。 不需要特别的配置。 你只需要遵循官方指南。

使用 Java SE Platform

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

server.port=5000
Upload binaries instead of sources

默认情况下,Elastic Beanstalk会在AWS中上传源代码并进行编译。 然而,最好的办法是上传二进制文件。 要做到这一点,请在你的 .elasticbeanstalk/config.yml 文件中添加类似以下的行。

deploy:
    artifact: target/demo-0.0.1-SNAPSHOT.jar
Reduce costs by setting the environment type

默认情况下,Elastic Beanstalk环境是负载均衡的。负载均衡器有很大的成本。为了避免这种成本,请将环境类型设置为 “Single instance” (单例),如 亚马逊文档 中所述。你也可以通过使用CLI和以下命令来创建单实例环境。

eb create -s

1.5.2. 总结

这是进入AWS的最简单的方法之一,但还有更多的东西需要介绍,比如如何将Elastic Beanstalk集成到任何CI/CD工具中,使用Elastic Beanstalk Maven插件而不是CLI,以及其他。有一篇 博文 更详细地介绍了这些话题。

1.6. CloudCaptain 和 Amazon Web Services

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

一旦你创建了 CloudCaptain账户,将其连接到你的AWS账户,安装了最新版本的CloudCaptain客户端,并确保应用程序已由Maven或Gradle构建(例如,通过使用 mvn clean package),你可以用类似于以下的命令将Spring Boot应用程序部署到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. Azure

本 入门指南将指导你将Spring Boot应用部署到 Azure Spring Cloud 或 Azure App Service。

1.8. Google Cloud

谷歌云有几个选项,可以用来启动Spring Boot应用程序。 最容易上手的可能是App Engine,但你也可以找到方法,用Container Engine在容器中运行Spring Boot,或用Compute Engine在虚拟机上运行。

要在App Engine中运行,你可以先在UI中创建一个项目,它为你设置了一个独特的标识符,还设置了HTTP路由。在项目中添加一个Java应用,并让它保持空白,然后使用 Google Cloud SDK,从命令行或CI构建中把你的Spring Boot应用推送到该slot(槽)中。

App Engine Standard要求你使用WAR打包。按照 这些步骤,将App Engine Standard应用程序部署到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 Boot 应用

除了通过使用 java -jar 运行Spring Boot应用程序外,还可以为Unix系统制作完全可执行的应用程序。完全可执行的jar可以像其他可执行的二进制文件一样执行,也可以用 init.d 或 systemd 注册。这有助于在普通生产环境中安装和管理Spring Boot应用程序。

完全可执行的jar通过在文件的前面嵌入一个额外的脚本来工作。目前,有些工具不接受这种格式,所以你不一定能使用这种技术。例如,jar -xf 可能会默默地无法提取一个已经被做成完全可执行的jar或war文件。建议你只有在打算直接执行你的jar或war,而不是用 java -jar 运行它或将它部署到servlet容器中时,才使它完全可执行。
一个zip64格式的jar文件不能被完全执行。 试图这样做会导致jar文件在直接执行或使用 java -jar 时被报告为损坏。 一个标准格式的jar文件包含一个或多个zip64格式的嵌套jar,可以完全执行。

要用Maven创建一个 ‘fully executable’ (完全可执行的)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 是你的artifact的名称)来运行你的应用程序。 包含jar的目录将作为你的应用程序的工作目录。

2.1. 支持的操作系统

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

2.2. Unix/Linux 服务

通过使用 init.d 或 systemd,Spring Boot应用程序可以很容易地作为Unix/Linux服务启动。

2.2.1. 作为 init.d 服务安装 (System V)

如果你将Spring Boot的Maven或Gradle插件配置为生成 完全可执行的jar,并且不使用自定义的 embeddedLaunchScript,你的应用程序就可以作为 init.d 服务使用。为此,将jar链接到 init.d,以支持标准的 start、 stop、 restart`和 `status 命令。

该脚本支持以下功能。

  • 以拥有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

2.2.2. 作为 systemd 服务安装

systemd 是System V init系统的后继者,现在很多现代Linux发行版都在使用。 虽然你可以继续使用 init.d 脚本与 systemd,但也可以通过使用 systemd ‘service’ 脚本来启动Spring Boot应用程序。

假设你在 /var/myapp 中安装了一个Spring Boot应用,要把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脚本可以提供一个 “description”。 既然你预先知道了描述(而且不需要改变),你也可以在生成jar时提供它。

要自定义写入的元素,请使用Spring Boot Maven插件的 embeddedLaunchScriptProperties 选项或 Spring Boot Gradle插件的 launchScript 的 properties 属性。

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

Name 说明 Gradle 默认 Maven 默认

mode

脚本模式。

auto

auto

initInfoProvides

“INIT INFO” 的 Provides 部分

${task.baseName}

${project.artifactId}

initInfoRequiredStart

“INIT INFO” 的 Required-Start 部分。

$remote_fs $syslog $network

$remote_fs $syslog $network

initInfoRequiredStop

“INIT INFO” 的 Required-Stop 部分。

$remote_fs $syslog $network

$remote_fs $syslog $network

initInfoDefaultStart

“INIT INFO” 的 Default-Start 部分。

2 3 4 5

2 3 4 5

initInfoDefaultStop

“INIT INFO” 的 Default-Stop 部分。

0 1 6

0 1 6

initInfoShortDescription

“INIT INFO” 的 Short-Description 部分。

Single-line version of ${project.description} (falling back to ${task.baseName})

${project.name}

initInfoDescription

“INIT INFO” 的 Description 部分。

${project.description} (falling back to ${task.baseName})

${project.description} (falling back to ${project.name})

initInfoChkconfig

“INIT INFO” 的 chkconfig 部分

2345 99 01

2345 99 01

confFolder

CONF_FOLDER 的默认值。

Folder containing the jar

Folder containing the jar

inlinedConfScript

对一个文件脚本的引用,该脚本应被内联到默认的启动脚本中。这可以用来在加载任何外部配置文件之前设置环境变量,如 JAVA_OPTS。

logFolder

LOG_FOLDER 的默认值。 Only valid for an init.d service

logFilename

LOG_FILENAME 的默认值。 Only valid for an init.d service

pidFolder

PID_FOLDER 的默认值。 Only valid for an init.d service

pidFilename

PID_FOLDER 中的PID文件名的默认值。 只对 init.d 服务有效。

useStartStopDaemon

当 start-stop-daemon 命令可用时,是否应使用该命令来控制进程。

true

true

stopWaitTime

STOP_WAIT_TIME 的默认值(秒)。 只对 init.d 服务有效。

60

60

脚本运行时的自定义

对于脚本中需要在写完jar后进行定制的项目,你可以使用环境变量或配置文件。

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

Variable 说明

MODE

操作的 “mode”。 默认情况取决于jar的构建方式,但通常是 auto(自动)(意味着它试图通过检查它是否是一个名为 init.d 目录下的符号链接来猜测它是否是一个init脚本)。 你可以明确地把它设置为 service,这样 stop|start|status|restart 命令就会起作用,如果你想在前台运行脚本,就可以设置为 run。

RUN_AS_USER

将用于运行应用程序的用户。 如果不设置,将使用拥有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 Boot应用程序)的参数。

JAVA_HOME

默认情况下,java 可执行文件的位置是通过使用 PATH 发现的,但如果在 $JAVA_HOME/bin/java 有一个可执行文件,你可以明确设置它。

JAVA_OPTS

当JVM启动时传递给它的选项。

JARFILE

jar文件的明确位置,以防脚本被用来启动一个它实际上没有嵌入的jar。

DEBUG

如果不是空的,在shell进程中设置 -x 标志,允许你看到脚本中的逻辑。

STOP_WAIT_TIME

停止应用程序时,在强制关机前等待的时间(以秒为单位)(默认为 60)。

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 的配置文件,如以下例子所示。

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

要了解如何适当地保护这个文件,请参阅保护init.d服务的指南。

2.3. 微软的Windows服务

通过使用 winsw,Spring Boot应用程序可以作为一个Windows服务启动。

这篇文章( 单独保存的样本)介绍了如何为Spring Boot应用程序创建一个Windows服务的步骤。

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 有一个额外的好处,即可预测的classpath顺序。jar包含一个 classpath.idx 文件,它被 JarLauncher 在构建classpath时使用。

3.2. 用JVM进行前向(Ahead-of-time)处理

使用AOT生成的初始化代码来运行你的应用程序,对启动时间很有好处。首先,你需要确保你正在构建的jar包含AOT生成的代码。

对于Maven来说,这意味着你应该用 -Pnative 进行构建,以激活 native profile:

$ 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 ...

请注意,使用超前处理有缺点。它意味着以下的限制:

  • classpath是固定的,在构建时完全定义。

  • 你的应用程序中定义的Bean不能在运行时改变,也就是说:

    • Spring 的 @Profile 注解和特定 profile 的配置 有其局限性。

    • 不支持创建Bean时发生变化的 Properties(例如,@ConditionalOnProperty 和 .enable 属性)。

要了解更多关于超前处理的信息,请参见 了解 Spring Ahead-of-Time 处理部分。

4. 接下来读什么

关于PaaS所能提供的各种功能的更多信息,请参见 Cloud Foundry、 Heroku、 OpenShift 和 Boxfuse 的网站。这些只是最受欢迎的四个Java PaaS供应商。由于Spring Boot非常适用于基于云的部署,你也可以自由考虑其他供应商。

下一节将继续介绍 原生镜像 ,或者你可以跳到前面阅读 Spring Boot CLI 或我们的 构建插件。