当前位置: 首页 > news >正文

微服务应用性能分析实战05 故障定位:Java VisualVM,第一款多合一的轻量可视化工具

你好,这一讲我将带领你学习 Java VisualVM(All-in-One Java Troubleshooting Tool),VisualVM 是第一款集成了Java 命令行工具支持实时在线问题分析的轻量级可视化工具,作为 Oracle Java 6 的一部分对外发布。

在上个年代,VisualVM 因为使用 JMX 规范,所以接入非常简单;而且 VisualVM 是多合一的生态架构,有很多第三方提供的扩展功能,具备强大的插件体系。所以在发布早期,就深受开发人员和企业的关注。

但遗憾的是,尽管 VisualVM 是官方制作且如此经典,可是在定位线上问题和场景剖析时,很多一线开发人员还是没有使用起来这个工具。至于背后的原因、落地、学习路径,今天我就与你系统性地学习一下。

通过落地方案,熟悉 VisualVM 在落地过程中需要规避的风险;通过学习路径,掌握如何学习 VisualVM。争取在定位问题时,提高 VisualVM 的使用率和定位问题的效率。

落地方案

VisualVM 的部署非常简单,在应用服务的启动命令中,增加相应的 JMX 管理功能参数,然后在本地使用 VisualVM 客户端连接 JMX 端口即可。

由于 VisualVM 接入简单且功能非常强大,所以一线开发人员在不正确使用 VisualVM 的情况下,很容易会造成线上故障。

比如:在没有摘除流量的情况下,点击监视选项卡页面中的“堆 Dump”按钮,进行制作 JVM 内存快照时,会产生“Stop The World”现象,造成服务在短时间内不可用的问题。

这些不正当使用操作造成的不必要线上故障,我们可以通过以下方案去减少甚至规避。

1.操作权限

VisualVM 不支持多用户-角色模式,所以我们需要尽可能缩小使用 VisualVM 操作应用服务的人员范围。为了实现这个目的,我使用开启 JMX 的认证,并结合产品树系统(负责管理应用服务归属于哪个团队)实现权限的下发。

这样实现的好处是:动态管理产品树上每个应用服务节点上的归属成员,就可以实现 VisualVM 工具权限的统一管理。使用产品树对所有 APM 工具的使用权限进行收口,在团队愈发壮大时,收益也会越来越大。

2.安全限制

操作权限中,我们提到了使用 VisualVM 需要开启 JMX(Java Management Extensions),那 JMX 是什么呢?JMX 是一个规范,它实现了 Java 远程监控管理的接口。

所以应用服务增加了相应的 JMX 管理功能参数后,不仅 VisualVM 可以通过 JMX 来监控管理这个应用服务,还有很多的 APM 工具,以及其他黑客入侵工具可以通过 JMX 来监控管理这个应用服务。

如果你感兴趣可以通过搜索【基于JMX协议攻击】来进行安全知识的学习。

所以上文中开启 JMX 认证只是一方面,在网络安全我们也需要联合网络工程师,拒绝外部访问应用服务的 JMX 端口。

对于一线开发人员,我们对 VisualVM 落地方案了解即可。因为整个落地方案需要我们懂得的知识非常少,也非常简单。在需要使用 VisualVM 时,我们只需要找到“产品树”系统,获取相应的权限,然后就可以对线上进程进行剖析了。

所以一线开发人员,需要学习的更多是 VisualVM 工具赋予我们的能力,并能用这些能力去快速解决问题。

为什么 VisualVM 让人感到鸡肋?

而现实情况是越来越多同学已经慢慢忘却了 VisualVM 这一工具。通过我的实地考察以及问卷调查发现,当线上问题(排除可以通过日志解决的问题)出现,需要使用 APM 工具定位问题时,VisualVM 的优先级非常低。

即使用了,他们基本停留在使用原始的 VisualVM,即只会使用原始的四个 VisualVM 选项卡:概览、监视、线程、采样。而这四个选项卡提供的能力很有限,所以其定位准确率也不会很高,且其他 APM 工具也基本都具备这四个选项卡的能力。

所以久而久之,一线的开发人员定位问题会优先使用其他 APM 工具,最后连 VisualVM 原始的四个选项卡的能力也逐渐忘却了(稍后我会带你回顾四个选项卡)。不能掌握工具,便会导致使用工具时愈发不顺手。

诚然 VisualVM 有一定的自身原因,比如:文档全部是英文,大部分实践经验没有很好地渗透到国内。加之国内 APM 工具近些年的开源盛世,VisualVM 在国内的一线开发人员中就更加无人问津了。

对于一个 Java 官方制作且每个企业的每个应用服务都有的 APM 工具,难道 VisualVM 是个鸡肋?答案肯定是否定的。正如一开始所说,VisualVM 的插件体系非常强大,非常值得你学习,这也是 VisualVM 是鸡腿不是鸡肋的原因。

关于 VisualVM 插件体系,我稍后会讲解。

VisualVM 的学习路径

想让 VisualVM 发挥出其真正价值,在一线程序员内心扎根并提升**定位率,**就需要对 VisualVM 的能力持续宣讲,让使用 VisualVM 定位问题的经典场景持续渗透。所以接下来我就会带你从官方的宣传语中,通过 All-in-One(多合一)这个关键词,与你重温经典的 VisualVM。

1.VisualVM 四个选项卡都有哪些能力?

我们先回顾下,原生 VisualVM 四个选项卡都有哪些能力。

  • 概述:此界面展示进程相关的概览信息、JVM 参数和系统属性。因为企业中开发人员是无法直观查看线上配置,所以概述选项卡很好地展示进程使用的线上环境信息,可以让我们快速确定是否是环境问题造成的线上问题。

  • 监视:此界面展示实时的 CPU 使用情况、JVM 堆信息,以及 Java 8 的元空间信息、类加载情况、进程中的线程情况。此页面的监视数据不支持追溯历史,所以追溯历史可以使用 CAT 等 APM 工具解决。监视界面的执行 GC、堆 Dump 可以以最快速度进行现场保留。

  • 线程:此页界面展示实时运行的各个线程情况,主要包括线程在一段时间内的运行状况,通过不同颜色的标识线程分别处于的 5 种常见状态:运行、休眠、等待、驻留、监视;右上角“线程 Dump”按钮,可以对线程进行快照操作。

  • 抽样器:此界面对进程使用的 CPU 和内存进行采样,进行性能分析。CPU 抽样,通过方法的视角,查看方法占用 CPU 的情况;内存抽样,通过类名归类和线程使用内存的视角,进行内存分配的调优。

原始的四个选项卡,可以说是将 Java 命令集成为可视化的工具。这只是 VisualVM 多合一生态的冰山一角,在揭开真正的庐山面目前,我先由浅入深地问你三个问题,来测试你掌握 VisualVM 的能力。

  • 你的 VisualVM 是不是只有四个选项卡?

  • 你有系统地学习过 VisualVM 的插件体系吗?

  • 你用 VisualVM 的插件都解决了什么问题呢?

我的调研结果是:很多一线开发人员可以回答第一个问题,但能回答上来用插件解决哪些经典场景的则凤毛麟角。

我认为插件是 VisualVM 的精华,是多合一(All-in-One)的具体实践,插件化带来的好处是更加轻量级的内核,更加多样化的生态。

经过前几课时的学习,你会发现所有 APM 工具都会选择插件化的实现方案,这种实现都借鉴于 VisualVM。所以可以说 VisualVM 是插件化的先驱者,插件化也是至今 VisualVM 还依然有很多受众的重要原因之一。

既然插件这么重要,那接下来我就带你系统地学习 VisualVM 的插件体系。

2.VisualVM 的插件体系

因为国内大厂基本使用的 Java 版本就是两个版本,Java 8 和 Java 11(Java 8 存量远大于 Java 11)。

  • 对于使用 Java 8 的用户,VisualVM 已经在 JDK 的 bin 目录中了。但当你打开插件仓库,会发现没有可以安装的插件,是因为插件的地址已失效,需要我们手动更新官方的插件中心地址。

  • 对于使用 Java 11 的用户,VisualVM 在 JDK9 后,已不再为 Oracle JDK 的一部分,我们需要去VisualVM官网进行下载。

经过一些小曲折,总算是安装好了。目前 VisualVM 历经了十几年的发展,总共有 20 个多插件,根据插件类型可以分为以下 8 种。

  • Profiling(性能剖析):Startup Profiler、BTrace Workbench

  • Sources(代码资源):VisualVM-GoToSource

  • Tools(工具):Threads Inspector、VisualVM-JConsole、VisualVM-BufferMonitor、VisualVM-TDA-Module、KillApplication、VisualVM-Coherence、Visual GC、VisualVM-MBeans

  • Platform(监控):VisualVM-Extensions

  • Security(安全):VisualVM-Security

  • Tracer(追踪):Tracer-Monitor Probes、Tracer-Collections Probes、Tracer-JavaFX Probes、Tracer-IO Probes、Tracer-Swing Probes、Tracer-Jvmstat Probes、Tracer-JVM Probes

  • UI(页面增强):OQL Syntax Support

  • Libraries(类库):GraalJS

看到插件的名字,凭借大家的专业度,我想你肯定能“顾名思义”。比如:Startup Profiler插件是在应用程序的启动阶段进行剖析的工具;GoToSource 插件是支持源代码导航和展示。

那每个插件我就不过多解释了,大家在实际工作过程中,根据实际场景,通过插件类型和说明,不停地实战总结经验即可。不过需要注意的是,如果你使用的是 2.0 以上版本的 VisualVM,在部分场景下第三方插件(上文中已加粗)可能有兼容问题。

VisualVM 的每个插件都非常经典,掌握了每个工具就像掌握了十八般兵器,你便可以“纵横江湖”(处理线上所有的问题)了。

3.实战案例:Threads Inspector 定位线上死循环线程

这里我以 Threads Inspector 定位线上死循环(无法退出)的线程为例,与你分享 Threads Inspector 插件如何通过可视化线程堆栈的实现,快速解决死循环问题。

场景是这样的:一套进程混补老服务需要扩容新节点,但是扩容的新节点从 CAT 监控上看,即使凌晨在没有任何请求的时间,总有一些 Http Server 线程无法释放。

这时一线开发人员想用 Arthas 来进行线程 Dump 分析,但发现新节点 Arthas 还没有安装完毕。由于是凌晨,发现问题后流量也全部切至老节点。我建议已开发人员先不要打扰 SRE 同学,先尝试使用 VisualVM 安装 Threads Inspector 插件来定位死循环线程。

Threads Inspector 是工具类插件,VisualVM 在安装此插件后,“线程”选项卡的底部就会增加一个新部分,可以实时分析一个或多个线程的堆栈轨迹。

  • 我们一起先通过“线程”选项卡,在带有 Http Server 前缀的线程中找到那些一直处于运行状态且无法退出的流量线程。

  • 然后抽样选取少量线程,在底部 Threads Inspector 插件视图中进行堆栈轨迹的跟踪,发现有少量用户查看的票务请求打到了新节点。

  • 获取票务信息需要通过 SDK 与第三方建立 Websocket 连接。如果建立连接失败,不仅异常日志没有打印,而且还会一直处于无限重试建立连接的状态,直到建立连接成功。

  • 再次通过 Threads Inspector 插件提供的运行堆栈轨迹,我们很轻松地找到了相应的代码块。

  • 最后结合 SDK 文档,我们查明新扩容的节点是由于没有对第三方 IP 增加白名单导致的。

所以我们在联系 SRE 时,直接将结果同步,在“加白”处理后,再观察类似请求线程,发现很快就完成了与第三方建立连接,也解决了这一线上问题。

可以看出 VisualVM 的接入成本远小于其他 APM 工具。在特定的场景下,相较于 Arthas 需要开发人员主动输入命令的方式,VisualVM 只需要“点点点”,即可引领一线开发人员处理线上问题。

小结与思考

今天的课程,我先带你学习了 VisualVM 的落地方案。虽然 VisualVM 使用 JMX 规范,接入非常简单,但与其他 APM 工具一样,控制安全风险非常必要。

接下来,带你系统地梳理了 VisualVM 的学习路径。VisualVM 的强大在于插件化生态,所以你的学习重点也应该是 VisualVM 的插件系统。

受限于中文学习资料的缺乏,我建议你先阅读官方英文文献,初步了解插件。之后在问题出现时,可以像刚刚讲解的 Threads Inspector 实践一样,根据问题的类型选择适合的插件去针对性实践。在提升自身实践经验同时,多加总结思考,做到循序渐进地掌握每一个插件。

你负责的应用服务应该都开放了 JMX 端口,所以你便可以开始尝试使用 VisualVM 进行线上问题定位。那么请你回顾一下过往的线上问题,哪些场景可以使用 VisualVM 可以进行线上问题的快速定位呢?请在留言区写下你的思考,欢迎与我讨论。


精选评论

相关文章:

  • 【优化调度】基于粒子群算法解决经济调度附Matlab代码
  • 第七章、优化算法
  • 关于HashMap中重写equals与hashcode的一下问题
  • 互亿无线语音通知平台常用使用场景及接入指南
  • 01 LaTeX命令环境和源代码结构
  • 浏览一个网站时的整个过程
  • 一条 sql 了解 MYSQL 的架构设计
  • 秋招还没offer,正常吗?
  • 什么是悬空 Docker 镜像?
  • 深度学习05——线性回归模型
  • 前端element-ui组件库el-card卡片【hover效果与点击事件(点击无效用@click.native=““)解决】
  • 基于JSP+java的酒店预订系统
  • 塑料检测项目和标准
  • SSM+网上书城系统 毕业设计-附源码180919
  • 6课题研究心得4
  • 【mysql】环境安装、服务启动、密码设置
  • CentOS6 编译安装 redis-3.2.3
  • Docker容器管理
  • express.js的介绍及使用
  • Java|序列化异常StreamCorruptedException的解决方法
  • JavaScript中的对象个人分享
  • mysql 数据库四种事务隔离级别
  • mysql外键的使用
  • nginx 配置多 域名 + 多 https
  • SegmentFault 2015 Top Rank
  • 阿里研究院入选中国企业智库系统影响力榜
  • 复习Javascript专题(四):js中的深浅拷贝
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 开源SQL-on-Hadoop系统一览
  • 理清楚Vue的结构
  • 如何编写一个可升级的智能合约
  • 如何设计一个微型分布式架构?
  • 什么是Javascript函数节流?
  • 想写好前端,先练好内功
  • 蚂蚁金服CTO程立:真正的技术革命才刚刚开始
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • #免费 苹果M系芯片Macbook电脑MacOS使用Bash脚本写入(读写)NTFS硬盘教程
  • #我与Java虚拟机的故事#连载03:面试过的百度,滴滴,快手都问了这些问题
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (9)目标检测_SSD的原理
  • (编译到47%失败)to be deleted
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (二)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)php投票系统 毕业设计 121500
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (一)eclipse Dynamic web project 工程目录以及文件路径问题
  • (一)Linux+Windows下安装ffmpeg
  • ../depcomp: line 571: exec: g++: not found
  • .NET Core Web APi类库如何内嵌运行?
  • .NET Standard 的管理策略
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道
  • [<死锁专题>]
  • [1159]adb判断手机屏幕状态并点亮屏幕