为 Azure 应用服务配置 Java 应用

注意

对于 Spring 应用程序,我们建议使用 Azure Spring Apps。 但是,你仍然可以使用 Azure 应用服务作为目标。

Azure 应用服务可让 Java 开发人员在完全托管服务中快速生成、部署和缩放其 Java SE、Tomcat 和 JBoss EAP Web 应用程序。 可以在命令行或者 IntelliJ、Eclipse 或 Visual Studio Code 等编辑器中使用 Maven 插件部署应用程序。

本指南为使用应用服务的 Java 开发人员提供了重要概念和说明。 如果你从未用过 Azure 应用服务,首先应该通读 Java 快速入门应用服务常见问题解答中解答了有关使用应用服务且非特定于 Java 开发的一般问题。

显示 Java 版本

若要显示当前的 Java 版本,请在 Azure CLI 中运行以下命令:

az webapp config show --name <app-name> --resource-group <resource-group-name> --query "[javaVersion, javaContainer, javaContainerVersion]"

若要显示所有受支持的 Java 版本,请在 Azure CLI 中运行以下命令:

az webapp list-runtimes --os windows | grep java

若要显示当前的 Java 版本,请在 Azure CLI 中运行以下命令:

az webapp config show --resource-group <resource-group-name> --name <app-name> --query linuxFxVersion

若要显示所有受支持的 Java 版本,请在 Azure CLI 中运行以下命令:

az webapp list-runtimes --os linux | grep "JAVA\|TOMCAT\|JBOSSEAP"

有关版本支持的详细信息,请参阅应用服务语言运行时支持策略

部署应用

生成工具

Maven

使用适用于 Azure Web 应用的 Maven 插件,可以在项目根中使用一个命令来轻松为 Azure Web 应用准备 Maven Java 项目:

mvn com.microsoft.azure:azure-webapp-maven-plugin:2.11.0:config

此命令会提示你选择现有的或创建新的 Azure Web 应用,通过这种方式来添加 azure-webapp-maven-plugin 插件和相关配置。 然后可以使用以下命令将 Java 应用部署到 Azure:

mvn package azure-webapp:deploy

下面是 pom.xml 中的示例配置:

<plugin> 
  <groupId>com.microsoft.azure</groupId>  
  <artifactId>azure-webapp-maven-plugin</artifactId>  
  <version>2.11.0</version>  
  <configuration>
    <subscriptionId>111111-11111-11111-1111111</subscriptionId>
    <resourceGroup>spring-boot-xxxxxxxxxx-rg</resourceGroup>
    <appName>spring-boot-xxxxxxxxxx</appName>
    <pricingTier>B2</pricingTier>
    <region>chinanorth</region>
    <runtime>
      <os>Linux</os>      
      <webContainer>Java SE</webContainer>
      <javaVersion>Java 11</javaVersion>
    </runtime>
    <deployment>
      <resources>
        <resource>
          <type>jar</type>
          <directory>${project.basedir}/target</directory>
          <includes>
            <include>*.jar</include>
          </includes>
        </resource>
      </resources>
    </deployment>
  </configuration>
</plugin> 

Gradle

  1. 通过将适用于 Azure Web 应用的 Gradle 插件添加到 build.gradle 来设置该插件:

    plugins {
      id "com.microsoft.azure.azurewebapp" version "1.7.1"
    }
    
  2. 配置 Web 应用详细信息,相应的 Azure 资源将会被创建(如果不存在)。 下面是示例配置。有关详细信息,请查看此文档

    azurewebapp {
        subscription = '<your subscription id>'
        resourceGroup = '<your resource group>'
        appName = '<your app name>'
        pricingTier = '<price tier like 'P1v2'>'
        region = '<region like 'chinanorth'>'
        runtime {
          os = 'Linux'
          webContainer = 'Tomcat 9.0' // or 'Java SE' if you want to run an executable jar
          javaVersion = 'Java 8'
        }
        appSettings {
            <key> = <value>
        }
        auth {
            type = 'azure_cli' // support azure_cli, oauth2, device_code and service_principal
        }
    }
    
  3. 使用一个命令进行部署。

    gradle azureWebAppDeploy
    

IDE

Azure 在常用 Java IDE 中提供了无缝的 Java 应用服务开发体验,这些 IDE 包括:

Kudu API

Java SE

若要将 .jar 文件部署到 Java SE,请使用 Kudu 站点的 /api/publish/ 终结点。 有关此 API 的详细信息,请参阅此文档

注意

必须将 .jar 应用程序命名为 app.jar,应用服务才能识别并运行该应用程序。 在部署过程中,(上述)Maven 插件会自动重命名应用程序。 如果不希望将 JAR 重命名为 app.jar,可使用命令上传 shell 脚本来运行 .jar 应用。 将此脚本的绝对路径粘贴到门户的“配置”部分的启动文件文本框中。 启动脚本不从放置它的目录运行。 因此,请始终使用绝对路径在启动脚本中引用文件(例如:java -jar /home/myapp/myapp.jar)。

Tomcat

若要将 .war 文件部署到 Tomcat,请使用 /api/wardeploy/ 终结点对存档文件执行 POST 操作。 有关此 API 的详细信息,请参阅此文档

不要使用 FTP 来部署 .war 或 .jar。 FTP 工具设计用来上传启动脚本、依赖项或其他运行时文件。 它不是用于部署 Web 应用的最佳选项。

日志记录和调试应用

可以通过 Azure 门户对每个应用使用性能报告、流量可视化和运行状况检查。

网络流量记录器

应用服务上使用 Azul JVM 的所有 Java 运行时均附带 Zulu 网络流量记录器。 可以使用它来记录 JVM、系统和应用程序事件,并对 Java 应用程序中的问题进行故障排除。

若要访问应用服务中的应用程序代码内生成的控制台日志,请在 Azure CLI 中运行以下命令以打开诊断日志记录:

az webapp log config --resource-group <resource-group-name> --name <app-name> --docker-container-logging filesystem --level Verbose

--level 的可能值为:ErrorWarningInfoVerbose。 每个后续级别包括上一个级别。 例如:Error 仅包含错误消息,Verbose 则包含所有消息。

启用诊断日志记录功能以后,请运行以下命令来查看日志流:

az webapp log tail --resource-group <resource-group-name> --name <app-name>

如果没有立即看到控制台日志,请在 30 秒后重新查看。

注意

也可通过浏览器在 https://<app-name>.scm.chinacloudsites.cn/api/logs/docker 中检查日志文件。

若要随时停止日志流式处理,请键入 Ctrl+C

可以访问在容器中生成的控制台日志。

首先,请运行以下命令,以便启用容器日志记录功能:

az webapp log config --name <app-name> --resource-group <resource-group-name> --docker-container-logging filesystem

<app-name><resource-group-name> 替换为适合 Web 应用的名称。

启用容器日志记录功能以后,请运行以下命令来查看日志流:

az webapp log tail --name <app-name> --resource-group <resource-group-name>

如果没有立即看到控制台日志,请在 30 秒后重新查看。

若要随时停止日志流式处理,可键入 CtrlC。

也可通过浏览器在 https://<app-name>.scm.chinacloudsites.cn/api/logs/docker 中检查日志文件。

SSH 控制台访问

若要通过容器打开直接的 SSH 会话,应用应该处于正在运行状态。

将以下 URL 粘贴到浏览器中,将 <app-name> 替换为应用名称:

https://<app-name>.scm.chinacloudsites.cn/webssh/host

如果尚未进行身份验证,则需通过要连接的 Azure 订阅进行身份验证。 完成身份验证以后,可以看到一个浏览器内 shell,可以在其中的容器中运行命令。

SSH 连接

注意

/home 目录之外进行的任何更改均存储在容器本身中,在应用重启后不保留。

若要从本地计算机打开远程 SSH 会话,请参阅从远程 shell 打开 SSH 会话

连续记录

你可以使用 Zulu 网络流量记录器在对运行时的性能影响最小的情况下连续分析 Java 应用程序。 为此,请运行以下 Azure CLI 命令,通过必要的配置创建名为 JAVA_OPTS 的应用设置。 应用启动后,JAVA_OPTS 应用设置的内容会被传递到 java 命令。

az webapp config appsettings set -g <your_resource_group> -n <your_app_name> --settings JAVA_OPTS=-XX:StartFlightRecording=disk=true,name=continuous_recording,dumponexit=true,maxsize=1024m,maxage=1d

开始记录后,你可以使用 JFR.dump 命令随时转储当前的记录数据。

jcmd <pid> JFR.dump name=continuous_recording filename="/home/recording1.jfr"

Java 探查器

Azure 应用服务上的所有 Java 运行时都附带 JDK 运行情况记录器,用于分析 Java 工作负载。 你可以使用它来记录 JVM、系统和应用程序事件,并排查应用程序中的问题。

应用日志记录

通过 Azure 门户或 Azure CLI 启用应用程序日志记录,以将应用服务配置为向本地文件系统或 Azure Blob 存储写入应用程序的标准控制台输出和标准控制台错误流。 在完成配置 12 个小时后,禁止记录到应用服务的本地文件系统实例。 如果需要保留日志更长时间,请将应用程序配置为向 Blob 存储容器写入输出。 Java 和 Tomcat 应用日志位于 /home/LogFiles/Application/ 目录中。

通过 Azure 门户或 Azure CLI 启用应用程序日志记录,以将应用服务配置为向本地文件系统或 Azure Blob 存储写入应用程序的标准控制台输出和标准控制台错误流。 如果需要保留日志更长时间,请将应用程序配置为向 Blob 存储容器写入输出。 Java 和 Tomcat 应用日志位于 /home/LogFiles/Application/ 目录中。

只能使用 Azure Monitor 配置适用于基于 Linux 的应用服务的 Azure Blob 存储日志记录功能

如果应用程序使用 LogbackLog4j 进行跟踪,则你可以遵照在 Application Insights 中浏览 Java 跟踪日志中的日志记录框架配置说明,将这些用于审查的跟踪写入到 Azure Application Insights。

注意

由于已知漏洞 CVE-2021-44228,请务必使用 Log4j 版本 2.16 或更高版本。

自定义和优化

Azure 应用服务原生支持通过 Azure 门户和 CLI 进行优化和自定义。 请查看以下文章了解非特定于 Java 的 Web 应用配置:

在本地复制应用内容

将应用设置 JAVA_COPY_ALL 设为 true,以将应用内容从共享文件系统复制到本地辅助角色。 这有助于解决文件锁定问题。

设置 Java 运行时选项

若要设置分配的内存或其他 JVM 运行时选项,请使用这些选项创建名为 JAVA_OPTS应用设置。 应用服务在启动时,会将此设置作为环境变量传递给 Java 运行时。

在 Azure 门户中,在 Web 应用的“应用程序设置”下为 Java SE 创建一个名为 JAVA_OPTS 的新应用设置,或为 Tomcat 创建一个 CATALINA_OPTS,其中包含 -Xms512m -Xmx1204m 等其他设置。

若要通过 Maven 插件配置应用设置,请在 Azure 插件部分中添加设置/值标记。 以下示例设置特定的最小和最大 Java 堆大小:

<appSettings>
    <property>
        <name>JAVA_OPTS</name>
        <value>-Xms1024m -Xmx1024m</value>
    </property>
</appSettings>

注意

在 Windows 应用服务上使用 Tomcat 时,无需创建 web.config 文件。

在应用服务计划中运行包含一个部署槽位的单个应用程序的开发人员可以使用以下选项:

  • B1 和 S1 实例:-Xms1024m -Xmx1024m
  • B2 和 S2 实例:-Xms3072m -Xmx3072m
  • B3 和 S3 实例:-Xms6144m -Xmx6144m
  • P1v2 实例:-Xms3072m -Xmx3072m
  • P2v2 实例:-Xms6144m -Xmx6144m
  • P3v2 实例:-Xms12800m -Xmx12800m
  • P1v3 实例:-Xms6656m -Xmx6656m
  • P2v3 实例:-Xms14848m -Xmx14848m
  • P3v3 实例:-Xms30720m -Xmx30720m
  • I1 实例:-Xms3072m -Xmx3072m
  • I2 实例:-Xms6144m -Xmx6144m
  • I3 实例:-Xms12800m -Xmx12800m
  • I1v2 实例:-Xms6656m -Xmx6656m
  • I2v2 实例:-Xms14848m -Xmx14848m
  • I3v2 实例:-Xms30720m -Xmx30720m

优化应用程序堆设置时,请查看应用服务计划详细信息,并考虑多个应用程序和部署槽位方面的需求,以得出最佳内存分配。

启用 Web 套接字

在 Azure 门户中应用程序的“应用程序设置”中启用 Web 套接字支持。 需要重启应用程序才能使设置生效。

在 Azure CLI 中使用以下命令启用 Web 套接字支持:

az webapp config set --name <app-name> --resource-group <resource-group-name> --web-sockets-enabled true

然后重启应用程序:

az webapp stop --name <app-name> --resource-group <resource-group-name>
az webapp start --name <app-name> --resource-group <resource-group-name>

设置默认的字符编码

在 Azure 门户中 Web 应用的“应用程序设置”下,创建名为 JAVA_OPTS 且包含值 -Dfile.encoding=UTF-8 的新应用设置。

或者,可以使用应用服务 Maven 插件配置应用设置。 在插件配置中添加设置名称和值标记:

<appSettings>
    <property>
        <name>JAVA_OPTS</name>
        <value>-Dfile.encoding=UTF-8</value>
    </property>
</appSettings>

预编译 JSP 文件

要提高 Tomcat 应用程序的性能,可以先编译 JSP 文件,再部署到应用服务。 你可以使用由 Apache Sling 提供的 Maven 插件,也可以使用此 Ant 生成文件

安全应用程序

在应用服务中运行的 Java 应用程序实施与其他应用程序相同的一套安全最佳做法

对用户进行身份验证(简易身份验证)

在 Azure 门户中使用“身份验证和授权”选项设置应用身份验证。 在此处,可以使用 Microsoft Entra ID 或社交登录(如 GitHub)启用身份验证。 仅当配置单个身份验证提供程序时,Azure 门户配置才起作用。 有关详细信息,请参阅将应用服务应用配置为使用 Microsoft Entra 登录以及其他标识提供者的相关文章。

Java SE

Spring Boot 开发人员可以使用 Microsoft Entra Spring Boot Starter 通过熟悉的 Spring Security 注释和 API 来保护应用程序。 务必增加 application.properties 文件中的最大标头大小。 我们建议值为 16384

Tomcat

Tomcat 应用程序可通过将 Principal 对象强制转换为 Map 对象这种方式,直接从 Servlet 访问用户的声明。 Map 对象会将每个声明类型映射到该类型的声明集合。 在下面的代码中,requestHttpServletRequest 的实例。

Map<String, Collection<String>> map = (Map<String, Collection<String>>) request.getUserPrincipal();

现在,你可以检查 Map 对象是否有任何特定的声明。 例如,以下代码片段循环访问所有声明类型,并输出各集合的内容。

for (Object key : map.keySet()) {
        Object value = map.get(key);
        if (value != null && value instanceof Collection {
            Collection claims = (Collection) value;
            for (Object claim : claims) {
                System.out.println(claims);
            }
        }
    }

若要将用户注销,请使用 /.auth/ext/logout 路径。 若要执行其他操作,请参阅有关应用服务身份验证和授权的用法文档。 还可以阅读关于 Tomcat HttpServletRequest 接口及其方法的官方文档。 以下 Servlet 方法是基于你的应用服务配置解除冻结的:

public boolean isSecure()
public String getRemoteAddr()
public String getRemoteHost()
public String getScheme()
public int getServerPort()

要禁用此功能,请创建一个名为 WEBSITE_AUTH_SKIP_PRINCIPAL 的应用程序设置,其值为 1。 若要禁用应用服务添加的所有 servlet 筛选器,请创建名为 WEBSITE_SKIP_FILTERS、值为 1 的设置。

配置 TLS/SSL

按照在 Azure 应用服务中使用 TLS/SSL 绑定保护自定义 DNS 名称中的说明,上传现有的 TLS/SSL 证书,并将其绑定到应用程序的域名。 在默认情况下,应用程序仍会允许 HTTP 连接 - 请遵循教程中的具体步骤来强制实施 TLS/SSL。

使用 Key Vault 引用

Azure Key Vault 通过访问策略和审核历史记录提供集中式机密管理。 你可以在 Key Vault 中存储机密(例如密码或连接字符串),并通过环境变量在应用程序中访问这些机密。

首先,请按照说明执行以下操作:授予应用对密钥保管库的访问权限以及在应用程序设置中创建对机密的 KeyVault 引用。 你可以验证在远程访问应用服务终端时,该引用是否通过输出环境变量解析为机密。

若要在 Spring 或 Tomcat 配置文件中注入这些机密,请使用环境变量注入语法(即 ${MY_ENV_VAR})。 请参阅有关外部化配置的文档来了解 Spring 配置文件。

使用 Java 密钥存储

在容器启动时,系统会默认将上传到应用服务 Linux 的公用或专用证书都加载到各自的 Java 密钥存储中。 上传证书后,需要重启应用服务,以便将它加载到 Java 密钥存储中。 系统会将公用证书加载到位于 $JRE_HOME/lib/security/cacerts 的密钥存储中,将专用证书存储到 $JRE_HOME/lib/security/client.jks 中。

如果要在 Java 密钥存储中使用证书加密 JDBC 连接,可能需要其他配置。 请参阅适用于所选 JDBC 驱动程序的文档。

初始化 Java 密钥存储

要初始化 import java.security.KeyStore 对象,请使用密码加载密钥存储文件。 这两个密钥存储的默认密码均为 changeit

KeyStore keyStore = KeyStore.getInstance("jks");
keyStore.load(
    new FileInputStream(System.getenv("JRE_HOME")+"/lib/security/cacerts"),
    "changeit".toCharArray());

KeyStore keyStore = KeyStore.getInstance("pkcs12");
keyStore.load(
    new FileInputStream(System.getenv("JRE_HOME")+"/lib/security/client.jks"),
    "changeit".toCharArray());

手动加载密钥存储

可以手动向密钥存储加载证书。 创建应用设置 SKIP_JAVA_KEYSTORE_LOAD,将其值设置为 1,以禁止应用服务自动将证书加载到密钥存储。 所有通过 Azure 门户上传到应用服务的公用证书都存储在 /var/ssl/certs/ 下。 专用证书则存储在 /var/ssl/private/ 下。

打开与应用服务的 SSH 连接并运行命令 keytool,即可与 Java 密钥工具进行交互或对它进行调试。 请参阅密钥工具文档,获取命令列表。 有关密钥存储 API 的详细信息,请参阅官方文档

配置 APM 平台

本部分介绍如何将 Azure 应用服务上部署的 Java 应用程序与 Azure Monitor Application Insights、NewRelic 和 AppDynamics 应用程序性能监视 (APM) 平台进行连接。

配置 Application Insights

Azure Monitor Application Insights 是一项云本机应用程序监视服务,它使客户能够观察故障、瓶颈和使用模式,以便提高应用程序性能并减少平均解决时间 (MTTR)。 只需单击几下或使用 CLI 命令,就可以启用对 Node.js 或 Java 应用的监视,自动收集日志、指标和分布式跟踪,而无需在应用中包含 SDK。 若要详细了解可用于配置代理的应用设置,请查看 Application Insights 文档

Azure 门户

要从 Azure 门户启用“Application Insights”,请转到左侧菜单的“Application Insights”,选择“启用 Application Insights”。 默认情况下,将使用与 Web 应用名称相同的新 Application Insights 资源。 可以选择使用现有的 Application Insights 资源,也可以更改名称。 选择底部的“应用”

Azure CLI

要通过 Azure CLI 启用,需要创建一个 Application Insights 资源并在 Azure 门户上设置几个应用设置,以将 Application Insights 连接到 Web 应用。

  1. 启用 Applications Insights 扩展

    az extension add -n application-insights
    
  2. 使用下面的 CLI 命令创建 Application Insights 资源。 将占位符替换为所需的资源名称和组。

    az monitor app-insights component create --app <resource-name> -g <resource-group> --location chinanorth2  --kind web --application-type web
    

    记下 connectionStringinstrumentationKey 的值,你将在下一步中使用这些值。

    要检索其他位置的列表,请运行 az account list-locations

  1. 将检测密钥、连接字符串和监视代理版本作为 Web 应用上的应用设置进行设置。 将 <instrumentationKey><connectionString> 替换为上一步中的值。

    az webapp config appsettings set -n <webapp-name> -g <resource-group> --settings "APPINSIGHTS_INSTRUMENTATIONKEY=<instrumentationKey>" "APPLICATIONINSIGHTS_CONNECTION_STRING=<connectionString>" "ApplicationInsightsAgent_EXTENSION_VERSION=~3" "XDT_MicrosoftApplicationInsights_Mode=default" "XDT_MicrosoftApplicationInsights_Java=1"
    
  1. 将检测密钥、连接字符串和监视代理版本作为 Web 应用上的应用设置进行设置。 将 <instrumentationKey><connectionString> 替换为上一步中的值。

    az webapp config appsettings set -n <webapp-name> -g <resource-group> --settings "APPINSIGHTS_INSTRUMENTATIONKEY=<instrumentationKey>" "APPLICATIONINSIGHTS_CONNECTION_STRING=<connectionString>" "ApplicationInsightsAgent_EXTENSION_VERSION=~3" "XDT_MicrosoftApplicationInsights_Mode=default"
    

配置 NewRelic

  1. NewRelic.com 上创建一个 NewRelic 帐户

  2. 从 NewRelic 下载 Java 代理,该代理的文件名类似于 newrelic-java-x.x.x.zip。

  3. 复制你的许可证密钥,稍后需要使用它来配置代理。

  4. 通过 SSH 登录到应用服务实例,并创建新目录 /home/site/wwwroot/apm。

  5. 将解压缩的 NewRelic Java 代理文件上传到 /home/site/wwwroot/apm 下的一个目录中。 代理的文件应位于 /home/site/wwwroot/apm/newrelic 中。

  6. 修改位于 /home/site/wwwroot/apm/newrelic/newrelic.yml 处的 YAML 文件,并将占位符许可证值替换为你自己的许可证密钥。

  7. 在 Azure 门户中,浏览到你在应用服务中的应用程序并创建一个新的应用程序设置。

    • 对于 Java SE 应用,请创建一个名为 JAVA_OPTS 且值为 -javaagent:/home/site/wwwroot/apm/newrelic/newrelic.jar 的环境变量。
    • 对于 Tomcat,请创建一个名为 CATALINA_OPTS 且值为 -javaagent:/home/site/wwwroot/apm/newrelic/newrelic.jar 的环境变量。
  1. NewRelic.com 上创建一个 NewRelic 帐户

  2. 从 NewRelic 下载 Java 代理,该代理的文件名类似于 newrelic-java-x.x.x.zip。

  3. 复制你的许可证密钥,稍后需要使用它来配置代理。

  4. 通过 SSH 登录到应用服务实例,并创建新目录 /home/site/wwwroot/apm。

  5. 将解压缩的 NewRelic Java 代理文件上传到 /home/site/wwwroot/apm 下的一个目录中。 代理的文件应位于 /home/site/wwwroot/apm/newrelic 中。

  6. 修改位于 /home/site/wwwroot/apm/newrelic/newrelic.yml 处的 YAML 文件,并将占位符许可证值替换为你自己的许可证密钥。

  7. 在 Azure 门户中,浏览到你在应用服务中的应用程序并创建一个新的应用程序设置。

    • 对于 Java SE 应用,请创建一个名为 JAVA_OPTS 且值为 -javaagent:/home/site/wwwroot/apm/newrelic/newrelic.jar 的环境变量。
    • 对于 Tomcat,请创建一个名为 CATALINA_OPTS 且值为 -javaagent:/home/site/wwwroot/apm/newrelic/newrelic.jar 的环境变量。

如果你已有 JAVA_OPTSCATALINA_OPTS 的环境变量,请将 -javaagent:/... 选项追加到当前值的末尾。

配置 AppDynamics

  1. AppDynamics.com 上创建一个 AppDynamics 帐户

  2. 从 AppDynamics 网站下载 Java 代理,文件名将类似于 AppServerAgent-x.x.x.xxxxx.zip

  3. 使用 Kudu 控制台创建新目录 /home/site/wwwroot/apm

  4. 将 Java 代理文件上传到 /home/site/wwwroot/apm 下的一个目录中。 代理的文件应位于 /home/site/wwwroot/apm/appdynamics 中。

  5. 在 Azure 门户中,浏览到你在应用服务中的应用程序并创建一个新的应用程序设置。

    • 对于 Java SE 应用,请创建一个名为 JAVA_OPTS 且值为 -javaagent:/home/site/wwwroot/apm/appdynamics/javaagent.jar -Dappdynamics.agent.applicationName=<app-name> 的环境变量,其中,<app-name> 是你的应用服务名称。
    • 对于 Tomcat 应用,请创建一个名为 CATALINA_OPTS 且值为 -javaagent:/home/site/wwwroot/apm/appdynamics/javaagent.jar -Dappdynamics.agent.applicationName=<app-name> 的环境变量,其中,<app-name> 是你的应用服务名称。
  1. AppDynamics.com 上创建一个 AppDynamics 帐户

  2. 从 AppDynamics 网站下载 Java 代理,文件名将类似于 AppServerAgent-x.x.x.xxxxx.zip

  3. 通过 SSH 登录到应用服务实例,并创建新目录 /home/site/wwwroot/apm。

  4. 将 Java 代理文件上传到 /home/site/wwwroot/apm 下的一个目录中。 代理的文件应位于 /home/site/wwwroot/apm/appdynamics 中。

  5. 在 Azure 门户中,浏览到你在应用服务中的应用程序并创建一个新的应用程序设置。

    • 对于 Java SE 应用,请创建一个名为 JAVA_OPTS 且值为 -javaagent:/home/site/wwwroot/apm/appdynamics/javaagent.jar -Dappdynamics.agent.applicationName=<app-name> 的环境变量,其中,<app-name> 是你的应用服务名称。
    • 对于 Tomcat 应用,请创建一个名为 CATALINA_OPTS 且值为 -javaagent:/home/site/wwwroot/apm/appdynamics/javaagent.jar -Dappdynamics.agent.applicationName=<app-name> 的环境变量,其中,<app-name> 是你的应用服务名称。

注意

如果你已有 JAVA_OPTSCATALINA_OPTS 的环境变量,请将 -javaagent:/... 选项追加到当前值的末尾。

配置数据源

Java SE

若要连接 Spring Boot 中的数据源,我们建议创建连接字符串并将它们注入 application.properties 文件中。

  1. 在应用服务页面的“配置”部分,为字符串设置一个名称,将 JDBC 连接字符串粘贴到值字段中,然后将类型设置为“自定义”。 你可以选择将此连接字符串设置为槽设置。

    此连接字符串可作为名为 CUSTOMCONNSTR_<your-string-name> 的环境变量供应用程序访问。 例如,我们在上面创建的连接字符串将被命名为 CUSTOMCONNSTR_exampledb

  2. 在 application.properties 文件中,通过环境变量名称引用此连接字符串。 在我们的示例中,我们将使用以下代码。

    app.datasource.url=${CUSTOMCONNSTR_exampledb}
    

有关详细信息,请参阅有关数据访问的 Spring Boot 文档外部化配置

Tomcat

这些说明适用于所有数据库连接。 需要使用所选数据库的驱动程序类名称和 JAR 文件来填充占位符。 下面提供了一个表,其中包含了常见数据库的类名称和驱动程序下载。

数据库 驱动程序类名称 JDBC 驱动程序
PostgreSQL org.postgresql.Driver 下载
MySQL com.mysql.jdbc.Driver 下载(选择“独立于平台”)
SQL Server com.microsoft.sqlserver.jdbc.SQLServerDriver 下载

若要将 Tomcat 配置为使用 Java Database Connectivity (JDBC) 或 Java 持久性 API (JPA),请先自定义在启动时由 Tomcat 读取的 CATALINA_OPTS 环境变量。 在应用服务 Maven 插件中通过某个应用设置来设置这些值:

<appSettings>
    <property>
        <name>CATALINA_OPTS</name>
        <value>"$CATALINA_OPTS -Ddbuser=${DBUSER} -Ddbpassword=${DBPASSWORD} -DconnURL=${CONNURL}"</value>
    </property>
</appSettings>

或者在 Azure 门户的“配置”>“应用程序设置”页中设置环境变量 。

接下来,确定数据源应当供一个应用程序使用,还是供在 Tomcat servlet 上运行的所有应用程序使用。

应用程序级的数据源

  1. 在项目的 META-INF/ 目录中创建一个 META-INF/ 文件 。 如果没有 META-INF/ 目录,请创建一个。

  2. 在 context.xml 中,添加一个 Context 元素以将数据源链接到 JNDI 地址。 将 driverClassName 占位符替换为上表中你的驱动程序的类名称。

    <Context>
        <Resource
            name="jdbc/dbconnection"
            type="javax.sql.DataSource"
            url="${connURL}"
            driverClassName="<insert your driver class name>"
            username="${dbuser}"
            password="${dbpassword}"
        />
    </Context>
    
  3. 更新应用程序的 web.xml以便在应用程序中使用该数据源。

    <resource-env-ref>
        <resource-env-ref-name>jdbc/dbconnection</resource-env-ref-name>
        <resource-env-ref-type>javax.sql.DataSource</resource-env-ref-type>
    </resource-env-ref>
    

共享的服务器级资源

Windows 上的应用服务上的 Tomcat 安装存在于应用服务计划中的共享空间内。 不能为服务器范围的配置直接修改 Tomcat 安装。 若要对 Tomcat 安装进行服务器级配置更改,必须将 Tomcat 复制到本地文件夹,你可以在其中修改 Tomcat 的配置。

在应用启动时自动创建自定义 Tomcat

你可以使用启动脚本在 web 应用启动之前执行操作。 用于自定义 Tomcat 的启动脚本需要完成以下步骤:

  1. 检查是否已在本地复制并配置 Tomcat。 如果是,启动脚本可以在此处结束。
  2. 本地复制 Tomcat。
  3. 进行所需的配置更改。
  4. 指示配置已成功完成。

对于 Windows 站点,在 wwwroot 目录中创建一个名为 startup.cmdstartup.ps1 的文件。 这样将在 Tomcat 服务器启动之前自动执行。

下面是完成这些步骤的 PowerShell 脚本:

    # Check for marker file indicating that config has already been done
    if(Test-Path "$Env:LOCAL_EXPANDED\tomcat\config_done_marker"){
        return 0
    }

    # Delete previous Tomcat directory if it exists
    # In case previous config could not be completed or a new config should be forcefully installed
    if(Test-Path "$Env:LOCAL_EXPANDED\tomcat"){
        Remove-Item "$Env:LOCAL_EXPANDED\tomcat" --recurse
    }

    # Copy Tomcat to local
    # Using the environment variable $AZURE_TOMCAT90_HOME uses the 'default' version of Tomcat
    Copy-Item -Path "$Env:AZURE_TOMCAT90_HOME\*" -Destination "$Env:LOCAL_EXPANDED\tomcat" -Recurse

    # Perform the required customization of Tomcat
    {... customization ...}

    # Mark that the operation was a success
    New-Item -Path "$Env:LOCAL_EXPANDED\tomcat\config_done_marker" -ItemType File
转换

自定义 Tomcat 版本的一个常见用例是修改 server.xmlcontext.xmlweb.xml Tomcat 配置文件。 应用服务已修改这些文件以提供平台功能。 若要继续使用这些功能,请在对这些文件进行更改时保留其内容,这一点很重要。 为实现此目的,建议使用 XSL 转换 (XSLT)。 使用 XSL 转换对 XML 文件进行更改,同时保留该文件的原始内容。

示例 XSLT 文件

此示例转换将新的连接器节点添加到 server.xml。 请注意“标识转换”,它会保留文件的原始内容。

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

    <!-- Identity transform: this ensures that the original contents of the file are included in the new file -->
    <!-- Ensure that your transform files include this block -->
    <xsl:template match="@* | node()" name="Copy">
      <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="@* | node()" mode="insertConnector">
      <xsl:call-template name="Copy" />
    </xsl:template>

    <xsl:template match="comment()[not(../Connector[@scheme = 'https']) and
                                   contains(., '&lt;Connector') and
                                   (contains(., 'scheme=&quot;https&quot;') or
                                    contains(., &quot;scheme='https'&quot;))]">
      <xsl:value-of select="." disable-output-escaping="yes" />
    </xsl:template>

    <xsl:template match="Service[not(Connector[@scheme = 'https'] or
                                     comment()[contains(., '&lt;Connector') and
                                               (contains(., 'scheme=&quot;https&quot;') or
                                                contains(., &quot;scheme='https'&quot;))]
                                    )]
                        ">
      <xsl:copy>
        <xsl:apply-templates select="@* | node()" mode="insertConnector" />
      </xsl:copy>
    </xsl:template>

    <!-- Add the new connector after the last existing Connnector if there's one -->
    <xsl:template match="Connector[last()]" mode="insertConnector">
      <xsl:call-template name="Copy" />

      <xsl:call-template name="AddConnector" />
    </xsl:template>

    <!-- ... or before the first Engine if there's no existing Connector -->
    <xsl:template match="Engine[1][not(preceding-sibling::Connector)]"
                  mode="insertConnector">
      <xsl:call-template name="AddConnector" />

      <xsl:call-template name="Copy" />
    </xsl:template>

    <xsl:template name="AddConnector">
      <!-- Add new line -->
      <xsl:text>&#xa;</xsl:text>
      <!-- This is the new connector -->
      <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" 
                 maxThreads="150" scheme="https" secure="true" 
                 keystroreFile="${{user.home}}/.keystore" keystorePass="changeit"
                 clientAuth="false" sslProtocol="TLS" />
    </xsl:template>

    </xsl:stylesheet>
用于 XSL 转换的函数

PowerShell 具有使用 XSL 转换来转换 XML 文件的内置工具。 下面的脚本是一个示例函数,你可以在 startup.ps1 中使用它来执行转换:

    function TransformXML{
        param ($xml, $xsl, $output)

        if (-not $xml -or -not $xsl -or -not $output)
        {
            return 0
        }

        Try
        {
            $xslt_settings = New-Object System.Xml.Xsl.XsltSettings;
            $XmlUrlResolver = New-Object System.Xml.XmlUrlResolver;
            $xslt_settings.EnableScript = 1;

            $xslt = New-Object System.Xml.Xsl.XslCompiledTransform;
            $xslt.Load($xsl,$xslt_settings,$XmlUrlResolver);
            $xslt.Transform($xml, $output);

        }

        Catch
        {
            $ErrorMessage = $_.Exception.Message
            $FailedItem = $_.Exception.ItemName
            Write-Host  'Error'$ErrorMessage':'$FailedItem':' $_.Exception;
            return 0
        }
        return 1
    }
应用设置

平台还需要了解自定义版本的 Tomcat 的安装位置。 可以在 CATALINA_BASE 应用设置中设置安装的位置。

可以使用 Azure CLI 更改此设置:

    az webapp config appsettings set -g $MyResourceGroup -n $MyUniqueApp --settings CATALINA_BASE="%LOCAL_EXPANDED%\tomcat"

或者,可以在 Azure 门户中手动更改设置:

  1. 请转到“设置”>“配置”>“应用程序设置”。
  2. 选择“新建应用程序设置”。
  3. 使用以下值创建设置:
    1. 名称CATALINA_BASE
    2. "%LOCAL_EXPANDED%\tomcat"
示例 startup.ps1

下面的示例脚本会将自定义 Tomcat 复制到本地文件夹,执行 XSL 转换,并指示转换成功:

    # Locations of xml and xsl files
    $target_xml="$Env:LOCAL_EXPANDED\tomcat\conf\server.xml"
    $target_xsl="$Env:HOME\site\server.xsl"

    # Define the transform function
    # Useful if transforming multiple files
    function TransformXML{
        param ($xml, $xsl, $output)

        if (-not $xml -or -not $xsl -or -not $output)
        {
            return 0
        }

        Try
        {
            $xslt_settings = New-Object System.Xml.Xsl.XsltSettings;
            $XmlUrlResolver = New-Object System.Xml.XmlUrlResolver;
            $xslt_settings.EnableScript = 1;

            $xslt = New-Object System.Xml.Xsl.XslCompiledTransform;
            $xslt.Load($xsl,$xslt_settings,$XmlUrlResolver);
            $xslt.Transform($xml, $output);
        }

        Catch
        {
            $ErrorMessage = $_.Exception.Message
            $FailedItem = $_.Exception.ItemName
            echo  'Error'$ErrorMessage':'$FailedItem':' $_.Exception;
            return 0
        }
        return 1
    }

    $success = TransformXML -xml $target_xml -xsl $target_xsl -output $target_xml

    # Check for marker file indicating that config has already been done
    if(Test-Path "$Env:LOCAL_EXPANDED\tomcat\config_done_marker"){
        return 0
    }

    # Delete previous Tomcat directory if it exists
    # In case previous config could not be completed or a new config should be forcefully installed
    if(Test-Path "$Env:LOCAL_EXPANDED\tomcat"){
        Remove-Item "$Env:LOCAL_EXPANDED\tomcat" --recurse
    }

    md -Path "$Env:LOCAL_EXPANDED\tomcat"

    # Copy Tomcat to local
    # Using the environment variable $AZURE_TOMCAT90_HOME uses the 'default' version of Tomcat
    Copy-Item -Path "$Env:AZURE_TOMCAT90_HOME\*" "$Env:LOCAL_EXPANDED\tomcat" -Recurse

    # Perform the required customization of Tomcat
    $success = TransformXML -xml $target_xml -xsl $target_xsl -output $target_xml

    # Mark that the operation was a success if successful
    if($success){
        New-Item -Path "$Env:LOCAL_EXPANDED\tomcat\config_done_marker" -ItemType File
    }

完成配置

最后,将驱动程序 JAR 放在 Tomcat 类路径中并重启应用服务。 将 JDBC 驱动程序文件放入 /home/site/lib 目录,确保它们可供 Tomcat 类加载器使用。 在本地 shell 中,为每个驱动程序 JAR 运行 az webapp deploy --type=lib

az webapp deploy --resource-group <group-name> --name <app-name> --src-path <jar-name>.jar --type=lib --target-path <jar-name>.jar

Tomcat

这些说明适用于所有数据库连接。 需要使用所选数据库的驱动程序类名称和 JAR 文件来填充占位符。 下面提供了一个表,其中包含了常见数据库的类名称和驱动程序下载。

数据库 驱动程序类名称 JDBC 驱动程序
PostgreSQL org.postgresql.Driver 下载
MySQL com.mysql.jdbc.Driver 下载(选择“独立于平台”)
SQL Server com.microsoft.sqlserver.jdbc.SQLServerDriver 下载

若要将 Tomcat 配置为使用 Java Database Connectivity (JDBC) 或 Java 持久性 API (JPA),请先自定义在启动时由 Tomcat 读取的 CATALINA_OPTS 环境变量。 在应用服务 Maven 插件中通过某个应用设置来设置这些值:

<appSettings>
    <property>
        <name>CATALINA_OPTS</name>
        <value>"$CATALINA_OPTS -Ddbuser=${DBUSER} -Ddbpassword=${DBPASSWORD} -DconnURL=${CONNURL}"</value>
    </property>
</appSettings>

或者在 Azure 门户的“配置”>“应用程序设置”页中设置环境变量 。

接下来,确定数据源应当供一个应用程序使用,还是供在 Tomcat servlet 上运行的所有应用程序使用。

应用程序级的数据源

  1. 在项目的 META-INF/ 目录中创建一个 META-INF/ 文件 。 如果没有 META-INF/ 目录,请创建一个。

  2. 在 context.xml 中,添加一个 Context 元素以将数据源链接到 JNDI 地址。 将 driverClassName 占位符替换为上表中你的驱动程序的类名称。

    <Context>
        <Resource
            name="jdbc/dbconnection"
            type="javax.sql.DataSource"
            url="${connURL}"
            driverClassName="<insert your driver class name>"
            username="${dbuser}"
            password="${dbpassword}"
        />
    </Context>
    
  3. 更新应用程序的 web.xml以便在应用程序中使用该数据源。

    <resource-env-ref>
        <resource-env-ref-name>jdbc/dbconnection</resource-env-ref-name>
        <resource-env-ref-type>javax.sql.DataSource</resource-env-ref-type>
    </resource-env-ref>
    

共享的服务器级资源

添加共享的服务器级数据源需要编辑 Tomcat 的 server.xml。 首先,上传启动脚本,然后在“配置”>“启动命令”中设置该脚本的路径 。 你可以使用 FTP 上传启动脚本。

启动脚本将进行 xsl 转换,转换为 server.xml 文件,并将所得的 xml 文件输出到 /usr/local/tomcat/conf/server.xml。 启动脚本应通过 apk 安装 libxslt。 你的 xsl 文件和启动脚本均可通过 FTP 上传。 下面是一个示例启动脚本。

# Install libxslt. Also copy the transform file to /home/tomcat/conf/
apk add --update libxslt

# Usage: xsltproc --output output.xml style.xsl input.xml
xsltproc --output /home/tomcat/conf/server.xml /home/tomcat/conf/transform.xsl /usr/local/tomcat/conf/server.xml

下面提供了一个示例 xsl 文件。 该文件向 Tomcat server.xml 添加了一个新的连接器节点。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="@* | node()" name="Copy">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="@* | node()" mode="insertConnector">
    <xsl:call-template name="Copy" />
  </xsl:template>

  <xsl:template match="comment()[not(../Connector[@scheme = 'https']) and
                                 contains(., '&lt;Connector') and
                                 (contains(., 'scheme=&quot;https&quot;') or
                                  contains(., &quot;scheme='https'&quot;))]">
    <xsl:value-of select="." disable-output-escaping="yes" />
  </xsl:template>

  <xsl:template match="Service[not(Connector[@scheme = 'https'] or
                                   comment()[contains(., '&lt;Connector') and
                                             (contains(., 'scheme=&quot;https&quot;') or
                                              contains(., &quot;scheme='https'&quot;))]
                                  )]
                      ">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()" mode="insertConnector" />
    </xsl:copy>
  </xsl:template>

  <!-- Add the new connector after the last existing Connnector if there's one -->
  <xsl:template match="Connector[last()]" mode="insertConnector">
    <xsl:call-template name="Copy" />

    <xsl:call-template name="AddConnector" />
  </xsl:template>

  <!-- ... or before the first Engine if there's no existing Connector -->
  <xsl:template match="Engine[1][not(preceding-sibling::Connector)]"
                mode="insertConnector">
    <xsl:call-template name="AddConnector" />

    <xsl:call-template name="Copy" />
  </xsl:template>

  <xsl:template name="AddConnector">
    <!-- Add new line -->
    <xsl:text>&#xa;</xsl:text>
    <!-- This is the new connector -->
    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" 
               maxThreads="150" scheme="https" secure="true" 
               keystroreFile="${{user.home}}/.keystore" keystorePass="changeit"
               clientAuth="false" sslProtocol="TLS" />
  </xsl:template>

</xsl:stylesheet>

完成配置

最后,将驱动程序 JAR 放置在 Tomcat 类路径中并重启你的应用服务。

  1. 将 JDBC 驱动程序文件放入 /home/site/lib 目录,确保它们可供 Tomcat 类加载器使用。 在本地 shell 中,为每个驱动程序 JAR 运行 az webapp deploy --type=lib
az webapp deploy --resource-group <group-name> --name <app-name> --src-path <jar-name>.jar --type=lib --path <jar-name>.jar

如果你创建了服务器级数据源,请重启应用服务 Linux 应用程序。 Tomcat 会将 CATALINA_BASE 重置为 /home/tomcat,并使用更新后的配置。

  1. 获取数据库的 JDBC 驱动程序。

  2. 为 JDBC 驱动程序创建 XML 模块定义文件。 下面显示的示例是 PostgreSQL 的模块定义。

    <?xml version="1.0" ?>
    <module xmlns="urn:jboss:module:1.1" name="org.postgres">
        <resources>
        <!-- ***** IMPORTANT : REPLACE THIS PLACEHOLDER *******-->
        <resource-root path="/home/site/deployments/tools/postgresql-42.2.12.jar" />
        </resources>
        <dependencies>
            <module name="javax.api"/>
            <module name="javax.transaction.api"/>
        </dependencies>
    </module>
    
  3. 将 JBoss CLI 命令放入名为 jboss-cli-commands.cli 的文件中。 JBoss 命令必须添加模块,并将其注册为数据源。 以下示例显示了用于 PostgreSQL 的 JBoss CLI 命令。

    #!/usr/bin/env bash
    module add --name=org.postgres --resources=/home/site/deployments/tools/postgresql-42.2.12.jar --module-xml=/home/site/deployments/tools/postgres-module.xml
    
    /subsystem=datasources/jdbc-driver=postgres:add(driver-name="postgres",driver-module-name="org.postgres",driver-class-name=org.postgresql.Driver,driver-xa-datasource-class-name=org.postgresql.xa.PGXADataSource)
    
    data-source add --name=postgresDS --driver-name=postgres --jndi-name=java:jboss/datasources/postgresDS --connection-url=${POSTGRES_CONNECTION_URL,env.POSTGRES_CONNECTION_URL:jdbc:postgresql://db:5432/postgres} --user-name=${POSTGRES_SERVER_ADMIN_FULL_NAME,env.POSTGRES_SERVER_ADMIN_FULL_NAME:postgres} --password=${POSTGRES_SERVER_ADMIN_PASSWORD,env.POSTGRES_SERVER_ADMIN_PASSWORD:example} --use-ccm=true --max-pool-size=5 --blocking-timeout-wait-millis=5000 --enabled=true --driver-class=org.postgresql.Driver --exception-sorter-class-name=org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLExceptionSorter --jta=true --use-java-context=true --valid-connection-checker-class-name=org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLValidConnectionChecker
    
  4. 创建调用此 JBoss CLI 命令的启动脚本 startup_script.sh。 以下示例演示了如何调用 jboss-cli-commands.cli。 稍后,请将应用服务配置为在容器启动时运行此脚本。

    $JBOSS_HOME/bin/jboss-cli.sh --connect --file=/home/site/deployments/tools/jboss-cli-commands.cli
    
  5. 使用所选的 FTP 客户端,将 JDBC 驱动程序、jboss-cli-commands.clistartup_script.sh 和模块定义上传到 /site/deployments/tools/

  6. 将站点配置为在容器启动时运行 startup_script.sh。 在 Azure 门户中,导航到“配置”>“通用设置”>“启动命令” 。 将“启动命令”字段设置为 /home/site/deployments/tools/startup_script.sh。 单击“保存”以保存更改。

若要确认已将数据源添加到 JBoss 服务器,请使用 SSH 进入 webapp 并运行 $JBOSS_HOME/bin/jboss-cli.sh --connect。 连接到 JBoss 后,请运行 /subsystem=datasources:read-resource 来打印数据源列表。

日志中的 robots933456

你可能会在容器日志中看到以下消息:

2019-04-08T14:07:56.641002476Z "-" - - [08/Apr/2019:14:07:56 +0000] "GET /robots933456.txt HTTP/1.1" 404 415 "-" "-"

可以放心忽略此消息。 /robots933456.txt 是一个虚拟 URL 路径,应用服务使用它来检查容器能否为请求提供服务。 404 响应只是指示该路径不存在,但它让应用服务知道容器处于正常状态并已准备就绪,可以响应请求。

选择 Java 运行时版本

应用服务允许用户选择 JVM 的主版本(例如 Java 8 或 Java 11)和补丁版本(例如 1.8.0_232 或 11.0.5)。 还可以选择在新的次要版本可用时自动更新补丁版本。 在大多数情况下,生产站点应使用 JVM 的固定补丁版本。 这将防止在补丁版本自动更新期间发生意外中断。 所有 Java Web 应用都使用 64 位 JVM,这是不可配置的。

如果使用 Tomcat,可以选择固定 Tomcat 的补丁版本。 在 Windows 上,可以固定 JVM 和 Tomcat 的补丁版本。 在 Linux 上,可以固定 Tomcat 的补丁版本;JVM 的补丁版本也会被固定,但不能单独配置。

如果选择固定次要版本,则需要定期更新站点上 JVM 的次要版本。 为了确保应用程序在较新的次要版本上运行,请创建一个过渡槽并在暂存站点上递增次要版本。 确认应用程序在新的次要版本上正常运行后,可以交换过渡槽和生产槽。

自动缩放规则

在配置用于水平缩放的自动缩放规则时,务必以递增方式(一次一个)删除实例,以确保每个被删除的实例可以将其活动(例如处理数据库事务)转移到群集的另一个成员。 在门户中配置用于纵向缩减的自动缩放规则时,请使用以下选项:

  • 操作:“计数递减”
  • 冷却:“5 分钟”或更长时间
  • 实例计数:1

不需要以递增方式添加实例(横向扩展),可以一次将多个实例添加到群集中。

应用服务上的 Tomcat 基线配置

如果 Java 开发人员了解 server.xml 文件和 Tomcat 的配置详细信息,他们就可以自信地自定义服务器设置、排查问题并将应用程序部署到 Tomcat。 其中部分可能是:

  • 自定义 Tomcat 配置:通过了解 server.xml 文件和 Tomcat 的配置详细信息,开发人员可以微调服务器设置以满足其应用程序的需求。
  • 调试:在 Tomcat 服务器上部署应用程序时,开发人员需要了解服务器配置以调试可能出现的任何问题。 其中包括检查服务器日志、检查配置文件以及识别可能发生的任何错误。
  • 排查 Tomcat 问题:Java 开发人员不可避免地会遇到 Tomcat 服务器问题,例如性能问题或配置错误。 通过了解 server.xml 文件和 Tomcat 的配置详细信息,开发人员可以快速诊断和排查这些问题,从而节省时间和精力。
  • 将应用程序部署到 Tomcat:若要将 Java Web 应用程序部署到 Tomcat,开发人员需要了解如何配置 server.xml 文件和其他 Tomcat 设置。 了解这些详细信息对于成功部署应用程序并确保它们在服务器上顺利运行至关重要。

使用 Tomcat 预配应用服务来托管 Java 工作负载(WAR 文件或 JAR 文件)时,Tomcat 配置中有一些现成的设置。 有关详细信息,请参阅 Apache Tomcat 官方文档,其中包括 Tomcat Web 服务器的默认配置。

此外,在启动 Tomcat 发行版时,还会在 server.xml 之上进一步应用某些转换。 这些转换是连接器、主机和阀设置的转换。

请注意,Tomcat 的最新版本将具有这些 server.xml。 (8.5.58 和 9.0.38 起)。 旧版本的 Tomcat 不使用转换,因此可能会有不同的行为。

连接器

<Connector port="${port.http}" address="127.0.0.1" maxHttpHeaderSize="16384" compression="on" URIEncoding="UTF-8" connectionTimeout="${site.connectionTimeout}" maxThreads="${catalina.maxThreads}" maxConnections="${catalina.maxConnections}" protocol="HTTP/1.1" redirectPort="8443"/>
  • maxHttpHeaderSize 设置为 16384
  • URIEncoding 设置为 UTF-8
  • conectionTimeout 设置为 WEBSITE_TOMCAT_CONNECTION_TIMEOUT,默认为 240000
  • maxThreads 设置为 WEBSITE_CATALINA_MAXTHREADS,默认为 200
  • maxConnections 设置为 WEBSITE_CATALINA_MAXCONNECTIONS,默认为 10000

注意

可以使用应用设置优化 connectionTimeout、maxThreads 和 maxConnections 设置

以下是一条示例 CLI 命令,可用于更改 conectionTimeout、maxThreads 或 maxConnections 的值:

az webapp config appsettings set --resource-group myResourceGroup --name myApp --settings WEBSITE_TOMCAT_CONNECTION_TIMEOUT=120000
az webapp config appsettings set --resource-group myResourceGroup --name myApp --settings WEBSITE_CATALINA_MAXTHREADS=100
az webapp config appsettings set --resource-group myResourceGroup --name myApp --settings WEBSITE_CATALINA_MAXCONNECTIONS=5000
  • 连接器使用容器的地址,而不是 127.0.0.1

主机

<Host appBase="${site.appbase}" xmlBase="${site.xmlbase}" unpackWARs="${site.unpackwars}" workDir="${site.tempdir}" errorReportValveClass="com.microsoft.azure.appservice.AppServiceErrorReportValve" name="localhost" autoDeploy="true">
  • appBase 设置为 AZURE_SITE_APP_BASE,默认为本地 WebappsLocalPath
  • xmlBase 设置为 AZURE_SITE_HOME,默认为 /site/wwwroot
  • unpackWARs 设置为 AZURE_UNPACK_WARS,默认为 true
  • workDir 设置为 JAVA_TMP_DIR,默认为 TMP
  • errorReportValveClass 使用自定义错误报告阀

<Valve prefix="site_access_log.${catalina.instance.name}" pattern="%h %l %u %t &quot;%r&quot; %s %b %D %{x-arr-log-id}i" directory="${site.logdir}/http/RawLogs" maxDays="${site.logRetentionDays}" className="org.apache.catalina.valves.AccessLogValve" suffix=".txt"/>
  • directory 设置为 AZURE_LOGGING_DIR,默认为 home\logFiles
  • maxDaysWEBSITE_HTTPLOGGING_RETENTION_DAYS,默认为 0 [永久]

在 Linux 上,它具有所有相同的自定义项,以及:

  • 向阀添加一些错误和报告页:
               <xsl:attribute name="appServiceErrorPage">
                   <xsl:value-of select="'${appService.valves.appServiceErrorPage}'"/>
               </xsl:attribute>

               <xsl:attribute name="showReport">
                   <xsl:value-of select="'${catalina.valves.showReport}'"/>
               </xsl:attribute>
               
               <xsl:attribute name="showServerInfo">
                   <xsl:value-of select="'${catalina.valves.showServerInfo}'"/>
               </xsl:attribute>

::: zone-end

后续步骤

请访问面向 Java 开发人员的 Azure 中心查找 Azure 快速入门、教程和 Java 参考文档。