亚马逊AWS官方博客

通过 Amazon CodeGuru Profiler 简化应用程序的性能优化

Original URL: https://aws.amazon.com/cn/blogs/machine-learning/simplifying-application-onboarding-with-amazon-codeguru-profiler/

 

Amazon CodeGuru 介绍

Amazon CodeGuru 是基于机器学习技术构建的一款开发人员工具,通过该工具可以对您的代码质量进行分析,发现执行成本最高的代码行。同时您可以将Amazon CodeGuru集成到现有的软件开发工作流程中,实现智能代码审查功,代码性能检测和优化执行成本高的代码行,从而实现降低成本的目的。 Amazon CodeGuru 包含以下两个组件: Amazon CodeGuru Profiler可帮助开发人员找到应用程序中最昂贵的代码行,以及有关如何改进代码以节省成本的特定可视化内容和建议。了解更多 », 这个也是本篇文章介绍的重点。 Amazon CodeGuru Reviewer使用机器学习来识别应用程序开发过程中的严重问题和难以发现的错误,从而提升代码质量。了解更多 »

Amazon CodeGuru Profiler介绍

如果您需要使用Amazon CodeGuru profiler ,当前可以通过java agent或者sdk的方式集成到您现有的代码中。通过集成您可以获取应用程序的实时运行性能数据,然后将收集到的数据通过图形的方式进行展示,同时根据采集的数据然后结合机器学习算法,Amazon CodeGuru Profiler可以帮助您找到执行最昂贵的代码行,并给出提高效率和消除 CPU 瓶颈的方法。 在这篇文章中,我将向您介绍两个增强功能,此次的新特性能够让您已更简单,更快速的方式将CodeGuru Profiler功能与您的应用集成:

  • 基于资源的授权-您可以使用基于资源权限的方式,授权您的代码用于上传性能分析数据,这样您就不用手动配置AWS Identity and Access Manager(IAM)权限到代码中。如果您的 IAM 中已存在程序的运行角色或者用户,只需要在 CodeGuru Profiler 控制台上选择相应的角色或者用户即可。
  • 通过命令行方式启动 Profiler 代理 –现在在您可以直接使用 -javaagent 参数来启动支持JVM的程序或者容器(比如Java,Scala,Tomcat),而不需要修改代码并重新编译代码或者设置依赖的方式来启动 Profiler 代理用于性能数据采集。您只需要下载CodeGuru Profiler对应的jar包 ,然后将 -javaagent 参数添加到命令行并运行(只需要在您原有的java -jar 命令增加-javaagent:codeguru-profiler-java-agent-standalone-1.0.0.jar即可)。整个过程只需几分钟即可完成。

Amazon Code Profiler可以做什么?

CodeGuru Profiler 旨在以最小的 CPU 开销在生产环境中运行,以帮助您提高应用程序的性能并降低基础架构成本。使用 CodeGuru Profiler,您可以获得以下收益:

  • 便于解决应用程序中的延迟和 CPU 利用率问题
  • 识别应用程序性能问题
  • 通过获取运行成本最高的代码行并给出相关优化建议,从而便于降低您应用程序在基础架构上的运行成本

CodeGuru Profiler 可以运行在包括 Amazon 弹性计算云 (Amazon EC2)上的应用程序、运行在 AWS Fargate 和 AWS Lambda 上的无服务器应用程序, Amazon 弹性容器服务 (Amazon ECS) 和 Amazon 弹性 Kubernetes 服务 (Amazon EKS) 上运行的容器化应用程序等,同时Cod Guru Profiler还可以在本地运行。它目前支持所有可运行在 Java 虚拟机 (JVM)中的编程语言所编写的应用程序,比如如 Java、Kotlin 和 Scala。下面的例子我们将以java 语言编写的代码进行演示。

分析组介绍

在 CodeGuru Profiler 中,分析组是可以进行一起分析的一组应用程序单元。通过上一节我们提到的 Profiler 代理将应用程序数据发送到单个分析组,然后对分析组中所有应用程序的数据进行聚合和分析。您可以通过 CodeGuru 控制台上的”分析组”页面对其进行管理,当然也可以通过CLI和API的方式进行管理,您可以查看所有分析组、以及它的状态列表,或者创建或删除分析组。更多详细信息,请参阅 Setting up Amazon CodeGuru Profiler. 分析组支持对部署在多个主机上的单个应用程序进行分析,还可以分析两个相关的不同应用程序。

启用基于资源的授权

通过启用基于资源的授权,可以大大简化您的应用程序启用性能优化功能的步骤,之前必须每个应用程序的角色或者用户都必须通过控制台配置IAM 权限。同时该功能的上线也有助于减少配置错误,并可将应用程序快速载入分析组。 在本节中,我们将向您展示如何在 CodeGuru Profiler 控制台上授予所需的权限。首次载入应用程序时,管理员需要创建 IAM 角色或者用户,该角色或者用户被用于提交分析数据以及配置代理。此次新功能发布后,您只需要在下拉列表中选择您的用户或者角色即可成此设置,无需在 IAM 控制台上设置权限。

创建分析组(使用基于资源的授权方式)

创建启用了基于资源的授权的分析组,请完成以下步骤:

  • 在 CodeGuru Profiler 控制台上,选择”创建分析组”。
  • 设置名称为 test-group.
  • 然后选择创建

现在,我们可以向您展示基于资源的授权增强功能。在通过代理上传性能数据之前,您需要对应用程序执行的角色或者用户已经创建好,比如我当前使用的是我的IAM用户“admin” 在本机执行代码,下面选择的时候就选择admin用户即可。

  • 创建成功后,您可以看到如下界面设置用户/角色具备上传性能数据权限到CloudGuru Profiler的权限
  • 下面选择我当前执行代码的IAM用户 admin

 

  • 选择 保存 ,这样,您已为分析组中的用户和角色设置了数据提交权限。

启动 Profiler 代理(不修改应用程序的方式)

接下来,我们通过一个完整的例子来演示如何在不修改应用程序代码的情况下启动Profiler代理。

先决条件

如果您想完成以下实验,需要先执行以下操作:

  • 拥有一个AWS 账户
  • 一台可上网的笔记本电脑或台式电脑
  • 已安装Corretto 8 或 JDK 8 或更高版本的JDK(如果在EC2上运行,需要安装在EC2上)
  • 已安装 Maven(如果在EC2上运行,需要安装在EC2上)

您不再需要修改应用程序代码或添加依赖项来运行代理。只需要使用 -javaagent 参数启动代理即可,这样您可以分析现有应用程序,而无需重新编译或更改应用程序的代码。不过 -javaagent 方法不支持用于 Lambda 和 Spark 作业,此场景下只能使用之前的方式。 要载入应用程序,请完成以下步骤:

  • 创建分析组,并设置区域的环境变量。
  • 从 CodeGuru Profiler 控制台下载最新的Profiler Java JAR 文件。
  • 通过运行 -javaagent 参数重新启动 JVM

这篇文章有一些额外的步骤在实际中并不是必须的,这里主要是因为该示例通过两个不同的分析组来进行测试,一个是DemoApplication-WithIssues(存在问题的场景) 和 DemoApplicationWithoutIssue(不存在问题的场景),因此需要通过设置如环境变量来区分。

克隆示演示代码

将演示应用程序克隆到本机或者EC2 实例,请输入以下代码:

git clone  https://github.com/aws-samples/aws-codeguru-profiler-demo-application
cd aws-codeguru-profiler-demo-application 

切换当前目录到 aws-codeguru-profiler-demo 应用程序后,可以看到 pom.xml 文件等信息:

创建分析组

在命令行中输入以下命令,该命令用于创建分析组(在执行该命令前,需要您的执行环境已经安装了aws CLI,同时配置了aws configure 这里配置的ak,sk就是上面选择的执行角色或者用户):

aws codeguruprofiler create-profiling-group --profiling-group-name DemoApplication-WithIssues
aws codeguruprofiler create-profiling-group --profiling-group-name DemoApplication-WithoutIssues

上面的命令创建了DemoApplication-WithIssues和DemoApplication-WithoutIssues两个分析组

设置演示应用程序

要完成该项目,您需要创建一个Amazon 简单存储服务 (Amazon S3) 存储桶和一个Amazon 简单队列服务 (Amazon SQS) 队列。创建 S3 存储桶和 SQS 队列并不是必须的,只是因为本演示程序使用了该组件。该示例程序通过读取S3上的图片信息,然后将信息写入到SQS队列,另外一个线程通过消费 SQS 队列中的消息,然后对消息中的图像进行处理,然后再将处理后的图片存储到S3中。 首先我们创建程序需要的S3和SQS资源,请输入以下代码:

aws s3 mb s3://demo-application-test-bucket-YOUR BUCKET NAME aws sqs create-queue –queue-name DemoApplicationQueue

对于本文,请用一组随机的数字或者您的名字简拼替换您的桶名称,这里主要是因为S3的桶名称需要全局唯一。 接下来,我们使用以下命令设置环境变量。这些步骤不是必要的,正如上文所述主要是为了测试不同场景,因此通过环境变量进行设置区分,这里的设置包括桶的名称,SQS的地址等 这些信息可以通过上面命令执行结果的返回中获取,或者通过Console获取,第三个参数是当前使用的CodeGuru所在区域的编码比如弗吉尼亚需要配置为 us-east-1。

export DEMO_APP_BUCKET_NAME="demo-application-test-bucket-10245"
export DEMO_APP_SQS_URL="https://sqs.us-east-1.amazonaws.com/12345678/DemoApplicationQueue"
export AWS_CODEGURU_TARGET_REGION=REPLACE WITH YOUR-AWS-REGION

下载Java agent 的jar文件

首先我们测试有问题的场景,因此设置环境变量为:

export AWS_CODEGURU_PROFILER_GROUP_NAME=DemoApplication-WithIssues

提示: “有问题场景“模拟了日志Logger未复用的问题,java中一般会建议日志打印对象,通过一个类共享的方式进行使用,如定一个static的全局日志类,不用每次打印的时候去初始化一个Logger对象用于日志输出,这样是很消耗资源的方式。同时日志输出操作本身也很耗时,也不建议在生产环境中一直卡其Debug。 然后我们编译并打包测试应用,当前应用使用的是Maven进行项目的管理,因此在/aws-codeguru-profiler-demo-application目录下执行如下命令构建(该目录下包含pom.xml文件,该文件是用于构建和管理java应用):

mvn clean install

如上命令会将当前测试应用构建为jar包并生成在/aws-codeguru-profiler-demo-application/targe 目录下。此过程可能需要 1 分钟左右的时间。 对于本文中的操作,您不需要下载CodeGuru Profiler Java agent JAR文件,因为上面通过 GitHub 下载的Demo应用程序中已包含该文件,不过,当您在实际生产上使用应用程序进行分析时,建议从 CodeGuru Profiler 控制台下载 最新的JAR 文件,下载页面如下图所示:

运行演示应用程序

接下来,通过运行 -javaagent 重新启动 JVM,同时需要确保命令中包含应用程序的启动命令。需要注意的是当您运行此项目时,实际的 CodeGuru Profiler java agent JAR 文件的版本可能已经更新。

java -javaagent:codeguru-profiler-java-agent-standalone-1.0.0.jar \
-jar target/DemoApplication-1.0-jar-with-dependencies.jar with-issues

当您通过您的环境看到如下日志时说明CodeGuru Profiler已经配置成功:

INFO: Profiling scheduled, sampling rate is PT1S

您将命令窗口上看到消息运行几分钟后,此时您可以选择继续运行或者退出。如果选择了退出,同时是使用Ec2的话需要通过 SSH 重新连接到 EC2 实例再次查看运行情况。 您可以通过如下命令可以查看agent是否仍然在运行:

ps -ef |grep javaagent

检查分析组的 CodeGuru 控制台

若要验证应用程序是否正在分析,请返回到 CodeGuru 控制台。此时您应该会看到分析组从”非活动”状态 变为”挂起”状态,然后变为”分析”状态后结束,最终状态显示如下图: 当分析组显示状态为“分析”时,就可以通过可视化的方式查看应用程序的运行时数据了。从CodeGuru 分析代理将数据提交到分许组大约需要 5 分钟,大约 10 分钟后,您可以看到火焰图可视化效果。在 1 小时左右,您就获得第一份性能建议报告(如上图最后一列显示建议5)。 大约10分钟后点击DemoApplication-WithIssues分析组展示类似如下图: 1小时左右可以查看建议报告类似如下图:上图是其中的一条优化建: 发现代码中的debug的日志输出对应用性能明显(占用Runnalbe线程时间的6.67%,同时根据经验应该小于1%),优化建议是按需开启debug日志,这个通过机器学习发现的问题和给出的建议与我们实际的经验来看是吻合的。 如果要再次运行此项目,测试无问题场景,请重复前面的步骤,并进行以下更改:

  • 根据设置设置导出变量。正如我们前面在运行演示应用 WithIssues 时所讨论的,这些环境变量特定于运行演示应用,并非必须的设置
    export DEMO_APP_SQS_URL=https://sqs.YOUR-AWS-REGION.queue.amazonaws.com/YOUR-ACCOUNT-ID/DemoApplicationQueue
    export DEMO_APP_BUCKET_NAME=demo-application-test-bucket-1092734-YOUR-BUCKET-NAME
    export AWS_CODEGURU_TARGET_REGION=YOUR-AWS-REGION
  • 根据如下代码执行命令(注意这里的环境变量已设置为无问题场景 DemoApplication-WithoutIssues ),同时启动参数为 without-issues
    export AWS_CODEGURU_PROFILER_GROUP_NAME=DemoApplication-WithoutIssues
    mvn clean install ## This command will generate the DemoApplication-1.0-jar-with-dependencies.jar
    java -javaagent:codeguru-profiler-java-agent-standalone-1.0.0.jar \
      -jar target/DemoApplication-1.0-jar-with-dependencies.jar without-issues

有关 CodeGuru Profiler 中的可视化功能,详情参阅 “Optimizing application performance with Amazon CodeGuru Profiler“。

清理环境

为避免后续继续产生费用,请删除您为此项目创建的相关资源:

  • 删除 分析组 DemoApplication-WithIssues/ DemoApplication-WithoutIssues
  • 删除 SQS 队列 和 S3 桶
  • 删除 EC2 实例(如果您有创建)

结论

我们很高兴能够帮助您使用 CodeGuru Profiler 已更快、更轻松地方式将性能优化能力集成到您的应用程序中。在这篇文章中,我们回顾并学习了如何使用CodeGuru Profiler 的两个最近的增强功能:基于资源的权限设置 和 使用 -javaagent 开关启动探查器代理,而无需修改应用程序的代码。 CodeGuru Profiler 是 Amazon CodeGuru 的一部分,这是一种基于机器学习的服务,可执行自动代码审查和应用程序性能建议。它使用 AWS API、SDK 和各种库在代码中查找问题,并发现与性能方面最佳实践的偏差,以便识别问题,并提出修复的具体建议。CodeGuru 由 机器学习功能、最佳实践和从数百万代码审查和数千个应用程序中吸取的经验教训提供支持,同时它也在包括开源项目和亚马逊内部都有应用。 我们希望您通过本文可以更简单,更快速的将CodeGuru Profiler 应用到您的项目中。本文的样例代码可以通过GitHub project page进行下载。

 

本篇作者

Charles Gibson

Amazon Web Services专业服务团队企业转型架构师。他帮助客户面向AWS云实现现有业务的迁移与现代化转型。在业余时间,Charles喜欢为家人及好友烹饪意大利北部的特色美食。