11.【Java】为在Azure容器应用中运行的Java应用捕获JVM堆转储
推荐超级课程:
@TOC
概述
捕获JVM堆转储是在Java应用程序中调试内存问题最常用的调试技术之一。在云服务中这可能不那么直接,但在Azure容器应用中,您可以通过调试控制台轻松地进行JVM堆转储。
连接到正在运行的Azure容器应用实例的调试控制台
使用Azure CLI和最新安装的Azure容器应用扩展,运行以下命令以连接到调试控制台。
az containerapp debug \
--resource-group <资源组> \
--name <容器应用名称>
连接到调试控制台后,运行以下命令安装JDK以使用JDK内置工具捕获JVM堆转储:
root [ / ]# setup-jdk
然后,使用向上箭头(↑)和向下箭头(↓)选择要安装的JDK版本。我们检测您的应用程序运行时环境,并为您推荐一个JDK版本。例如:
选择要安装的JDK:
[temurin-8-jdk]: Eclipse Temurin JDK 8
[msopenjdk-11]: Microsoft Build OpenJDK 11
[msopenjdk-17]: Microsoft Build OpenJDK 17
>[msopenjdk-21]: Microsoft Build OpenJDK 21(推荐)
[可选]切换用户上下文
在调试控制台会话中,Java应用程序通常是进程1,其文件存储在**/proc/1中,如果没有对镜像进行自定义的话。(否则,您可能需要获取Java应用程序的正确进程ID)。但是,如果要分析的Java应用程序是由非root用户(这也是在镜像中定义的)运行的,由于调试控制台默认以root启动,您无法直接访问/proc/1**中的任何内容。
root [ / ]# ls /proc/1/root ls: 无法访问'/proc/1/root':权限拒绝
为了解决这个问题,使用以下命令切换用户上下文。
root [ / ]# switch-user
切换到用户app...
app [ / ]$
然后,用户上下文将更改为运行Java应用程序的用户,您可以使用它来捕获JVM堆转储。
捕获JVM堆转储
jmap和jcmd都是JDK中的内置工具,可以帮助您捕获JVM堆转储。它们都位于JDK主目录下的bin文件夹中。
要使用jmap捕获JVM堆转储,请在调试控制台中运行以下命令:
app [ / ]$ jmap -dump:live,format=b,file=/tmp/dump.hprof 1
要使用jcmd捕获JVM堆转储,请在调试控制台中运行以下命令:
app [ / ]$ jcmd 1 GC.heap_dump /tmp/dump.hprof
无论哪种方式,您都可以在**/proc/1/tmp/dump.hprof**访问转储文件。
将转储文件下载到本地
从云服务传输文件到本地有时可能很棘手。但在Azure容器应用的调试控制台中,您可以通过Azure云存储 的帮助下载转储文件。有几种选择:
- 将Azure存储文件共享 作为卷挂载到Azure容器应用。
- 向Azure Blob存储 发送HTTP请求,以从调试控制台会话上传文件。
- 使用AzCopy 来节省构建上传HTTP请求的工作量,并使用Azure身份验证。
在本文中,我们关注第3种方法。
步骤1:在调试控制台会话中安装AzCopy。请注意,这一步需要以root用户身份完成。如果当前用户不是root,请输入"exit"回到root上下文。
root [ / ]# tdnf install -y azcopy
步骤2:使用Azure Entra ID进行身份验证。
root [ / ]# azcopy login
步骤3:将转储文件复制到Azure Blob存储。
root [ / ]# azcopy copy "/proc/1/tmp/dump.hprof" "https://<存储账户名称>.blob.core.windows.net/<Blob存储名称>/dump.hprof"
步骤4:使用Azure门户或本地机器上的Azure CLI从Azure Blob存储下载转储文件。