你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

将 Spring Boot 应用程序迁移到 Azure 容器应用

本指南指导你完成将现有 Spring Boot 应用程序迁移到 Azure 容器应用的过程。 它涵盖迁移前评估、迁移本身和迁移后优化。

先决条件

迁移前评估

在开始迁移之前,请完成以下部分中介绍的评估和清单步骤。

标识本地状态

在平台即服务(PaaS)环境中,应用程序不保证它在任何给定时间运行完全相同的一个实例。 即使配置单个实例,也可以在以下情况下创建重复实例:

  • 由于故障或系统更新,系统必须将应用程序重新定位到物理主机。
  • 系统更新应用程序。

在这两种情况下,原始实例将一直运行,直到新实例完成启动。 此行为对应用程序有以下影响:

  • 你无法保证任何单例真正唯一。
  • 可能会丢失未保存到外部存储的任何数据。

在迁移到Azure 容器应用之前,请确保代码不包含不得丢失或复制的本地状态。 如果存在本地状态,请重构代码以在外部存储该状态。 云就绪应用程序通常将状态存储在以下位置之一:

查看文件系统使用情况

标识服务从本地文件系统读取或写入到的任何实例。 请注意哪些文件是短期或临时文件,哪些文件是长期存在的。

Azure 容器应用提供多种类型的存储。 通过使用临时存储,可以在正在运行的容器或副本中读取和写入临时数据。 通过使用 Azure 文件存储,可以提供多个容器可以共享的永久存储。 有关详细信息,请参阅 在 Azure 容器应用中使用存储挂载

如果应用程序提供 只读静态内容,请考虑将其移动到 Azure Blob 存储并添加用于全局分发的 Azure CDN。 有关详细信息,请参阅 Azure 存储 中的静态网站托管快速入门:将 Azure 存储帐户与 Azure CDN 集成

如果应用程序处理 动态发布的静态内容 (在创建后上传或生成的内容不会更改),则可以集成 Azure Blob 存储和 Azure CDN。 还可以使用 Azure 函数来管理上传和触发 CDN 刷新。 有关示例实现,请参阅 使用 Azure Functions 上传和 CDN 预加载静态内容

检查特定于操作系统的代码

如果应用程序包含具有主机 OS 依赖项的代码,请重构它以删除这些依赖项。 例如,将文件系统路径中/\的任何用法替换为File.SeparatorPaths.get

验证平台兼容性

如果手动创建 Dockerfile 并将容器化应用程序部署到 Azure 容器应用,则可以完全控制部署,包括 JRE/JDK 版本。

对于从项目部署,Azure 容器应用提供特定版本的 Java(8、11、17 和 21)以及特定版本的 Spring Boot 和 Spring Cloud 组件。 若要确保兼容性,请先将应用程序迁移到当前环境中受支持的 Java 版本,然后继续执行剩余的迁移步骤。 使用 Linux 分发版的最新稳定版本全面测试生成的配置。

注释

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

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

java -version

有关支持的 Java、Spring Boot 和 Spring Cloud 版本,请参阅 Azure 容器应用上的 Java 概述

标识 Spring Boot 版本

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

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

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

Gradle 项目中,在 plugins 部分查找 Spring Boot 版本:

plugins {
  id 'org.springframework.boot' version '3.3.3'
  id 'io.spring.dependency-management' version '1.1.6'
  id 'java'
}

对于使用 3.x 之前的 Spring Boot 版本的应用程序,请按照 Spring Boot 3.0 迁移指南 更新到受支持的版本。 有关支持的版本,请参阅 Spring Boot 和 Spring Cloud 版本

标识计划任务

基于 Spring Batch 框架的临时应用程序(如 Unix cron 作业或生存期较短的应用程序)应在 Azure 容器应用中以作业的形式运行。 有关详细信息,请参阅 Azure 容器应用 中的作业

如果应用程序长时间运行,并且使用计划框架(如“硅”或“Spring Batch”)定期执行任务,则可以在 Azure 容器应用上托管它。 但是,应用程序必须正确处理扩缩容,避免扩缩容或滚动升级期间同一任务在每个计划周期运行多次的竞争条件。

清点生产服务器上运行的任何计划任务,无论在应用程序代码内部还是外部。

清点外部资源

标识外部资源,如数据源、JMS 消息代理和其他服务的 URL。 在 Spring Boot 应用程序中,通常会在 src/main/resources 文件夹中查找此类资源的配置,该文件通常称为 application.propertiesapplication.yml

数据库

对于 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 Data 文档:

JMS 消息代理

通过在构建清单中查找相关依赖项(通常是 pom.xmlbuild.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.4.0.5")
      ...
    }

确定使用的代理后,找到相应设置。 通常可在 application.properties 中找到它们,并在应用程序目录中 application.yml 文件。

注释

Microsoft 建议使用最安全的可用身份验证流。 此过程中所述的身份验证流(例如数据库、缓存、消息传送或 AI 服务)需要对应用程序高度信任,并且存在其他流中不存在的风险。 仅当更安全的选项(例如无密码连接或无密钥连接的托管标识)不可行时,才使用此流。 对于本地计算机操作,首选无密码连接或无密钥连接的用户标识。

下面是 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=<password>

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

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

ibm:
  mq:
    queueManager: qm1
    channel: dev.ORDERS
    connName: localhost(14)
    user: admin
    password: <password>

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

外部缓存

确定正在使用的任何外部缓存。 在很多情况下,你会通过 Spring Data Redis 来使用 Redis。 有关配置信息,请参阅 Spring Data Redis 文档。

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

身份提供者

标识应用程序使用的任何标识提供者。 有关如何配置标识提供者的信息,请参阅以下资源:

非标准端口

通过使用 Azure 容器应用,可以根据容器应用资源配置公开端口。 默认情况下,Spring Boot 应用程序侦听 8080 端口,但您可以通过使用 server.portSERVER_PORT 环境变量来更改此端口。

所有其他的外部资源

本指南无法记录每个可能的外部依赖项。 迁移后,请验证是否可以满足应用程序的每个外部依赖项。

清单配置、机密和证书

密码和安全字符串

检查生产部署中的所有属性、配置文件和环境变量中是否存在机密字符串和密码。 在 Spring Boot 应用程序中,通常会在 application.propertiesapplication.yml 文件中找到这些字符串。

证书

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

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

评估日志记录和 应用性能管理 (APM)

确定要迁移的应用程序使用的任何日志聚合解决方案。 需要在迁移期间配置诊断设置,以使记录的事件可供使用。 有关详细信息,请参阅 “配置日志记录和诊断 ”部分。

确定应用程序使用的任何应用程序性能管理(APM)代理。 Azure 容器应用不提供内置的 APM 支持。 需要准备容器映像或将 APM 工具直接集成到代码中。 若要衡量应用程序的性能,但尚未集成任何 APM,请考虑使用 Azure 应用程序 Insights。 有关详细信息,请参阅 “集成应用程序性能监视 ”部分。

文档部署体系结构

记录 Spring Boot 应用程序的以下信息:

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

此外,确定是否当前正在多个区域或数据中心之间分发应用程序实例。 记录要迁移的应用程序的运行时间要求和 SLA。

Migration

创建容器应用环境

在 Azure 订阅中创建容器应用环境。 有关详细信息,请参阅 Quickstart:使用 Azure 门户部署第一个容器应用

配置日志记录和诊断

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

将应用程序部署到 Azure 容器应用后,可以在容器应用环境中配置日志记录选项以定义一个或多个日志目标。 这些目标可能包括 Azure Monitor Log Analytics、Azure 事件中心或非Microsoft监视解决方案。 您还可以禁用日志数据存储,并仅在运行时查看日志。 有关配置说明,请参阅 Azure 容器应用中的日志存储和监视选项

配置持久性存储

如果应用程序的任何部分读取或写入本地文件系统,请配置永久性存储以替换它。 指定通过应用设置在容器中装载的路径,并将其与应用程序使用的路径保持一致。 有关详细信息,请参阅 在 Azure 容器应用中使用存储挂载

将证书迁移到 Azure 密钥保管库

Azure 容器应用支持应用之间的安全通信。 应用程序无需管理建立安全通信的过程。 可以将专用证书上传到 Azure 容器应用或使用免费的托管证书。 建议使用 Azure 密钥保管库 管理证书。 有关详细信息,请参阅 Azure 容器应用中的证书

集成应用程序性能监视

无论是从容器映像还是代码部署应用,Azure 容器应用都不会干扰映像或代码。 将应用程序与 APM 工具集成取决于偏好和实现。

如果应用程序未使用受支持的 APM,请考虑使用 Azure 应用程序 Insights。 有关详细信息,请参阅将 Azure Monitor Application Insights 与 Spring Boot 配合使用

部署应用程序

请按照使用 az containerapp up 命令部署 Azure 容器应用中所述,部署每个已迁移的微服务(不包括 Spring Cloud 配置服务器和 Spring Cloud 服务注册中心)。

配置机密和环境变量

可以将配置设置作为环境变量注入每个应用程序。 将这些变量设置为手动条目或对机密的引用。 有关详细信息,请参阅 管理 Azure 容器应用中的环境变量

设置标识和身份验证

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

  • 如果标识提供者是 Microsoft Entra ID,请不要进行任何更改。

  • 如果标识提供者是本地 Active Directory 林,请考虑使用 Microsoft Entra ID 实现混合标识解决方案。 有关详细信息,请参阅混合标识文档

  • 如果标识提供者是另一个本地解决方案(例如 PingFederate),请参阅 Microsoft Entra Connect 的自定义安装 ,以配置与 Microsoft Entra ID 的联合身份验证。

或者,考虑使用 Spring 安全性通过 OAuth2/OpenID ConnectSAML 来使用标识提供者。

公开应用程序

默认情况下,部署到 Azure 容器应用的应用程序可通过应用程序 URL 访问。 如果你在带自有虚拟网络的托管环境中部署应用,确定应用的可访问级别,允许公共入口或仅来自虚拟网络的入口。 有关详细信息,请参阅 Azure 容器应用 环境中的 Networking

迁移后

完成迁移后,请验证应用程序是否按预期工作。 以下部分介绍了有关使应用程序更具云原生性和可操作性的建议。

针对云原生模式进行优化

以下建议可帮助你采用 Spring Cloud 组件和 Azure 容器应用的 Java 组件,使应用程序更具云原生的特性。

服务发现和负载均衡

使应用程序能够使用 Spring Cloud 注册表组件,以便其他已部署的 Spring 应用程序和客户端可以动态发现它。 有关详细信息,请参阅 Azure 容器应用0 中用于 Spring 组件的 Eureka Server 的配置设置。

然后,修改任何应用程序客户端以使用 Spring Client 负载均衡器。 使用 Spring Client 负载均衡器时,客户端会获取应用程序的所有正在运行实例的地址,并在另一个实例损坏或无响应时找到一个有效实例。 有关详细信息,请参阅 Spring Blog 中的 Spring 提示:Spring Cloud 负载均衡器

API 网关

请考虑添加 Spring Cloud Gateway 实例。 Spring Cloud Gateway 为Azure 容器应用环境中部署的所有应用程序提供单个终结点。 如果已部署 Spring Cloud Gateway,请确保已配置路由规则以将流量路由到新部署的应用程序。

集中配置

考虑添加 Spring Cloud Config Server,以便集中管理所有 Spring Cloud 应用程序的配置并对其进行版本控制。 首先,创建 Git 存储库来容纳配置并配置应用实例以使用它。 有关详细信息,请参阅 Azure 容器应用0 中用于 Spring 组件的 Config Server 配置设置。

使用以下步骤迁移配置:

  1. 在应用程序的 src/main/resources 目录中,创建 包含以下内容的bootstrap.yml 文件:

    spring:
      application:
        name: <your-application-name>
    
  2. 在配置 Git 存储库中创建名为 <your-application-name>.yml 的文件,其中 your-application-name 与上一步中的名称相同。 将设置从 src/main/resources 中的application.yml文件移动到所创建的新文件。 如果设置以前在 .properties 文件中,请先将它们转换为 YAML。 可以找到联机工具或 IntelliJ 插件来完成此转换。

  3. 在创建的目录中创建 application.yml 文件。 使用此文件定义 Azure 容器应用环境中所有应用程序之间共享的设置和资源,例如数据源、日志记录设置和 Spring Boot 执行器配置。

  4. 提交这些更改并将其推送到 Git 存储库。

  5. 从应用程序中删除 application.propertiesapplication.yml 文件。

管理

考虑添加 Admin for Spring 托管组件,为公开执行器终结点的 Spring Boot Web 应用程序启用管理界面。 有关详细信息,请参阅 在 Azure 容器应用

改进操作准备情况

以下建议可帮助你增强迁移应用程序的可靠性、可观测性和部署做法。

  • CI/CD 管道:添加一个用于自动且一致部署的管道。 可以查看有关 Azure PipelinesGitHub Actions 的说明。
  • 蓝绿部署:使用容器应用修订、修订标签和入口流量权重测试生产中的代码更改,然后再将其提供给最终用户。 有关详细信息,请参阅 Azure 容器应用 中的蓝绿部署
  • 服务绑定:添加服务绑定以将应用程序连接到受支持的 Azure 数据库。 服务绑定无需向 Spring Boot 应用程序提供连接信息(包括凭据)。
  • JVM 指标:启用 Java 开发堆栈以收集 JVM 核心指标。 有关详细信息,请参见 Azure 容器应用 中的 Java 应用程序的 Java 指标
  • 警报:添加 Azure Monitor 警报规则和操作组,以快速检测和解决异常情况。 有关详细信息,请参阅 在 Azure 容器应用
  • 区域冗余:通过启用区域冗余跨可用性区域复制应用。 如果发生区域中断,流量会负载均衡并自动路由到副本。 有关详细信息,请参阅 Azure 容器应用中的可靠性
  • Web 应用程序防火墙:在应用程序网关上使用 Web 应用程序防火墙保护容器应用免受常见攻击和漏洞的影响。 有关详细信息,请参阅通过应用程序网关上的网页应用防火墙保护Azure容器应用