在部署应用程序时,Spring Boot 的灵活打包选项提供了大量选择。您可以将 Spring Boot 应用程序部署到各种云平台、虚拟机/真实机上,或者使它们完全可执行 Unix 系统。
1. 部署到云端
Spring Boot 的可执行 jar 已为大多数流行的云 PaaS(平台即服务)提供商提供了现成的。这些提供商倾向于要求您“自带容器”。他们管理应用程序进程(不是专门的 Java 应用程序),因此他们需要一个中间层,使您的应用程序适应云中运行进程的概念。
两个流行的云提供商 Heroku 和 Cloud Foundry 采用“buildpack”方法。buildpack 将您部署的代码包装在启动应用程序所需的任何内容中。它可能是 JDK 和对 的调用java
、嵌入式 Web 服务器或成熟的应用程序服务器。buildpack 是可插入的,但理想情况下,您应该能够对它进行尽可能少的定制。这减少了不受您控制的功能的占用。它最大限度地减少了开发和生产环境之间的差异。
理想情况下,您的应用程序(如 Spring Boot 可执行 jar)将运行所需的所有内容打包在其中。
在本节中,我们将了解如何让我们在“入门”部分中开发的应用程序在云中启动并运行。
1.1云铸造
如果未指定其他构建包,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
有关更多选项,请参阅cf push文档。如果manifest.yml同一目录中存在 Cloud Foundry 文件,则会考虑该文件。
此时,cf
开始上传您的应用程序,产生类似于以下示例的输出:
正在上传 acloudyspringtime... OK
准备启动 acloudyspringtime... OK
-----> 下载的应用程序包(8.9M)
-----> Java Buildpack 版本:v3.12(离线)| https://github.com/cloudfoundry/java-buildpack.git#6f25b7e
-----> 从 https://java-buildpack.cloudfoundry.org/openjdk/trusty/x86_64/openjdk-1.8.0_121.tar.gz 下载 Open Jdk JRE 1.8.0_121(在缓存中找到)
将 Open Jdk JRE 扩展为 .java-buildpack/open_jdk_jre (1.6s)
-----> 从 https://java-buildpack.cloudfoundry.org/memory-calculator/trusty/x86_64/memory-calculator-2.0.2_RELEASE.tar.gz 下载 Open JDK Like Memory Calculator 2.0.2_RELEASE(在缓存)
内存设置:-Xss349K -Xmx681574K -XX:MaxMetaspaceSize=104857K -Xms681574K -XX:MetaspaceSize=104857K
-----> 从 https://java-buildpack.cloudfoundry.org/container-certificate-trust-store/container-certificate-trust-store-1.0.0_RELEASE.jar 下载容器证书信任库 1.0.0_RELEASE(找到在缓存中)
将证书添加到 .java-buildpack/container_certificate_trust_store/truststore.jks (0.6s)
-----> 从 https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-1.10.0_RELEASE.jar 下载 Spring Auto Reconfiguration 1.10.0_RELEASE(在缓存中找到)
正在检查应用程序“acloudyspringtime”的状态...
1 个实例中的 0 个正在运行(1 个开始)
...
1 个实例中的 0 个正在运行(1 个开始)
...
1 个实例中的 0 个正在运行(1 个开始)
...
1 个实例中的 1 个正在运行(1 个正在运行)
应用启动
恭喜!该应用程序现已上线!
应用程序上线后,您可以使用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 会自动提取它们并将数据扁平化为可以通过 Spring 的Environment
抽象访问的属性,如下例所示:
@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” Javadoc。
1.2. Kubernetes
Spring Boot 通过检查环境"*_SERVICE_HOST"
和"*_SERVICE_PORT"
变量来自动检测 Kubernetes 部署环境。spring.main.cloud-platform
您可以使用配置属性覆盖此检测。
Spring Boot 可帮助您管理应用程序的状态,并使用 Actuator 使用 HTTP Kubernetes Probes将其导出。
1.2.1Kubernetes 容器生命周期
当 Kubernetes 删除一个应用程序实例时,关闭过程会同时涉及多个子系统:关闭钩子、注销服务、从负载均衡器中删除实例……因为这个关闭过程是并行发生的(并且由于分布式系统的性质),有一个窗口可以将流量路由到也已开始其关闭处理的 pod。
您可以在 preStop 处理程序中配置睡眠执行,以避免将请求路由到已经开始关闭的 pod。这种休眠应该足够长,以使新请求停止路由到 pod,并且其持续时间因部署而异。可以使用 Pod 配置文件中的 PodSpec 配置 preStop 处理程序,如下所示:
spec:
containers:
- name: "example-container"
image: "example-image"
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 10"]
一旦 pre-stop 钩子完成,SIGTERM 将被发送到容器并开始正常关闭,允许任何剩余的正在进行的请求完成。
1.3. Heroku
Heroku 是另一个流行的 PaaS 平台。要自定义 Heroku 构建,您需要提供一个Procfile
,它提供部署应用程序所需的咒语。Heroku 分配一个port
供 Java 应用程序使用,然后确保路由到外部 URI 有效。
您必须将应用程序配置为侦听正确的端口。以下示例显示了Procfile
我们的初学者 REST 应用程序:
网页:java -Dserver.port=$PORT -jar 目标/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
这将导致以下结果:
初始化存储库,完成。
计数对象:95,完成。
使用多达 8 个线程的 Delta 压缩。
压缩对象:100% (78/78),完成。
写入对象:100% (95/95),8.66 MiB | 606.00 KiB/s,完成。
总计 95(增量 31),重复使用 0(增量 0)
-----> 检测到 Java 应用程序
-----> 安装 OpenJDK 1.8...完成
-----> 安装 Maven 3.3.1...完成
-----> 安装 settings.xml...完成
-----> 执行: mvn -B -DskipTests=true clean install
[INFO] 正在扫描项目...
下载:https://repo.spring.io/...
已下载:https://repo.spring.io/...(818 B,1.8 KB/秒)
……
已下载:https://s3pository.heroku.com/jvm/...(152 KB,595.3 KB/秒)
[信息] 安装 /tmp/build_0c35a5d2-a067-4abc-a232-14b1fb7a8229/target/...
[信息] 安装 /tmp/build_0c35a5d2-a067-4abc-a232-14b1fb7a8229/pom.xml ...
[信息] --------------------------------------------- -------------------------
[信息]构建成功
[信息] --------------------------------------------- -------------------------
[INFO] 总时间:59.358s
[INFO] 完成时间:2014 年 3 月 7 日星期五 07:28:25 UTC
[INFO] 最终内存:20M/493M
[信息] --------------------------------------------- -------------------------
-----> 发现进程类型
Procfile 声明类型 -> web
-----> 压缩...完成,70.4MB
-----> 正在启动...完成,v6
https://agile-sierra-1405.herokuapp.com/部署到 Heroku
至[email protected] :agile-sierra-1405.git
* [新分支] 主 -> 主
您的应用程序现在应该在 Heroku 上启动并运行。有关更多详细信息,请参阅将Spring Boot 应用程序部署到 Heroku。
1.4. 开班
OpenShift有许多描述如何部署 Spring Boot 应用程序的资源,包括:
- 使用 S2I 构建器
- 架构指南
- 在 Wildfly 上作为传统 Web 应用程序运行
- OpenShift Commons 简报
1.5亚马逊网络服务 (AWS)
Amazon Web Services 提供了多种安装基于 Spring Boot 的应用程序的方法,可以作为传统的 Web 应用程序 (war) 或作为具有嵌入式 Web 服务器的可执行 jar 文件。选项包括:
- AWS Elastic Beanstalk
- AWS 代码部署
- AWS 运维工作
- AWS 云形成
- AWS 容器注册表
每个都有不同的功能和定价模型。在本文档中,我们描述了使用 AWS Elastic Beanstalk 的方法。
1.5.1AWS Elastic Beanstalk
如官方Elastic Beanstalk Java 指南中所述,部署 Java 应用程序有两个主要选项。您可以使用“Tomcat 平台”或“Java SE 平台”。
使用 Tomcat 平台
此选项适用于生成 war 文件的 Spring Boot 项目。无需特殊配置。您只需要遵循官方指南即可。
使用 Java SE 平台
此选项适用于生成 jar 文件并运行嵌入式 Web 容器的 Spring Boot 项目。Elastic Beanstalk 环境在端口 80 上运行一个 nginx 实例来代理在端口 5000 上运行的实际应用程序。要配置它,请将以下行添加到您的application.properties
文件中:
server.port=5000
1.5.2. 概括
这是进入 AWS 的最简单方法之一,但还有更多内容需要介绍,例如如何将 Elastic Beanstalk 集成到任何 CI/CD 工具中、使用 Elastic Beanstalk Maven 插件而不是 CLI 等等。有一篇博文更详细地介绍了这些主题。
1.6. CloudCaptain 和亚马逊网络服务
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 会为您的应用程序创建一个图像,将其上传,并在 AWS 上配置和启动必要的资源,产生类似于以下示例的输出:
为 myapp-1.0.jar 融合图像 ...
图像融合在 00:06.838s (53937 K) -> axelfontaine/myapp:1.0
创建 axelfontaine/myapp ...
推送 axelfontaine/myapp:1.0 ...
正在验证 axelfontaine/myapp:1.0 ...
创建弹性 IP ...
将 myapp-axelfontaine.boxfuse.io 映射到 52.28.233.167 ...
等待 AWS 在 eu-central-1 中为 axelfontaine/myapp:1.0 创建一个 AMI(这可能需要 50 秒)...
AMI 创建于 00:23.557s -> ami-d23f38cf
创建安全组 boxfuse-sg_axelfontaine/myapp:1.0 ...
在 eu-central-1 中启动 axelfontaine/myapp:1.0 (ami-d23f38cf) 的 t2.micro 实例 ...
实例在 00:30.306s 启动 -> i-92ef9f53
等待 AWS 启动实例 i-92ef9f53 和有效负载从 https://52.28.235.61/ 开始...
有效负载开始于 00:29.266s -> https://52.28.235.61/
将弹性 IP 52.28.233.167 重新映射到 i-92ef9f53 ...
等待 AWS 完成弹性 IP 零停机时间过渡 15 秒...
部署成功完成。axelfontaine/myapp:1.0 在 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 中运行,您可以先在 UI 中创建一个项目,该项目会为您设置一个唯一标识符并设置 HTTP 路由。将 Java 应用程序添加到项目中并将其留空,然后使用Google Cloud SDK从命令行或 CI 构建将您的 Spring Boot 应用程序推送到该插槽中。
App Engine Standard 要求您使用 WAR 打包。按照以下步骤将 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 Boot 应用程序
除了使用 运行 Spring Boot 应用程序之外java -jar
,还可以为 Unix 系统制作完全可执行的应用程序。完全可执行的 jar 可以像任何其他可执行二进制文件一样执行,也可以使用或注册init.dsystemd。这有助于在常见的生产环境中安装和管理 Spring Boot 应用程序。
要使用 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 服务
Spring Boot 应用程序可以通过使用init.d
或轻松启动为 Unix/Linux 服务systemd
。
2.2.1作为 init.d 服务安装(系统 V)
如果您配置 Spring Boot 的 Maven 或 Gradle 插件以生成完全可执行的 jar,并且您不使用 custom embeddedLaunchScript
,则您的应用程序可以用作init.d
服务。为此,将 jar 符号链接到init.d
以支持标准start
、stop
、restart
和status
命令。
该脚本支持以下功能:
- 以拥有 jar 文件的用户身份启动服务
- 通过使用跟踪应用程序的 PID
/var/run/<appname>/<appname>.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
您还可以使用标准操作系统工具将应用程序标记为自动启动。例如,在 Debian 上,您可以使用以下命令:
$ update-rc.d myapp defaults <priority>
保护 init.d 服务
当以 root 身份执行时,就像使用 root 启动 init.d 服务一样,默认的可执行脚本以RUN_AS_USER
环境变量中指定的用户身份运行应用程序。未设置环境变量时,将使用拥有 jar 文件的用户。你永远不应该以 . 身份运行 Spring Boot 应用程序root
,所以RUN_AS_USER
永远不应该是 root 并且你的应用程序的 jar 文件永远不应该由 root 拥有。相反,创建一个特定用户来运行您的应用程序并设置RUN_AS_USER
环境变量或使用chown
以使其成为 jar 文件的所有者,如以下示例所示:
$ chown bootapp:bootapp your-app.jar
在这种情况下,默认的可执行脚本以bootapp
用户身份运行应用程序。
您还应该采取措施防止修改应用程序的 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 应用程序。
假设您在/var/myapp
中安装了 Spring Boot 应用程序,要将 Spring Boot 应用程序安装为systemd
服务,请创建一个名为的脚本并将myapp.service
其放置在/etc/systemd/system
目录中。以下脚本提供了一个示例:
[单元]
描述=我的应用程序
之后=syslog.target
[服务]
用户=myapp
ExecStart=/var/myapp/myapp.jar
成功退出状态=143
[安装]
WantedBy=多用户.target
请注意,与作为init.d
服务运行时不同,运行应用程序的用户、PID 文件和控制台日志文件由其systemd
自身管理,因此必须使用“服务”脚本中的适当字段进行配置。有关更多详细信息,请参阅服务单元配置手册页。
要将应用程序标记为在系统启动时自动启动,请使用以下命令:
$ systemctl enable myapp.service
运行man systemctl
以获取更多详细信息。
2.2.3自定义启动脚本
可以通过多种方式自定义由 Maven 或 Gradle 插件编写的默认嵌入式启动脚本。对于大多数人来说,使用默认脚本和一些自定义通常就足够了。如果您发现无法自定义您需要的内容,请使用embeddedLaunchScript
选项来完全编写您自己的文件。
编写时自定义启动脚本
在写入 jar 文件时自定义启动脚本的元素通常很有意义。例如,init.d 脚本可以提供“描述”。由于您预先知道描述(并且不需要更改),因此您最好在生成 jar 时提供它。
要自定义书面元素,请使用embeddedLaunchScriptProperties
Spring Boot Maven 插件的选项或propertiesSpring Boot Gradle 插件的launchScript.
默认脚本支持以下属性替换:
姓名 | 描述 | 摇篮默认 | Maven 默认 |
| 脚本模式。 | | |
| “ | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| 默认值为 | 包含罐子的文件夹 | 包含罐子的文件夹 |
| 对应在默认启动脚本中内联的文件脚本的引用。这可用于设置环境变量,例如 | ||
| 的默认值 | ||
| 的默认值 | ||
| 的默认值 | ||
| 中 PID 文件的名称的默认值 | ||
| | | |
| | 60 | 60 |
在运行时自定义脚本
对于jar写好后需要自定义的脚本项,可以使用环境变量或者配置文件。
默认脚本支持以下环境属性:
多变的 | 描述 |
| 操作的“模式”。默认值取决于 jar 的构建方式,但通常是 |
| 将用于运行应用程序的用户。未设置时,将使用拥有 jar 文件的用户。 |
| |
| pid 文件夹的根名称( |
| 放置日志文件的文件夹的名称( |
| 从中读取 .conf 文件的文件夹的名称(默认情况下与 jar 文件相同的文件夹)。 |
| |
| 应用程序的名称。如果 jar 是从符号链接运行的,则脚本会猜测应用程序名称。如果它不是符号链接或者您想显式设置应用程序名称,这可能很有用。 |
| 要传递给程序(Spring Boot 应用程序)的参数。 |
| |
| 启动时传递给 JVM 的选项。 |
| jar 文件的显式位置,以防脚本用于启动实际上未嵌入的 jar。 |
| 如果不为空,则 |
| 在强制关闭之前停止应用程序时等待的时间( |
除了JARFILE
和之外APP_NAME
,上一节中列出的设置都可以通过.conf
文件进行配置。该文件应位于 jar 文件旁边,并具有相同的名称但后缀为.conf
而不是.jar
. 例如,一个名为的 jar/var/myapp/myapp.jar
使用名为 的配置文件/var/myapp/myapp.conf
,如下例所示:
myapp.conf
JAVA_OPTS=-Xmx1024M
LOG_FOLDER=/自定义/日志/文件夹
要了解如何正确保护此文件,请参阅保护 init.d 服务的指南。
2.3. 微软视窗服务
Spring Boot 应用程序可以通过使用winsw.
A(单独维护的示例)分步描述了如何为 Spring Boot 应用程序创建 Windows 服务。
标签:...,Spring,Boot,应用程序,jar,myapp From: https://blog.51cto.com/u_15326439/5849084