4.2 基础故障处理工具

Java开发人员肯定都知道JDK的bin目录中有java.exe、javac.exe这两个命令行工具,但并非所有程序员都了解过JDK的bin目录下其他各种小工具的作用。随着JDK版本的更迭,这些小工具的数量和功能也在不知不觉地增加与增强。除了编译和运行Java程序外,打包、部署、签名、调试、监控、运维等各种场景都可能会用到它们,这些工具如图4-1所示。

image-20210917101020292

在本章,笔者将介绍这些工具中的一部分,主要是用于监视虚拟机运行状态和进行故障处理的工具。这些故障处理工具并不单纯是被Oracle公司作为“礼物”附赠给JDK的使用者,根据软件可用性和授权的不同,可以把它们划分成三类:

  • 商业授权工具:主要是JMC(Java Mission Control)及它要使用到的JFR(Java Flight Recorder),JMC这个原本来自于JRockit的运维监控套件从JDK 7 Update 40开始就被集成到OracleJDK 中,JDK 11之前都无须独立下载,但是在商业环境中使用它则是要付费的^1
  • 正式支持工具:这一类工具属于被长期支持的工具,不同平台、不同版本的JDK之间,这类工具可能会略有差异,但是不会出现某一个工具突然消失的情况^2
  • 实验性工具:这一类工具在它们的使用说明中被声明为“没有技术支持,并且是实验性质的”(Unsupported and Experimental)产品,日后可能会转正,也可能会在某个JDK版本中无声无息地消失。但事实上它们通常都非常稳定而且功能强大,也能在处理应用程序性能问题、定位故障时发挥很大的作用。

读者如果比较细心的话,还可能会注意到这些工具程序大多数体积都异常小。假如之前没注意到,现在不妨再看看图4-1中的最后一列“大小”,各个工具的体积基本上都稳定在21KB左右。并非JDK开发团队刻意把它们制作得如此精炼、统一,而是因为这些命令行工具大多仅是一层薄包装而已,真正的功能代码是实现在JDK的工具类库中的,读者把图4-1和图4-2两张图片对比一下就可以看得很清楚[^3]。假如读者使用的是Linux版本的JDK,还可以发现这些工具中不少是由Shell脚本直接写成,可以用文本编辑器打开并编辑修改它们。

image-20210917101204118

图4-2 JDK类库中的工具模块

JDK开发团队选择采用Java语言本身来实现这些故障处理工具是有特别用意的:当应用程序部署到生产环境后,无论是人工物理接触到服务器还是远程Telnet到服务器上都可能会受到限制。借助这些工具类库里面的接口和实现代码,开发者可以选择直接在应用程序中提供功能强大的监控分析功能 [^4]。

本章所讲解的工具大多基于Windows平台下的JDK进行演示,如果读者选用的JDK版本、操作系统不同,那么工具不仅可能数量上有所差别,同一个工具所支持的功能范围和效果都可能会不一样。 本章提及的工具,如无特别说明,是JDK 5中就已经存在的,但为了避免运行环境带来的差异和兼容性问题,建议读者使用更高版本的JDK来验证本章介绍的内容。通常高版本JDK的工具有可能向下兼容运行于低版本JDK的虚拟机上的程序,反之则一般不行。

注意如果读者在工作中需要监控运行于JDK 5的虚拟机之上的程序,在程序启动时请添加参数“-Dcom.sun.management.jmxremote”开启JMX管理功能,否则由于大部分工具都是基于或者要用到JMX(包括下一节的可视化工具),它们都将无法使用,如果被监控程序运行于JDK 6或以上版本的虚拟机之上,那JMX管理默认是开启的,虚拟机启动时无须再添加任何参数。

[^3]: 图4-2中展示的是JDK 9模块化改造之后的类库形式,在JDK 9前,这些代码实现在jdk\lib\tools.jar 中。
[^4]: 有一部分工具的实现并不属于Java SE的标准API,如果引入这些类库,就意味着你的程序只能运行于HotSpot(或一些从Oracle买了JDK的源码许可证的虚拟机)上面,又或者在部署程序时需要一起部署这些工具类库。