部署到云端
Spring Boot 的可执行 jar 已为大多数流行的云端 PaaS(平台即服务)提供商准备完成。 这些服务商通常要求你“自带容器”。 它们管理应用进程(不是专门针对Java应用),因此需要一个中介层,将你的应用适应云端对运行进程的认知。
两家知名云服务提供商Heroku和Cloud Foundry采用“构建包”方法。
构建包会把你部署的代码包裹在启动应用所需的内容里。
可能是个JDK和一个电话Java,嵌入式Web服务器,或完整的应用服务器。
构建包是可以插拔的,但理想情况下你应该能用尽可能少的自定义内容来应付。
这减少了你无法控制的功能足迹。
它最大限度地减少了开发环境与生产环境之间的差异。
理想情况下,你的应用程序,比如 Spring Boot 的可执行文件 jar,里面包含了运行所需的一切。
在本节中,我们将探讨如何让我们在“入门”部分开发的应用在云端上运行。
云铸造厂
Cloud Foundry 提供默认的构建包,如果没有指定其他构建包,这些构建包会被调用。
Cloud Foundry Java 构建包对 Spring 应用程序(包括 Spring Boot)有出色的支持。
你可以部署独立的可执行 jar 应用程序,也可以部署传统应用。战争打包应用。
一旦你构建好了应用程序(例如使用,MVN 清洁封装) 并且有安装了参见命令行工具,通过使用CF推力命令,将路径替换为你的编译。罐.
一定要有登录时参见命令行客户端在推送申请之前。
以下行展示了使用CF推力命令部署应用程序:
$ cf push acloudyspringtime -p target/demo-0.0.1-SNAPSHOT.jar
在前面的例子中,我们用阴沉的Spring无论你给出多少价值参见作为你申请的名称。 |
参见CF推力文档更多选择。
如果有云铸造厂manifest.yml文件存在于同一目录中,则被视为该文件。
此时,参见开始上传你的应用程序,输出结果类似于以下示例:
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 应用命令,如下示例所示:
$ 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/.
服役约束
默认情况下,关于运行中的应用程序的元数据以及服务连接信息会以环境变量的形式暴露给应用程序(例如:$VCAP服务).
这一架构选择源于Cloud Foundry的多语种特性(任何语言和平台都可以作为构建包支持)。
进程范围的环境变量与语言无关。
环境变量并不总是最简单的 API,所以 Spring Boot 会自动提取它们,并将数据扁平化为可以通过 Spring 访问的属性环境抽象,如下例所示:
-
Java
-
Kotlin
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");
}
// ...
}
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完整细节需参考API文档。
| Java CFEnv 项目更适合配置数据源等任务。 |
Kubernetes
Spring Boot 通过检查 Kubernetes 部署环境,自动检测“*_SERVICE_HOST”和“*_SERVICE_PORT”变量。
你可以用spring.main.cloud-platform配置属性。
Spring Boot 帮助你管理应用状态,并通过 HTTP Kubernetes 探测器使用 Actuator 导出应用。
Kubernetes 容器生命周期
当Kubernetes删除应用实例时,关闭过程涉及多个子系统同时进行:关闭钩子、取消注册服务、从负载均衡器中移除实例...... 由于这种关机处理是并行进行的(且由于分布式系统的特性),存在一个窗口,流量可以被路由到同样开始关机处理的舱口。
你可以在preStop处理器中配置睡眠执行,以避免请求被路由到已经开始关闭的Pod上。 这个休眠时间应足够长,使得新请求停止被路由到该舱,且其持续时间会因部署而异。
如果你使用的是Kubernetes 1.32及以上版本,可以通过Pod配置文件中的PodSpec配置预停止处理程序,具体如下:
spec:
containers:
- name: "example-container"
image: "example-image"
lifecycle:
preStop:
sleep:
seconds: 10
如果你还没用 Kubernetes 1.32,可以用执行官命令调用睡.
spec:
containers:
- name: "example-container"
image: "example-image"
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 10"]
| 容器需要有外壳才能实现。 |
一旦预停钩完成,SIGTERM将被发送到集装箱,并开始优雅关机,允许剩余的飞行中请求完成。
当Kubernetes向Pod发送SIGTERM信号时,它会等待一个称为终止宽限期(默认为30秒)的指定时间。
如果容器在宽限期后仍在运行,则会收到SIGKILL信号并强制移除。
如果舱内关闭时间超过30秒,可能是因为你增加了spring.lifecycle.timeout-per-shutdown-phase确保通过设置终止宽限期秒在 Pod YAML中选择了这个选项。 |
赫罗库
Heroku是另一个受欢迎的PaaS平台。
要自定义Heroku构建,你需要提供一个Procfile,提供了部署应用所需的咒语。
Heroku分配了端口用于 Java 应用,并确保路由到外部 URI 的正常运行。
你必须配置应用监听正确的端口。
以下示例展示了Procfile对于我们的入门 REST 应用:
web: java -Dserver.port=$PORT -jar target/demo-0.0.1-SNAPSHOT.jar
Spring靴制造商-D可通过 Spring 访问的属性参数环境实例。
这server.port配置属性会被输入给嵌入的 Tomcat 或 Jetty 实例,然后在启动时使用该端口。
这$PORT环境变量由Heroku PaaS分配给我们。
这些应该就是你需要的一切了。
Heroku 部署最常见的部署工作流程是Git 推送代码转为生产环境,如下示例所示:
$ 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 上运行了。 更多细节请参见《向 Heroku 部署 Spring Boot 应用》。
开放转移
OpenShift 有许多资源介绍如何部署 Spring Boot 应用程序,包括:
亚马逊网络服务(AWS)
亚马逊网络服务提供了多种适合运行基于Spring Boot的应用程序的选项,无论是容器、传统Web应用(战争)还是自包含的可执行jar文件。 常见的选项有:
-
亚马逊弹性容器服务(ECS)
-
AWS 弹性豆茎
亚马逊弹性容器服务(ECS)
官方的亚马逊ECS开发者指南提供了平台功能的全面概述,并包含了引导你完成启动容器所需步骤的入门指南。
| Spring Boot 应用可以通过容器镜像中描述的技术打包在 Docker 容器中。 |
除了开发者指南外,AWS 还提供了使用 AWS Fargate 在 Amazon ECS 上部署容器化 Java 服务的专题指南。
Spring Boot 通过检查 AWS ECS 部署环境,自动检测AWS_EXECUTION_ENV变量。
你可以用spring.main.cloud-platform配置属性。 |
AWS 弹性豆茎
正如官方 Elastic Beanstalk Java 指南中所述,部署 Java 应用有两种主要选项。 你可以选择使用“Tomcat 平台”或“Java SE 平台”。
CloudCaptain 和亚马逊网络服务
CloudCaptain 的工作原理是将你的 Spring Boot 可执行文件 jar 或 war 变成一个最小的虚拟机镜像,可以在 VirtualBox 或 AWS 上不改动地部署。 CloudCaptain 对 Spring Boot 有深度集成,利用 Spring Boot 配置文件中的信息自动配置端口和健康检查 URL。 CloudCaptain 利用这些信息来生成镜像,也用于所有资源配置(实例、安全组、弹性负载均衡器等)。
一旦你创建了 CloudCaptain 账户,将其连接到你的 AWS 账户,安装了最新版本的 CloudCaptain 客户端,并确保该应用是由 Maven 或 Gradle 构建的(例如,使用MVN 清洁封装),你可以用类似以下命令将你的 Spring Boot 应用部署到 AWS:
$ boxfuse run myapp-1.0.jar -env=prod
参见箱型引信运行文档更多选择。
如果存在boxfuse.conf当前目录中存在的文件,则考虑它。
默认情况下,CloudCaptain会激活一个名为Spring的配置文件箱式保险丝启动时。
如果你的可执行容器或战争包含application-boxfuse.propertiesCloudCaptain 基于其包含的属性进行配置。 |
此时,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构建来运行该应用。
天蓝色
这份入门指南将带你了解如何将Spring Boot应用部署到Azure Spring Cloud或Azure App Service上。
谷歌云
Google Cloud 有多种选项可用于启动 Spring Boot 应用。 最容易入门的可能是App Engine,但你也可以找到用Container Engine在容器里运行Spring Boot的方法,或者用Compute Engine在虚拟机上运行。
要将你的第一个应用部署到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:部署(你需要先认证,否则构建会失败。)