将 Spring Boot 应用程序迁移到 Azure App Service

本指南介绍了要将现有 Spring Boot 应用程序迁移到Azure App Service时应注意的内容。

迁移前

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

切换到受支持的平台

应用服务提供特定版本的 Java SE。 若要确保兼容性,请在继续执行其余任何步骤之前,将应用程序迁移到其当前环境支持的版本之一。 请务必完全测试生成的配置。 在此类测试中使用 Linux 分发版的最新稳定版本。

注释

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

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

java -version

在 Azure App Service 上,Java 8 的二进制文件由 Eclipse Temurin 提供。 对于 Java Java 11、17 和所有将来的 LTS 版本,应用服务提供 Microsoft Build of OpenJDK。 可在以下站点免费下载这些二进制文件:

清点外部资源

标识外部资源,例如数据源、JMS 消息代理和其他服务的 URL。 在 Spring Boot 应用程序中,通常可以在 src/main/directory 文件夹中查找此类资源的配置,该文件通常称为 application.properties 或 application.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.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.4.0.5")
      ...
    }

确定正在使用的一个或多个代理后,请找到相应的设置。 在 Spring Boot 应用程序中,通常可以在 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 组件文档。

标识外部缓存

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

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

身份提供者

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

所有其他的外部资源

在本指南中,不可能记录每个可能的外部依赖项。 团队负责验证应用服务迁移后是否可以满足应用程序的每个外部依赖项。

清单机密

密码和安全字符串

检查生产部署上的所有属性和配置文件以及所有环境变量,以查找任何机密字符串和密码。 在 Spring Boot 应用程序中,此类字符串很可能在 application.properties 或 application.yml 中找到。

清单证书

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

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

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

使用应用程序服务器上的文件系统需要重新配置,在极少数情况下需要体系结构更改。 可以识别下面的部分或所有情况。

只读静态内容

如果应用程序当前提供静态内容,则需要一个备用位置。 应考虑将静态内容移动到Azure Blob Storage并添加全局快速下载Azure Front Door。 有关详细信息,请参阅 Azure Storage 中的静态网站托管 和 将 Azure Storage 帐户与 Azure Front Door 集成。

特殊情况

某些生产方案可能需要其他更改或施加其他限制。 虽然这种情况可能不常见,但重要的是确保它们要么不适用于您的应用程序,要么得到正确解决。

确定应用程序是否依赖于计划的作业

计划任务(如 Quartz 调度器任务或 cron 作业)不能与应用服务一起使用。 应用服务不会阻止你在内部部署包含计划任务的应用程序。 但是,如果应用程序横向扩展,则相同的计划任务可能会在每个安排好的时间段内运行多次。 这种情况可能会导致意外的后果。

盘点应用程序流程内部或外部的任何计划任务。

确定应用程序是否包含特定于 OS 的代码

如果应用程序包含的代码有主机 OS 的依赖项,则需重构该代码,删除那些依赖项。 例如,如果应用程序在Windows上运行,可能需要将文件系统路径中的 / 或 \ 的任何用法替换为 File.Separator 或 Paths.get。

确定生产服务器上运行的所有外部进程/守护程序

在应用程序服务器外部运行的进程(例如监视守护程序)需要迁移到其他位置或消除。

确定非 HTTP 请求或多个端口的处理

应用服务仅支持单个端口上的单个 HTTP 终结点。 如果应用程序侦听多个端口或使用 HTTP 以外的协议接受请求,请不要使用Azure App Service。

迁移

参数化配置

确保所有外部资源坐标(如数据库连接字符串)和其他可自定义设置都可以从环境变量中读取。 如果要迁移 Spring Boot 应用程序,则所有配置设置都应是外部的。 有关详细信息,请参阅 Spring Boot 文档中 的外部化配置 。

下面是从 SERVICEBUS_CONNECTION_STRING 文件中引用环境变量的示例:

spring.jms.servicebus.connection-string=${SERVICEBUS_CONNECTION_STRING}
spring.jms.servicebus.topic-client-id=contoso1
spring.jms.servicebus.idle-timeout=10000

配置应用服务计划

从 可用服务计划列表中,选择其规格满足或超过当前生产硬件的计划。

注释

如果计划运行预生产/canary 部署或使用部署插槽,应用服务计划必须包含额外容量。 建议对Java应用程序使用高级或更高计划。

创建应用服务计划。

创建和部署 Web 应用

对于要运行的每个可执行 JAR 文件,需要在应用服务计划(选择“Java SE”作为运行时堆栈)上创建 Web 应用。

Maven 应用程序

如果应用程序是从 Maven POM 文件生成的,则请使用 Maven 的 Webapp 插件来创建 Web 应用并部署应用程序。 有关详细信息,请参阅 Quickstart:在 Azure App Service。

非 Maven 应用程序

如果无法使用 Maven 插件,则需通过如下所示的其他机制来预配 Web 应用:

创建 Web 应用后,请使用其中一种 可用的部署机制 来部署应用程序。 如果可能,应用程序应上传到 /home/site/wwwroot/app.jar。 如果不想将 JAR 重命名为 app.jar,可以使用命令上传 shell 脚本来运行 JAR。 然后将此脚本的完整路径粘贴到门户的“配置”部分的 “启动文件 ”文本框中。 启动脚本不会在其放置的目录中运行。 因此,始终使用绝对路径来引用启动脚本中的文件(例如: java -jar /home/myapp/myapp.jar

迁移 JVM 运行时选项

如果应用程序需要特定的运行时选项, 请使用最合适的机制来指定它们。

配置自定义域和 SSL

如果应用程序将在自定义域上可见,则需将 Web 应用程序映射到它。 有关详细信息,请参阅 Tutorial:将现有自定义 DNS 名称映射到 Azure App Service。

然后,需要将该域的 SSL 证书绑定到应用服务 Web 应用。 有关详细信息,请参阅 在 Azure App Service 中使用 SSL 绑定保护自定义 DNS 名称。

导入后端证书

与后端系统(如数据库)通信的所有证书都需要提供给应用服务。 有关详细信息,请参阅 在应用服务中添加 SSL 证书。

迁移外部资源坐标和其他设置

按照以下步骤 迁移连接字符串和其他设置。

注释

对于使用参数 化配置 节中的变量参数化的任何 Spring Boot 应用程序设置,必须在应用程序配置中定义这些环境变量。 任何未使用环境变量明确参数化的 Spring Boot 应用程序设置仍然可以通过应用程序配置被覆盖。 例如:

spring.jms.servicebus.connection-string=${CUSTOMCONNSTR_SERVICE_BUS}
spring.jms.servicebus.topic-client-id=contoso1
spring.jms.servicebus.idle-timeout=1800000

应用服务应用程序配置

迁移计划任务

若要在 Azure 上执行计划任务,请考虑使用 Timer 触发器 for Azure Functions。 无需将作业代码本身迁移到函数中。 函数可以直接在应用程序中调用 URL 来触发作业。 如果此类作业执行必须动态调用和/或集中跟踪,请考虑使用 Spring Batch。

或者,可以使用定期触发器创建逻辑应用来调用 URL,而无需在应用程序外部编写任何代码。 有关详细信息,请参阅 概述 - 什么是 Azure Logic Apps? 和 在 Azure Logic Apps 中使用定期触发器创建、安排和运行定期任务和工作流。

注释

为了防止恶意使用,您可能需要确保作业调用接口要求输入凭据。 在这种情况下,触发器函数需要提供凭据。

迁移和启用标识提供者

如果应用程序需要身份验证和授权,请根据以下指南确保其配置为可以访问身份提供者:

  • 如果标识提供者Microsoft Entra ID,则无需更改。
  • 如果标识提供者是本地的 Active Directory 林,请考虑使用 Microsoft Entra ID 实现混合标识解决方案。 有关详细信息,请参阅混合标识文档。
  • 如果标识提供者是另一个本地解决方案(如 PingFederate),请查阅 Microsoft Entra Connect 自定义安装主题以配置与 Microsoft Entra ID 的联合。 或者,请考虑使用 Spring Security,通过 OAuth2/OpenID Connect 或 SAML 来使用身份提供者。

重启和冒烟测试

最后,需重启 Web 应用以应用所有配置更改。 重启完成后,请验证应用程序是否正常运行。

迁移后

将应用程序迁移到Azure App Service后,应验证它是否按预期工作。 完成上述步骤后,我们有一些建议给你,可以使你的应用程序更加符合云原生。

建议

  • 如果选择将 /home 目录用于文件存储,请考虑使用 将其替换为 Azure Storage。

  • 如果您的 /home 目录中有包含连接字符串、SSL 密钥和其他机密信息的配置,请考虑尽可能使用 Azure Key Vault 和/或通过应用程序设置进行参数注入。

  • 请考虑 将部署插槽 用于实现可靠的部署和零停机。

  • 设计和实施 DevOps 策略。 若要在提高开发速度的同时保持可靠性,请考虑使用 Azure Pipelines 自动执行部署和测试。 使用部署槽位时,可以 自动部署到槽 ,然后执行槽位交换。

  • 设计和实施业务连续性和灾难恢复策略。 对于任务关键型应用程序,请考虑 使用多区域部署体系结构。