将 Spring Cloud 应用程序迁移到 Azure Spring Apps

注意

Azure Spring Apps 是 Azure Spring Cloud 服务的新名称。 虽然该服务有新名称,但一些地方仍会使用旧名称,我们仍在更新屏幕截图、视频和图形等资产。

本指南介绍在想要迁移现有 Spring Cloud 应用程序以在 Azure Spring Apps 上运行时应注意的内容。

预迁移

若要确保迁移成功,请在开始之前完成以下各节中所述的评估和清点步骤。

如果无法满足任何预迁移要求,请参阅以下伴随迁移指南:

  • 将可执行的 JAR 应用程序迁移到 Azure Kubernetes 服务上的容器(按指南进行计划)
  • 将可执行的 JAR 应用程序迁移到 Azure 虚拟机(按指南进行计划)

检查应用程序组件

确定是否使用以及如何使用文件系统

查找向本地文件系统写入和/或从中读取服务的任何实例。 确定写入和读取短期/临时文件的位置,以及写入和读取长期文件的位置。

注意

Azure Spring Apps 为每个 Azure Spring Apps 实例提供 5 GB 的临时存储,并装载到 /tmp其中。 如果临时文件的写入超出了该限制或位于其他位置,则需要进行代码更改。

只读静态内容

如果应用程序当前提供静态内容,则需为其提供一个备用位置。 可能需要考虑将静态内容移到 Azure Blob 存储,并添加 Azure CDN,方便用户在全球范围内快速下载。 有关详细信息,请参阅 Azure 存储中的静态网站托管快速入门:将 Azure 存储帐户与 Azure CDN 集成

动态发布的静态内容

如果应用程序允许那些通过应用程序上传/生成但在创建后不可变的静态内容,则可将上述 Azure Blob 存储和 Azure CDN 与 Azure 函数配合使用,以便处理上传和 CDN 刷新操作。 我们提供了一个示例实现,用于通过 Azure Functions 进行静态内容的上传和 CDN 预加载操作

确定是否有服务包含特定于 OS 的代码

如果应用程序包含的代码有主机 OS 的依赖项,则需重构该代码,删除那些依赖项。 例如,可能需要将文件系统路径中使用的 /\ 替换为 File.SeparatorPaths.get

切换到受支持的平台

Azure Spring Apps 提供特定版本的 Java 和 Spring Boot 和 Spring Cloud 的特定版本。 若要确保兼容性,请在继续执行其余迁移步骤之前,首先将应用程序迁移到当前环境中支持的 Java 版本之一。 务必全面测试生成的配置。 请在此类测试中使用最新且稳定的 Linux 发布版。

注意

如果当前服务器在不受支持的 JDK(如 Oracle JDK 或 IBM OpenJ9)上运行,则此验证尤其重要。

若要获取当前的 Java 版本,请登录到生产服务器并运行以下命令:

java -version

有关受支持的 Java、Spring Boot 和 Spring Cloud 版本以及更新的说明,请参阅 准备应用程序以在 Azure Spring Apps 中部署

确定 Spring Boot 版本

检查要迁移的每个应用程序的依赖项,以确定其 Spring Boot 版本。

Maven

在 Maven 项目中,通常可以在 POM 文件的 <parent> 元素中找到 Spring Boot 版本:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
Gradle

在 Gradle 项目中,通常可以在 plugins 部分找到 Spring Boot 版本(作为 org.springframework.boot 插件的版本):

plugins {
  id 'org.springframework.boot' version '2.2.6.RELEASE'
  id 'io.spring.dependency-management' version '1.0.9.RELEASE'
  id 'java'
}

对于使用 Spring Boot 1.x 的任何应用程序,请按照 Spring Boot 2.0 迁移指南将其更新为受支持的 Spring Boot 版本。 有关支持的版本,请参阅 Azure Spring Apps 中准备应用程序部署的Spring Boot 和 Spring Cloud 版本部分。

确定 Spring Cloud 版本

检查要迁移的每个应用程序的依赖项,以确定其使用的 Spring Cloud 组件的版本。

Maven

在 Maven 项目中,Spring Cloud 版本通常在 spring-cloud.version 属性中设置:

  <properties>
    <java.version>1.8</java.version>
    <spring-cloud.version>Hoxton.SR3</spring-cloud.version>
  </properties>
Gradle

在 Gradle 项目中,Spring Cloud 版本通常在“额外属性”块中设置:

ext {
  set('springCloudVersion', "Hoxton.SR3")
}

需要将所有应用程序更新为使用受支持的 Spring Cloud 版本。 有关受支持的版本列表,请参阅 Azure Spring Apps 中准备应用程序部署的Spring Boot 和 Spring Cloud 版本部分。

确定日志聚合解决方案

确定要迁移的应用程序所使用的任何日志聚合解决方案。

确定应用程序性能管理 (APM) 代理

确定与应用程序一起使用的任何应用程序性能监视代理(例如 Dynatrace 和 Datadog)。 为了取代此类代理,Azure Spring Apps 与 Azure Monitor 提供深度集成,以便对性能管理和实时响应异常。 有关详细信息,请参阅迁移后

确定 Zipkin 依赖项

确定应用程序是否在 Zipkin 上具有显式依赖项。 在 Maven 或 Gradle 依赖项中查找 io.zipkin.java 组的依赖项。

清点外部资源

标识外部资源,如数据源、JMS 消息代理和其他服务的 URL。 在 Spring Cloud 应用程序中,通常可以在以下位置之一找到此类资源的配置:

  • 在 src/main/directory 文件夹中,位于通常称为 application.properties 或 application.yml 的文件中 。
  • 在之前的步骤中标识的 Spring Cloud Config 存储库中。

数据库

确定任何 SQL 数据库的连接字符串。

Spring Boot 应用程序的连接字符串通常出现在配置文件中。

下面是 application.properties 文件中的示例:

spring.datasource.url=jdbc:mysql://localhost:3306/mysql_db
spring.datasource.username=dbuser
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

下面是 application.yaml 文件中的示例:

spring:
  data:
    mongodb:
      uri: mongodb://mongouser:deepsecret@mongoserver.contoso.com:27017

有关可能性更大的配置场景,请参阅 Spring 数据文档:

JMS 消息代理

通过在生成清单(通常是 pom.xml 或 build.gradle 文件)中查找相关依赖项,确定所使用的一个或多个代理 。

例如,使用 ActiveMQ 的 Spring Boot 应用程序通常会在其 pom.xml 文件中包含此依赖项:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-activemq</artifactId>
</dependency>

使用商业代理的 Spring Boot 应用程序通常直接包含代理的 JMS 驱动程序库的依赖项。 下面是 build.gradle 文件中的示例:

    dependencies {
      ...
      compile("com.ibm.mq:com.ibm.mq.allclient:9.0.4.0")
      ...
    }

确定正在使用的一个或多个代理后,请找到相应的设置。 在 Spring Cloud 应用程序中,通常可以在应用程序目录的 application.properties 和 application.yml 中找到,或在 Spring Cloud Config 服务器存储库中找到 。

下面是 application.properties 文件中的 ActiveMQ 示例:

spring.activemq.brokerurl=broker:(tcp://localhost:61616,network:static:tcp://remotehost:61616)?persistent=false&useJmx=true
spring.activemq.user=admin
spring.activemq.password=tryandguess

有关 ActiveMQ 配置的详细信息,请参阅 Spring Boot 消息文档

下面是 application.yaml 文件中的 IBM MQ 示例:

ibm:
  mq:
    queueManager: qm1
    channel: dev.ORDERS
    connName: localhost(14)
    user: admin
    password: big$ecr3t

有关 IBM MQ 配置的详细信息,请参阅 IBM MQ Spring 组件文档

确定外部缓存

确定正在使用的任何外部缓存。 通常,Redis 是通过 Spring Data Redis 使用的。 有关配置信息,请参阅 Spring Data Redis 文档。

通过搜索相应的配置(在 JavaXML)中,确定是否正在通过 Spring 会话缓存会话数据。

标识提供者

标识需要身份验证和/或授权的所有标识提供者和所有 Spring Cloud 应用程序。 有关可如何配置标识提供者的信息,请参阅以下内容:

通过 VMware Tanzu 应用程序服务(TAS,之前称为 Pivotal Cloud Foundry)配置的资源

对于使用 TAS 托管的应用程序,通常通过 TAS 服务绑定配置外部资源(包括前面所述的资源)。 若要检查此类资源的配置,请使用 TAS (Cloud Foundry) CLI 查看应用程序的 VCAP_SERVICES 变量。

# Log into TAS, if needed (enter credentials when prompted)
cf login -a <API endpoint>

# Set the organization and space containing the application, if not already selected during login.
cf target org <organization name>
cf target space <space name>

# Display variables for the application
cf env <Application Name>

检查绑定到应用程序的外部服务配置设置的 VCAP_SERVICES 变量。 有关详细信息,请参阅 TAS (Cloud Foundry) 文档

所有其他的外部资源

本指南不可能记录每个可能的外部依赖项。 迁移后,你将负责验证你能否满足应用程序的所有外部依赖项的要求。

清单配置源和机密

清单密码和安全字符串

检查生产部署上的所有属性和配置文件以及所有环境变量中是否有机密字符串和密码。 在 Spring Cloud 应用程序中,通常可以在各个服务的 application.properties 和 application.yml 文件中找到此类字符串,或在 Spring Cloud Config 存储库中找到此类字符串 。

清点证书

记录用于公共 SSL 终结点或与后端数据库以及其他系统通信的所有证书。 可以通过运行以下命令来查看生产服务器上的所有证书:

keytool -list -v -keystore <path to keystore>

确定是否使用 Spring Cloud Vault

如果使用 Spring Cloud Vault 来存储和访问机密,请标识备用机密存储(例如,HashiCorp Vault 或 CredHub)。 然后标识应用程序代码使用的所有机密。

查找配置服务器源

如果应用程序使用 Spring Cloud Config 服务器,请确定配置的存储位置。 通常可以在 bootstrap.yml 或 bootstrap.properties 文件中找到此设置,有时也可以在 application.yml 或 application.properties 文件中找到此设置 。 此设置与以下示例类似:

spring.cloud.config.server.git.uri: file://${user.home}/spring-cloud-config-repo

尽管 git 最常用作 Spring Cloud Config 的备用数据存储(如前文所述),但也可能使用一种其他的后端。 请参阅 Spring Cloud Config 文档,了解有关其他后端的信息,如关系数据库 (JDBC)SVN本地文件系统

注意

如果配置服务器数据存储在本地(如 GitHub Enterprise),则需要通过 Git 存储库将其提供给 Azure Spring Apps。

检查部署体系结构

记录每个服务的硬件要求

对于每个 Spring Cloud 服务(不包括配置服务器、注册表或网关),记录以下信息:

  • 正在运行的实例数。
  • 为每个实例分配的 CPU 数量。
  • 为每个实例分配的 RAM 量。

记录异地复制/分发

确定 Spring Cloud 应用程序当前是否分布在多个区域或数据中心。 记录要迁移的应用程序的运行时间要求/SLA。

确定绕过服务注册表的客户端

确定调用任何要迁移的服务的客户端应用程序,而无需使用 Spring Cloud 服务注册表。 迁移后,将无法再进行此类调用。 更新此类客户端,以便在迁移前使用 Spring Cloud OpenFeign

迁移

删除显式配置服务器设置

在要迁移的服务中,查找 Eureka 设置的任何显式分配,并将其删除。 此类设置通常出现在 application.properties 或 application.yml 文件中 :

application.yml

eureka:
  client:
    serviceUrl:
      defaultZone: http://myusername:mysecretpassword@localhost:8761/eureka/

如果应用程序配置中出现类似的设置,请将其删除。 Azure Spring Apps 将自动注入其配置服务器的连接信息。

创建 Azure Spring Apps 实例和应用

在 Azure 订阅中预配 Azure Spring Apps 实例。 然后,为要迁移的每个服务预配一个应用。 请不要包含 Spring Cloud 注册表和配置服务器。 请包含 Spring Cloud 网关服务。 有关说明,请参阅 快速入门:将第一个应用程序部署到 Azure Spring Apps

准备 Spring Cloud Config 服务器

在 Azure Spring Apps 实例中配置配置服务器。 有关详细信息,请参阅为服务设置 Spring Cloud 配置服务器实例

注意

如果当前的 Spring Cloud Config 存储库位于本地文件系统或本地,你首先需要将配置文件迁移或复制到基于私有云的存储库,例如 GitHub、Azure Repos 或 BitBucket。

确保控制台日志记录并配置诊断设置

配置日志记录,使所有输出都路由到控制台而不是文件。

将应用程序部署到 Azure Spring Apps 后, 添加诊断设置 ,使记录的事件可供使用,例如通过 Azure Monitor Log Analytics。

LogStash/ELK 堆栈

如果使用 LogStash/ELK 堆栈进行日志聚合,请将诊断设置配置为将控制台输出流式传输到 Azure 事件中心。 然后,使用 LogStash EventHub 插件将记录的事件引入到 LogStash 中。

Splunk

如果使用 Splunk 进行日志聚合,请将诊断设置配置为将控制台输出流式传输到 Azure Blob 存储。 然后,使用 Microsoft 云服务的 Splunk 附加产品将记录的事件引入到 Splunk 中。

配置持久性存储

如果应用程序的任何部分读取或写入到本地文件系统,将需要配置持久性存储来替换本地文件系统。 有关详细信息,请参阅 在 Azure Spring Apps 中使用内置持久存储

应将任何临时文件写入 /tmp 目录。 要实现 OS 独立性,可以使用 System.getProperty("java.io.tmpdir") 获取此目录。 还可以使用 java.nio.Files::createTempFile 来创建临时文件。

VMware Tanzu 组件

在企业层中,为 VMware Tanzu® 提供应用程序配置服务,以支持应用的外部化配置。 托管 Spring Cloud 配置服务器在企业层中不可用,仅在 Azure Spring Apps 的标准层和基本层中可用。

Tanzu 的应用程序配置服务

Tanzu 的应用程序配置服务是商业 VMware Tanzu 组件之一。 Tanzu 的应用程序配置服务是 Kubernetes 本机的,与 Spring Cloud Config Server 完全不同。 Tanzu 的应用程序配置服务可以管理从一个或多个 Git 存储库中定义的属性填充的 Kubernetes 本机 ConfigMap 资源。

在企业层中,没有 Spring Cloud Config Server,但是可以使用 Tanzu 的应用程序配置服务来管理集中式配置。 有关详细信息,请参阅使用 Tanzu 的应用程序配置服务

若要使用 Tanzu 的应用程序配置服务,请针对每个应用执行以下步骤:

  1. 添加显式应用绑定,以声明应用需要使用 Tanzu 的应用程序配置服务。

    注意

    更改绑定/取消绑定状态时,必须重启或重新部署应用才能使更改生效。

  2. 设置配置文件模式。 通过配置文件模式可以选择应用将使用的应用程序和配置文件。 有关详细信息,请参阅使用 Tanzu 的应用程序配置服务模式部分。

    另一种方法是在应用部署的同时设置配置文件模式,如以下示例中所示:

       az spring app deploy \
           --name <app-name> \
           --artifact-path <path-to-your-JAR-file> \
           --config-file-pattern <config-file-pattern>
    

用于 Tanzu 的应用程序配置服务在 Kubernetes 上运行。 为了帮助实现透明的本地开发体验,我们提供了以下建议。

  • 如果已有 Git 存储库来存储外部化配置,则可以在本地将 Spring Cloud Config Server 设置为应用程序的集中式配置。 配置服务器启动后,它将克隆 Git 存储库,并通过其 Web 控制器提供存储库内容。 有关详细信息,请参阅 Spring 文档中的 Spring Cloud 配置 。 为 spring-cloud-config-client 应用程序提供从配置服务器自动选取外部配置的功能。

  • 如果没有 Git 存储库,或者不想在本地设置配置服务器,可以直接在项目中使用配置文件。 建议使用配置文件来隔离配置文件,使其仅在开发环境中使用。 例如,用作 dev 配置文件。 然后,可以在 src/main/resource 文件夹中创建 application-dev.yml 文件以存储配置。 若要让应用使用此配置,请使用本地方式 --spring.profiles.active=dev启动应用。

Tanzu 服务注册表

VMware Tanzu 服务注册表是商业 VMware Tanzu® 组件之一。 Tanzu 服务注册表为企业层应用提供服务发现模式的实现,这是基于微服务的体系结构的主要原则之一。 应用可以使用 Tanzu 服务注册表来动态发现和调用已注册的服务。 使用 Tanzu 服务注册表最好是手动配置服务的每个客户端,这可能很困难,或者采用某种形式的访问约定,这可能会在生产环境中很脆弱。 有关详细信息,请参阅使用 Tanzu 服务注册表

将 Spring Cloud Vault 机密迁移到 Azure KeyVault

可以使用 Azure KeyVault Spring Boot 起动器,通过 Spring 将机密直接注入到应用程序。 有关详细信息,请参阅如何使用适用于 Azure Key Vault 的 Spring Boot 起动器

注意

迁移可能需要重命名一些机密。 请相应地更新应用程序代码。

将所有证书迁移到 KeyVault

Azure Spring Apps 不提供对 JRE 密钥存储的访问权限,因此必须将证书迁移到 Azure KeyVault,并更改应用程序代码以访问 KeyVault 中的证书。 有关详细信息,请参阅 Key Vault 证书入门适用于 Java 的 Azure Key Vault 证书客户端库

删除应用程序性能管理 (APM) 集成

消除与 APM 工具/代理的任何集成。 有关使用 Azure Monitor 配置性能管理的信息,请参阅迁移后部分。

将显式 Zipkin 依赖项替换为 Spring Cloud 起动器

如果任何迁移的应用程序具有显式 Zipkin 依赖项,请将其删除,并将其替换为 Spring Cloud Starters。 有关 Azure 应用程序 Insights 的信息,请参阅迁移后部分。

在应用程序中禁用指标客户端和终结点

删除应用程序中使用的任何指标客户端或应用程序中公开的任何指标终结点。

部署服务

如快速入门中所述,部署每个已迁移的 Spring 应用 (不包括 Spring Cloud 配置和注册表服务器) :将第一个应用程序部署到 Azure Spring Apps

配置基于服务的机密和外部化设置

可以将任何基于服务的配置设置作为环境变量注入每个服务。 在 Azure 门户中,使用以下步骤:

  1. 导航到 Azure Spring Apps 实例并选择 “应用”。
  2. 选择要配置的服务。
  3. 选择“配置”。
  4. 输入要配置的变量。
  5. 选择“保存”。

Spring Cloud 应用配置设置

迁移和启用标识提供者

如果任何 Spring Cloud 应用程序需要身份验证或授权,请确保将其配置为访问标识提供者:

  • 如果标识提供者是 Azure Active Directory,则不需要进行任何更改。
  • 如果标识提供者是本地 Active Directory 林,请考虑使用 Azure Active Directory 实现混合标识解决方案。 有关指南,请参阅混合标识文档
  • 如果标识提供者是另一个本地解决方案(如 PingFederate),请参阅 Azure AD Connect 的自定义安装主题,以使用 Azure Active Directory 配置联合。 或者,考虑使用 Spring 安全性通过 OAuth2/OpenID ConnectSAML 来使用标识提供者。

更新客户端应用程序

更新所有客户端应用程序的配置,以将已发布的 Azure Spring Apps 终结点用于迁移的应用程序。

迁移后

  • 请考虑为自动、一致的部署添加部署管道。 提供有关 Azure PipelinesGitHub ActionsJenkins 的说明。

  • 请考虑使用过渡部署在生产中测试代码更改,然后再将其提供给一些或所有最终用户。 有关详细信息,请参阅在 Azure Spring Apps 中设置过渡环境

  • 请考虑添加服务绑定,以便将应用程序连接到受支持的 Azure 数据库。 如果使用这些服务绑定,则无需向 Spring Cloud 应用程序提供连接信息(包括凭据)。

  • 请考虑使用 Azure 应用程序 Insights 监视应用程序的性能和交互。 有关详细信息,请参阅 Azure Spring Apps 中的 Application Insights Java 进程内代理

  • 请考虑添加 Azure Monitor 预警规则和操作组,以快速检测并解决异常情况。 有关详细信息,请参阅教程:使用警报和操作组监视 Spring Cloud 资源

  • 请考虑在另一个区域中复制 Azure Spring Apps 部署,以提高延迟和更高的可靠性和容错能力。 使用 Azure 流量管理器在部署之间实现负载均衡,或使用 Azure Front Door 添加 SSL 卸载和具有 DDoS 防护的 Web 应用程序防火墙。

  • 如果不需要异地复制,请考虑添加 Azure 应用程序网关,以便添加 SSL 卸载和具有 DDoS 防护的 Web 应用程序防火墙。

  • 如果应用程序使用旧的 Spring Cloud Netflix 组件,请考虑将它们替换为当前替代项:

    旧的 当前
    Spring Cloud Eureka Spring Cloud 服务注册表
    Spring Cloud Netflix Zuul Spring Cloud 网关
    Spring Cloud Netflix Archaius Spring Cloud 配置服务器
    Spring Cloud Netflix 功能区 Spring Cloud 负载均衡器(客户端负载均衡器)
    Spring Cloud Hystrix Spring Cloud 断路器 + Resilience4J
    Spring Cloud Netflix Turbine Micrometer + Prometheus