Java 性能瓶颈分析工具 你知道几个?(2)
JFR 记录并保存事件流,JMC 提供不同的视图来分析这些事件,但是 JFR 事件面板(如上图所示)才是分析事件最有效的途径。点击事件,展开堆栈跟踪。 从图中可以看出,在 2 分钟内发生了 4403 次 Hotspot JVM 事件和 161 次 Java Runtime 事件。应用程序有多个线程共消耗 73 毫秒向套接字内写数据(Socket Write);应用程序中多个线程共消耗 120 秒从套接字读取数据(Socket Read)。这看起来并不正常,通过查看这些事件的处理记录可以发现,由多个线程使用阻塞式 I/O 读取请求。这些管理请求的时间间隔通常很长,但这些线程却在 read() 方法内被阻塞,所以导致这些线程读取数据时消耗了过多的时间。 JFR 的事件就如黑匣子一般,通过收集的这些事件的详细信息能够更加深入了解程序的内部运行过程,这是很多其他工具所不具备的。 1.5 实际案例 API Gateway 是一种高并发、高流量的系统,它的主要功能是用于给第三方合作伙伴提供数据与服务的能力。因此,API Gateway 对于处理用户请求的完整链路中每个环节的性能损耗都会非常敏感。 最近,在升级网关的核心功能模块之后与测试同学一起合作对网关的某些 API 接口进行性能压力测试,利用压测机 Jmeter 模拟多用户并发请求。但不管怎么增加并发数,每分钟的请求总量稳定保持在 4 万/min,TPS 也一直在 650 左右波动,而且所有服务器的 CPU、内存、网络、IO 占用率均不高。 针对这种情况,我们首先排除了业务方的性能问题,因此直接对业务方(2 核 8G)发起并发请求,TPS 都可以达到 800 左右的并发数。其次,我们也排除了接入层 SLB、OpenResty 的问题,因为网关未升级核心功能情况下单台网关的 TPS 很容易达到 4000 左右。 因此,根据以上分析基本可以确定性能瓶颈出在网关处理请求的过程中。 在网关的 JVM 启动参数中增加 JFR 启动参数:
使用 JFR 的事件视图点击堆栈跟踪,就可以查看到代码调用链,看到自己的业务代码,从而定位到最耗时的代码位置。 下图很清楚展示了来自客户端每个请求主要的事件都耗费在调用 Redis 读取 API 元信息,每一次读取源信息都需要进行序列化与反序列化,导致平均响应时间增加网关处理请求时间加长,因此 TPS 下降并一直稳定在某个值。解决方案 API 元信息尽可能缓存到本地 JVM 内存,优先从本地内存读取数据减少访问 Redis 频次。 当然系统 TPS 上不去的原因也不能仅仅从单一维度分析,要综合起来多维度进行分析,如网络带宽、连接池、Java 内存管理、HTTP 通信机制、业务逻辑、系统架构(缓存、数据库等)等等。 2. Tprofiler TProfiler 是淘宝开源的一个可以在生产环境长期使用的性能分析工具。它同时支持剖析和采样两种方式,记录方法执行的时间和次数,生成方法热点、对象热点、线程状态分析等数据,为查找系统性能瓶颈提供数据支持。 TProfiler 在 JVM 启动时把时间采集程序注入到字节码中,整个过程无需修改应用源码。运行时会把数据写到日志文件,一般情况下每小时输出的日志小于 50M。目前 TProfiler 已应用于淘宝的核心 Java 前端系统,部署后低峰期对应用响应时间影响 20% 高峰期对吞吐量大约有 30% 的降低。 2.1 配置部署
直接下载完整安装包或者下载源码运行 package.bat 脚本或者执行 mvn assembly:assembly命令生成 tprofiler.jar 即可。
profile.properties 作为 tprofiler.jar 的配置文件,可以根据实际情况进行调整。
(编辑:ASP站长网) |