专家分享选择开源和自研道路上的考量以及具体的业务案例,点击查看 了解详情
写点什么

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

  • 2020 年 10 月 24 日
  • 本文字数:5927 字

    阅读完需:约 19 分钟

通过 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-applicationcd 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-WithIssuesaws 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 时所讨论的,这些环境变量特定于运行演示应用,并非必须的设置

  • 根据如下代码执行命令(注意这里的环境变量已设置为无问题场景 DemoApplication-WithoutIssues ),同时启动参数为 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 喜欢为家人及好友烹饪意大利北部的特色美食。


本文转载自亚马逊 AWS 官方博客。


原文链接


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


2020 年 10 月 24 日 10:001559

评论

发布
暂无评论
发现更多内容

Arthas-技术专题-使用指南

浩宇天尚

Arthas 5月日更

声网、新东方、伴鱼英语的音视频技术解读

Jessie

音视频 视频消音

Golang 工作区和 GOPATH

escray

学习 极客时间 Go 语言 5月日更

精选面试题教你应对高级iOS开发面试官(提供底层进阶规划蓝图)

程序员 移动开发 ios开发

一文带你读懂PyQt:用Python做出与C++一样的GUI界面应用程序

老猿Python

ThreadLocal不好用?那是你没用对!

王磊

Java 后端 多线程 ThreadLocal 5月日更

深度剖析 | 关于数据锁定和读取一致性问题

VoltDB

数据库 数据分析 5G

在云计算时代,为什么Linux服务器市场占有率如此之高?

守护石

Linux

MongoDB如何才能优雅且合理地设计?

守护石

mongodb

「学习笔记」《02 | 第一个程序:教你输出彩色的文字》之二

Nydia

学习

作为最好用的可观测平台,如何监控 Grafana

耳东@Erdong

Grafana Prometheus 5月日更

前端开发:Async/Await的使用

三掌柜

5月日更

【LeetCode】停在原地的方案数Java题解

HQ数字卡

算法 LeetCode 5月日更

cri-o 技术探秘2

xumc

无常中的僵硬与柔软

zhoo299

随笔杂谈 教育 生命 5月日更

最近又有出什么新电影,要不要停泊片刻,与好友相约一起来去看呢?

叶小鍵

如何让消息队列达到最大吞吐量?

万俊峰Kevin

微服务 消息队列 Queue Go 语言

预告 · 5月26日IGS大会腾讯云游戏&新文娱分论坛遇见TcaplusDB

tcaplus

数据库 游戏

不忘过去,不畏将来

小天同学

5月日更 汶川地震 不忘过去

VMWare中Ubuntu网络配置

进击的梦清

Linux 运维 vmware 网络配置

给Java小白,整理一套能上手的简单编程算法题!!!

小傅哥

Java 程序员 数据结构 算法 小傅哥

零基础学习 NLP-DAY3

Qien Z.

动态规划 nlp 5月日更

kotlin基础

ES_her0

5月日更

Dubbo 本地调用

青年IT男

dubbo

如何利用k8s拉取私有仓库镜像

Xiao8

k8s 5月日更

华为云官网负责人明哥:我们是如何做到门面不倒,8个月挑战业界翘楚?

华为云开发者联盟

JavaScript node.js Serverless 云原生 大前端

追寻软件定义的梦想汽车

车骑

自动驾驶 智能汽车 软件定义汽车 汽车制造

xSocket框架接入需实现的接口

六维

xSocket 5月日更

Python自动打印文件

IT蜗壳-Tango

IT蜗壳教学 5月日更

找Matlab代码,看这一篇就够了

攻城先森

matlab 工具分享 5月日更

怎样做好服务提供方

程序员架构进阶

架构设计原则 服务化 28天写作 5月日更

面向体验的视频云-火山引擎增长沙龙

面向体验的视频云-火山引擎增长沙龙

通过 Amazon CodeGuru Profiler 简化应用程序的性能优化_测试_亚马逊云科技 (Amazon Web Services)_InfoQ精选文章