将 Spring Boot 应用程序迁移到 Azure 应用服务

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

迁移前

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

切换到受支持的平台

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

注释

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

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

java -version

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

清点外部资源

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

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

身份提供者

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

所有其他的外部资源

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

清单机密

密码和安全字符串

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

清单证书

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

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

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

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

只读静态内容

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

特殊情况

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

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

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

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

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

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

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

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

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

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

迁移

参数化配置

确保所有外部资源坐标(如数据库连接字符串)和其他可自定义设置都可以从环境变量中读取。 如果要迁移 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 应用并部署应用程序。 有关详细信息,请参阅快速入门:在 Azure 应用程序服务上创建 Java 应用

非 Maven 应用程序

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

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

迁移 JVM 运行时选项

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

配置自定义域和 SSL

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

然后,需要将该域的 SSL 证书绑定到应用服务 Web 应用。 有关详细信息,请参阅在 Azure 应用服务中使用 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 上执行计划作业,请考虑 对 Azure Functions 使用计时器触发器。 无需将作业代码本身迁移到函数中。 函数可以直接在应用程序中调用 URL 来触发作业。 如果此类作业执行必须动态调用和/或集中跟踪,请考虑使用 Spring Batch

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

注释

若要防止恶意使用,可能需确保作业调用终结点要求使用凭据。 在这种情况下,触发器函数需要提供凭据。

迁移和启用标识提供者

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

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

重启和冒烟测试

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

迁移后

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

建议