本文介绍 Azure 应用服务中 Java 应用的最常见部署和运行时配置。 如果是第一次使用 Azure 应用服务,则应首先阅读 Java 快速入门。 可以在 应用服务常见问题解答中找到有关使用应用服务(不特定于 Java 开发)的一般问题的解答。
Azure 应用服务以三种形式在完全托管的服务上运行 Java Web 应用程序:
- Java Standard Edition (SE):可以运行部署为 Java 存档 (JAR) 包的应用,其中包含嵌入式服务器(例如 Spring Boot、Quarkus、Dropwizard 或具有嵌入式 Tomcat 或 Jetty 服务器的应用)。
- Tomcat:内置 Tomcat 服务器可以运行部署为 Web 应用程序存档(WAR)包的应用。
若要显示当前的 Java 版本,请在 bash 中运行以下命令:
az webapp config show --resource-group <resource-group-name> --name <app-name> --query linuxFxVersion
若要显示所有受支持的 Java 版本,请在 bash 中运行以下命令:
az webapp list-runtimes --os linux | grep "JAVA\|TOMCAT\|JBOSSEAP"
有关 Linux 容器中更详细的版本信息,打开与容器的 SSH 会话。 下面是可进行的操作的一些示例。
若要在 SSH 会话中查看 Java 版本:
java -version
若要在 SSH 会话中查看 Tomcat 服务器版本:
sh /usr/local/tomcat/version.sh
或者,如果 Tomcat 服务器位于自定义位置,请通过以下方式查找 version.sh
:
find / -name "version.sh"
有关版本支持的详细信息,请参阅应用服务语言运行时支持策略。
过时的运行时被维护组织弃用,或者被发现存在重大漏洞。 因此,将从门户中的创建和配置页面中删除它们。 当门户中隐藏了过时的运行时后,任何仍使用该运行时的应用程序都会继续运行。
如果要创建具有门户上不再显示的过时运行时版本的应用,请使用 Azure CLI、ARM 模板或 Bicep。 通过这些部署替代方法,可以创建已在门户中移除的但仍受支持的弃用运行时。
如果从应用服务平台完全删除运行时,Azure 订阅所有者会在删除之前收到电子邮件通知。
通过使用 适用于 Azure Web 应用的 Maven 插件,可以使用项目根目录中的一个命令轻松准备项目:
mvn com.microsoft.azure:azure-webapp-maven-plugin:2.13.0:config
此命令通过提示选择现有 Azure Web 应用或创建新应用来添加 azure-webapp-maven-plugin
插件和相关配置。 在配置期间,它会尝试检测应用程序是否应部署到 Java Standard Edition(SE)、Tomcat。 然后可以使用以下命令将 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>westus</region>
<runtime>
<os>Linux</os>
<webContainer>Java SE</webContainer>
<javaVersion>Java 17</javaVersion>
</runtime>
<deployment>
<resources>
<resource>
<type>jar</type>
<directory>${project.basedir}/target</directory>
<includes>
<include>*.jar</include>
</includes>
</resource>
</resources>
</deployment>
</configuration>
</plugin>
通过将适用于 Azure Web 应用的 Gradle 插件添加到
build.gradle
来设置该插件:plugins { id "com.microsoft.azure.azurewebapp" version "1.10.0" }
配置 Web 应用详细信息。 如果相应的 Azure 资源不存在,则会创建它们。 下面是一个示例配置。 有关详细信息,请参阅 本文档。
azurewebapp { subscription = '<your subscription id>' resourceGroup = '<your resource group>' appName = '<your app name>' pricingTier = '<price tier like 'P1v2'>' region = '<region like 'westus'>' runtime { os = 'Linux' webContainer = 'Tomcat 10.0' // or 'Java SE' if you want to run an executable jar javaVersion = 'Java 17' } appSettings { <key> = <value> } auth { type = 'azure_cli' // support azure_cli, oauth2, device_code and service_principal } }
使用一个命令进行部署。
gradle azureWebAppDeploy
Azure 在常用的 Java 集成开发环境中提供无缝的 Java 应用服务开发体验,包括:
- VS Code: 使用 Visual Studio Code 的 Java Web 应用。
- IntelliJ IDEA: 使用 IntelliJ 为 Azure 应用服务创建 Hello World Web 应用。
- Eclipse IDE: 使用 Eclipse 为 Azure 应用服务创建 Hello World Web 应用。
Maven 插件、使用 azure/webapps-deploy@v3
和更新版本的 GitHub Actions 或 az webapp deploy 命令等部署客户端使用 OneDeploy,它通过在后台调用 Kudu 站点的 /api/publish
终结点进行调用。 有关此 API 的详细信息,请参阅 本文档
使用这些部署方法时,提供的 JAR 文件将在部署过程中自动重命名为 app.jar
。 这将放置在 /home/site/wwwwroot
下。 若要将 JAR 文件部署到 Java SE,请参阅 本文档。
注意
如果使用 FTP 或较旧的 ZipDeploy API 等替代方法,则不会调用重命名提供的 JAR 文件的方法。 如果使用门户“配置”部分中的“启动文件”文本框显式调用 JAR 文件,请记下这一点。
可以遵循 本文档将 WAR 文件部署到 Tomcat 应用程序。 使用上述部署方法时,它们将在部署过程中自动将提供的 War 文件重命名为 app.war
。 此文件将放置在/home/site/wwwwroot
下,默认情况下仅支持在wwwroot
部署一个 WAR 文件。 这不会像使用部署 API(如 WarDeploy)时看到的那样放置在 目录下/home/site/wwwroot/webapps
。 为了避免文件结构冲突的任何问题,建议只使用一种或其他部署类型。
不要使用 FTP 部署 WAR 或 JAR。 FTP 工具设计用来上传启动脚本、依赖项或其他运行时文件。 它不是用于部署 Web 应用的最佳选项。
若要重写或重定向 URL,请使用某个可用的 URL 重写程序,例如 UrlRewriteFilter。
Tomcat 还提供重写阀。
可以通过 Azure 门户对每个应用使用性能报告、流量可视化和运行状况检查。
可以访问在容器中生成的控制台日志。
首先,请运行以下命令,以便启用容器日志记录功能:
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 会话,应用应该处于正在运行状态。
将以下 URL 粘贴到浏览器中,将 <app-name>
替换为应用名称:
https://<app-name>.scm.chinacloudsites.cn/webssh/host
如果尚未进行身份验证,则需通过要连接的 Azure 订阅进行身份验证。 完成身份验证以后,可以看到一个浏览器内 shell,可以在其中的容器中运行命令。
注意
在 /home 目录之外进行的任何更改均存储在容器本身中,在应用重启后不保留。
若要从本地计算机打开远程 SSH 会话,请参阅从远程 shell 打开 SSH 会话。
内置的 Java 映像建立在 Alpine Linux 操作系统上。 使用 apk
包管理器安装任何故障排除工具或命令。
Azure 应用服务上的所有 Java 运行时都附带 Java 开发工具包 (JDK) 飞行记录器,用于分析 Java 工作负载。 可以使用它来记录 Java 虚拟机(JVM)、系统和应用程序事件,以及排查应用程序中的问题。
若要了解有关 Java 探查器的详细信息,请访问 Azure Application Insights 文档。
应用服务上的所有 Java 运行时都附带 Java Flight Recorder。 可以使用它记录 JVM、系统和应用程序事件,以及解决 Java 应用程序中的问题。
通过 SSH 连接到应用服务并运行 jcmd
命令以查看运行的所有 Java 进程的列表。 除了 jcmd
本身,你还会看到正在运行的 Java 应用程序以及进程 ID 号 (PID)。
078990bbcd11:/home# jcmd
Picked up JAVA_TOOL_OPTIONS: -Djava.net.preferIPv4Stack=true
147 sun.tools.jcmd.JCmd
116 /home/site/wwwroot/app.jar
执行以下命令以启动 JVM 的 30 秒录制。 它会分析JVM,并在主目录中创建一个名为jfr_example.jfr
的Java飞行记录器(JFR)文件。 将 116
替换为 Java 应用的 PID。
jcmd 116 JFR.start name=MyRecording settings=profile duration=30s filename="/home/jfr_example.jfr"
在 30 秒的间隔内,可以通过运行 jcmd 116 JFR.check
来验证记录是否正在进行。 该命令会显示给定 Java 进程的所有录制。
你可以使用 Java Flight Recorder 在对运行时的性能影响最小的情况下连续分析 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"
使用 FTPS 将 JFR 文件下载到本地计算机。 若要分析 JFR 文件,请下载并安装 Java Mission Control (JMC)。 有关如何使用 Java Mission Control 的说明,请参阅 JMC 文档 和 安装说明。
若要将应用服务配置为将应用程序的标准控制台输出和标准控制台错误流写入本地文件系统或 Azure Blob 存储,请执行以下作。 通过 Azure 门户或 Azure CLI 启用应用程序日志记录。 如果需要更长的保留期,请将应用程序配置为将输出写入 Blob 存储容器。
可以在目录中找到 /home/LogFiles/Application/
Java 和 Tomcat 应用日志。
只能使用 Azure Monitor 配置基于 Linux 的应用的 Azure Blob 存储日志记录。
如果应用程序使用 Logback 或 Log4j 进行跟踪,则可以将这些跟踪转发到 Azure Application Insights 中以供查看。 使用日志记录框架配置说明,参考Application Insights 中的探索 Java 跟踪日志。
注意
由于已知漏洞 CVE-2021-44228
,请务必使用 Log4j 版本 2.16 或更高版本。
Azure 应用服务原生支持通过 Azure 门户和 Azure CLI 进行优化和自定义。 请查看以下文章了解非特定于 Java 的 Web 应用配置:
将应用设置 JAVA_COPY_ALL
设为 true
,以将应用内容从共享文件系统复制到本地辅助角色。 此设置有助于解决文件锁定问题。
若要设置分配的内存或其他 JVM 运行时选项,请使用这些选项创建名为 的JAVA_OPTS
。 应用服务在启动时,会将此设置作为环境变量传递给 Java 运行时。
在 Azure 门户中 Web 应用的“应用程序设置”下,创建名为 且包含其他设置的新应用设置,例如 CATALINA_OPTS
。-Xms512m -Xmx1204m
若要通过 Maven 插件配置应用设置,请在 Azure 插件部分中添加设置/值标记。 以下示例设置特定的最小和最大 Java 堆大小:
<appSettings>
<property>
<name>JAVA_OPTS</name>
<value>-Xms1024m -Xmx1024m</value>
</property>
</appSettings>
注意
在 Windows 应用服务上使用 Tomcat 时,无需创建 web.config 文件。
默认情况下,应用服务会将 JVM 最大堆大小设置为应用服务计划可用的总内存的 70%。 若要禁用默认设置,可以使用应用设置WEBSITE_DISABLE_JAVA_HEAP_CONFIGURATION=“true”。
增强应用程序在平台上的性能可能涉及调整堆大小,以更好地满足特定需求。 优化应用程序堆设置时,请查看应用服务计划详细信息,并考虑多个应用程序和部署槽的要求来查找最佳内存分配。
在 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
的新应用设置。
或者,可以使用应用服务 Maven 插件配置应用设置。 在插件配置中添加设置名称和值标记:
<appSettings>
<property>
<name>JAVA_OPTS</name>
<value>-Dfile.encoding=UTF-8</value>
</property>
</appSettings>
要提高 Tomcat 应用程序的性能,可以先编译 JSP 文件,再部署到应用服务。 可以使用 Apache Sling 提供的 Maven 插件 ,也可以使用 此 Ant 生成文件。
你可能会在容器日志中看到以下消息:
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 响应只是指示该路径不存在,但它让应用服务知道容器处于正常状态并已准备就绪,可以响应请求。
应用服务允许用户选择 JVM 的主版本(例如 Java 8 或 Java 11)和补丁版本(例如 1.8.0_232 或 11.0.5)。 还可以选择在新的次要版本可用时自动更新补丁版本。 在大多数情况下,生产应用应使用 JVM 的固定补丁版本。 这可防止在补丁版本自动更新期间发生意外中断。 所有 Java Web 应用都使用 64 位 JVM,这是不可配置的。
如果选择固定次要版本,则需要定期更新应用上 JVM 的次要版本。 为了确保应用程序在较新的次要版本上运行,请创建一个过渡槽并在暂存站点上递增次要版本。 确认应用程序在新的次要版本上正常运行后,可以交换过渡槽和生产槽。
注意
本部分仅适用于 Linux。
如果 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
。 -
connectionTimeout
设置为WEBSITE_TOMCAT_CONNECTION_TIMEOUT
,默认为240000
。 -
maxThreads
设置为WEBSITE_CATALINA_MAXTHREADS
,默认为200
。 -
maxConnections
设置为WEBSITE_CATALINA_MAXCONNECTIONS
,默认为10000
。
注意
可以使用应用设置来调整connectionTimeout
、maxThreads
和maxConnections
设置。
以下是一些示例 CLI 命令,您可以用于更改 connectionTimeout
、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 "%r" %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
。 -
maxDays
设置为WEBSITE_HTTPLOGGING_RETENTION_DAYS
,默认为7
。 此值与应用程序日志记录平台默认值保持一致。
在 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>
请访问面向 Java 开发人员的 Azure 中心查找 Azure 快速入门、教程和 Java 参考文档。