排查常见的 Azure Spring Apps 问题

注意

基本、标准和企业计划将从 2025 年 3 月中旬开始弃用,停用期为 3 年。 建议转换到 Azure 容器应用。 有关详细信息,请参阅 Azure Spring Apps 停用公告

标准消耗和专用计划将于 2024 年 9 月 30 日开始弃用,并在六个月后完全关闭。 建议转换到 Azure 容器应用。

本文提供排查 Azure Spring Apps 开发问题的说明。 有关详细信息,请参阅 Azure Spring Apps 常见问题解答

可用性、性能和应用程序问题

应用程序无法启动

如果应用程序无法启动,你可能会发现无法连接其终结点,或者在重试几次后返回了 502。

若要进行故障排除,请将日志导出到 Azure Log Analytics。 Spring 应用程序日志的表名为 AppPlatformLogsforSpring。 有关详细信息,请参阅使用诊断设置分析日志和指标

日志中可能会显示以下错误消息:org.springframework.context.ApplicationContextException: Unable to start web server

该消息表示可能存在以下两个问题之一:

  • 某个 bean 或其依赖项之一缺失。
  • 某个 bean 属性缺失或无效。 这种情况下会显示“java.lang.IllegalArgumentException”。

服务绑定也可能会导致应用程序启动失败。 若要查询日志,请使用与绑定的服务相关的关键字。 例如,假设应用程序已绑定到设置为本地系统时间的 MySQL 实例。 如果该应用程序无法启动,你可能会在日志中看到以下错误消息:

“java.sql.SQLException:服务器时区值‘协调世界时’无法识别或表示多个时区。”

若要修复此错误,请转到 MySql 实例的 server parameters,并将 time_zone 值从 SYSTEM 更改为 +0:00 。

我的应用程序崩溃或引发意外错误

调试应用程序崩溃时,请先检查应用程序的运行状态和发现状态。 为此,请在 Azure 门户中转到“应用”,确保所有应用程序的状态为“正在运行”和“已启动”。

  • 如果状态是“正在运行”,但发现状态不是“已启动”,请转到“无法注册我的应用程序”部分。

  • 如果发现状态为“已启动”,请转到“指标”检查应用程序的运行状况。 检查以下指标:

    • tomcat.global.error

      所有 Spring 应用程序异常在这里进行计数。 如果此数字很大,请转到“Azure Log Analytics”检查应用程序日志。

    • jvm.memory.max

      应用程序可用的最大内存量。 内存量可能未定义,或者即使已定义,也可能会随时间而变化。 如果已定义,使用的和提交的内存量会始终少于或等于最大值。 但是,如果分配尝试增加已用内存以致“已使用”>“已提交”,则即使“已使用”<=“最大值”仍然为 true,内存分配可能也会失败并显示“OutOfMemoryError”消息。 在这种情况下,请尝试通过使用 -Xmx 参数提高最大堆栈大小。

    • jvm.memory.used

      应用程序目前使用的内存量(以字节为单位)。 对于正常负载的 Java 应用程序,此指标系列将形成一个“锯齿”模式,即内存使用量先是小幅度地平稳增减,然后突然大幅度下降。此模式会重复。 发生此指标系列是因为在 Java 虚拟机中进行的垃圾回收,其中的收集操作体现在“锯齿”模式的下降部分。

      此指标对于帮助识别内存问题至关重要,例如:

      • 最开始时的内存爆炸。
      • 特定逻辑路径的浪涌内存分配。
      • 渐进式的内存泄漏。

    有关详细信息,请参阅指标

    注意

    这些指标仅适用于 Spring Boot 应用程序。 若要启用这些指标,请添加 spring-boot-starter-actuator 依赖项。 有关详细信息,请参阅使用 Spring Boot Actuator 管理和监视应用添加执行器依赖项部分。

  • 如果应用程序无法启动,请验证应用程序是否具有有效的 jvm 参数。 如果 JVM 内存设置过高,日志中可能会显示以下错误消息:

    “所需的内存 2728741K 大于可供分配的 2000M”

若要了解有关 Azure Log Analytics 的更多信息,请参阅 Azure Monitor 中的 Log Analytics 入门

我的应用程序的 CPU 使用率或内存使用率过高

如果应用程序的 CPU/内存使用率较高,则表示出现了以下两个问题之一:

  • 所有应用实例的 CPU/内存使用率较高。
  • 部分应用实例的 CPU/内存使用率较高。

若要确定出现了哪一种情况,请使用以下步骤:

  1. 转到“指标”,然后选择“服务 CPU 使用率百分比”或“已用服务内存” 。
  2. 添加 App= 筛选器,指定要监视哪个应用程序。
  3. 按实例拆分指标。

如果所有实例的 CPU/内存使用率较高,则需要横向扩展应用程序或纵向扩展 CPU/内存使用率。 有关详细信息,请参阅教程:在 Azure Spring Apps 中缩放应用程序

如果部分实例的 CPU/内存使用率较高,请检查实例状态及其发现状态。

有关详细信息,请参阅 Azure Spring Apps 的指标

如果所有实例都已启动并运行,请转到 Azure Log Analytics,以查询应用程序日志并查看代码逻辑。 通过此评审,可查看它们中的任何一种是否影响缩放分区。 有关详细信息,请参阅使用诊断设置分析日志和指标

若要了解有关 Azure Log Analytics 的更多信息,请参阅 Azure Monitor 中的 Log Analytics 入门。 使用 Kusto 查询语言查询日志。

用于将 Spring 应用程序部署到 Azure Spring Apps 的检查清单

将应用程序加入之前,确保其满足以下条件:

  • 应用程序可以使用指定的 Java 运行时版本在本地运行。
  • 环境配置(CPU/RAM/实例)符合应用程序提供商规定的最低要求。
  • 配置项有预期的值。 有关详细信息,请参阅为服务设置 Spring Cloud 配置服务器实例
  • 环境变量有预期的值。
  • JVM 参数有预期的值。
  • 建议禁用/删除应用程序包中的嵌入式配置服务器和 Spring 服务注册表服务 。
  • 若要通过服务绑定来绑定 Azure 资源,请确保目标资源已启动并运行。

配置和管理

我在创建 Azure Spring Apps 服务实例时遇到了问题

当你通过 Azure 门户设置 Azure Spring Apps 服务实例时,Azure Spring Apps 将为你执行验证。

但如果你尝试通过使用 Azure CLIAzure 资源管理器模板设置 Azure Spring Apps 服务实例,请验证你是否满足以下条件:

  • 订阅处于活动状态。
  • Azure Spring Apps 在你所使用的区域中可用。 有关详细信息,请参阅 Azure Spring Apps 常见问题解答
  • 已创建实例的资源组。
  • 资源名称符合命名规则。 该名称只能包含小写字母、数字和连字符。 第一个字符必须是字母。 最后一个字符必须是字母或数字。 该值必须包含 2 到 32 个字符。

如果要使用资源管理器模板设置 Azure Spring Apps 服务实例,请先参阅了解 Azure 资源管理器模板的结构和语法

Azure Spring Apps 服务实例的名称用于请求 microservices.azure.cn 下的子域名,因此,如果该名称与现有名称冲突,设置操作会失败。 可以在活动日志中找到更多详细信息。

无法部署 JAR 包

无法通过 Azure 门户或资源管理器模板上传 Java 存档文件 (JAR)/源包。

使用 Azure CLI 部署应用程序包时,Azure CLI 会定期轮询部署进度,并最终显示部署结果。

如果轮询中断,仍可使用以下命令提取部署日志:

az spring app show-deploy-log --name <app-name>

确保应用程序打包时采用正确的可执行 JAR 格式。 如果未正确打包,你会收到类似于以下示例的错误消息:Error: Invalid or corrupt jarfile /jar/11111111-1111-1111-1111-111111111111

无法部署源包

无法通过 Azure 门户或资源管理器模板上传 JAR/源包。

使用 Azure CLI 部署应用程序包时,Azure CLI 会定期轮询部署进度,并最终显示部署结果。

如果轮询中断,仍可使用以下命令提取生成和部署日志:

az spring app show-deploy-log --name <app-name>

但是,一个 Azure Spring Apps 服务实例每次只能对一个源包触发一个生成作业。 有关详细信息,请参阅部署应用程序在 Azure Spring Apps 中设置过渡环境

我的应用程序无法注册

在大多数情况下,如果在项目对象模型 (POM) 文件中未正确配置“所需依赖项”和“服务发现”,就会发生这种情况 。 配置后,内置的服务注册表服务器终结点将作为环境变量注入到应用程序中。 然后,应用程序可自行注册到服务注册表服务器,并发现其他依赖性应用程序。

等待至少 2 分钟,然后新注册的实例就会开始接收流量。

如果要将现有的基于 Spring Cloud 的解决方案迁移到 Azure,请确保删除或禁用临时的服务注册表和配置服务器实例,以免与 Azure Spring Apps 提供的托管实例冲突。

还可以在 Azure Log Analytics 中检查服务注册表客户端日志。 有关详细信息,请参阅使用诊断设置分析日志和指标

若要了解有关 Azure Log Analytics 的更多信息,请参阅 Azure Monitor 中的 Log Analytics 入门。 使用 Kusto 查询语言查询日志。

我想要检查应用程序的环境变量

环境变量会通知 Azure Spring Apps 框架,确保 Azure 了解在何处以何种方式配置构成应用程序的服务。 在排查潜在问题的过程中,必须执行的第一步是确保环境变量正确。 可以使用 Spring Boot Actuator 终结点来查看环境变量。

警告

此过程使用测试终结点公开环境变量。 如果测试终结点可以公开访问,或者你已将域名分配给应用程序,请勿继续操作。

  1. 转到 https://<your-application-test-endpoint>/actuator/health

    类似于 {"status":"UP"} 的响应表明终结点已启用。 如果响应为负面,请在 POM.xml 文件中包括以下依赖项:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    
  2. 在启用 Spring Boot Actuator 终结点的情况下,请转到 Azure 门户并找到应用程序的配置页。 添加名为 MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE 和值为 * 的环境变量。

  3. 重启应用程序。

  4. 转到 https://<your-application-test-endpoint>/actuator/env 并检查响应。 应如下所示:

    {
        "activeProfiles": [],
        "propertySources": {,
            "name": "server.ports",
            "properties": {
                "local.server.port": {
                    "value": 1025
                }
            }
        }
    }
    

找到名为 systemEnvironment 的子节点。 此节点包含应用程序的环境变量。

重要

在使应用程序可以公共访问之前,请记得反转公开环境变量的操作。 转到 Azure 门户,找到应用程序的配置页,然后删除此环境变量:MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE

我找不到应用程序的指标或日志

转到“应用”,确保应用程序状态为“正在运行”和“已启动”。

检查应用程序包中是否启用了 JMX。 可以使用配置属性 spring.jmx.enabled=true 启用此功能。

检查应用程序包中是否启用了 spring-boot-actuator 依赖项,以及该项是否成功启动。

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

如果应用程序日志可以存档到某个存储帐户,但未发送到 Azure Log Analytics,请检查是否已正确设置工作区。 有关详细信息,请参阅创建 Log Analytics 工作区。 此外,请注意,基本计划不提供服务级别协议 (SLA)。 有关详细信息,请参阅联机服务的服务级别协议 (SLA)

后续步骤