Skip to content

Files

Failed to load latest commit information.

Latest commit

 Cannot retrieve latest commit at this time.

History

History

Tuning

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
title date tags categories
Java问题排查手册
2023-08-25 08:51:12 -0700
Troubleshoot

💠

💠 2024-12-06 19:28:00


Troubleshoot

当遇到需要对某个Java应用性能调优,故障处理时的技能或思路汇总

Troubleshooting: Oracle: Java8 | Oracle: Java11

【JVM进阶之路】十:JVM调优总结 - 三分恶 - 博客园
目前最全的Java服务问题排查套路
完蛋,我被故障包围了采用各种工具分析和排查


不可用故障处理 重要且紧急

基础设施层:寻求方式快速搭建新的一层(例如K8S的命名空间下全部服务重建),立马切换解析或网关流量
JVM层:记录好后续排查分析故障现场的必要信息后(dump,日志,linux系统日志),立马重启,释放本该释放的资源或中断已经异常的流程

排查思路:

  • Delta 正式环境可复现问题,测试或灰度无法出现,且不能轻易重启正式环境,通过对生产的JVM做各类指标的记录,对比某个业务操作前后或故障前后的指标差异分析出问题的触发点
    • 限制:不能做太影响性能的指标记录和分析
  • Debug 在测试或灰度环境上可复现问题,可直接Debug接入调试代码,或本地采用高耗能的方式debug分析抓包,strace,CPU火焰图,等方式
    • 限制:可复现,通常能有这个条件已经能直接通过debug代码就能解决问题了

性能调优

Linux 性能分析
Linux 网络
JVM 分析工具

GC

Java GC

Java中9种常见的CMS GC问题分析与解决

大量类加载器创建导致诡异FullGC 参考: 译:谁是 JDK8 中最快的 GC
《沙盘模拟系列》JVM如何调优
深入浅出GC问题排查 参考: CMS Deprecated. Next Steps?

工具

gceasy.io
GCViewer

实践

从实际案例聊聊Java应用的GC优化观察监控指标调整JVM参数: 年轻代 晋升阈值等
根本原则是每一次GC都回收尽可能多的对象,降低GC次数减少无用的扫描和暂停开销

主要关注指标

garbage-collection-kpi
What are Throughput Performance, Latency Performance, and Memory Footprint in Java Programming?

三者不可兼得,通常兼顾两者舍弃另一方

  • 延迟(Latency): 也可以理解为最大停顿时间,即垃圾收集过程中单次 STW 的最长时间,越短越好,一定程度上可以接受频次的增多,是 GC 技术的主要发展方向。
  • 吞吐量(Throughput): 应用系统的生命周期内,由于 GC 线程会占用 Mutator 当前可用的 CPU 时钟周期,吞吐量即为 Mutator 有效花费的时间占系统总运行时间的百分比
    • 例如应用系统运行了 100 min,GC 累计耗时 1 min,则系统吞吐量为 99%,通常目标是超过95%
    • 吞吐量优先的垃圾收集器会倾向于接受单次耗时较长的停顿,累计停顿耗时短的GC策略。
  • 内存占用(Footprint): 取决于不同的GC算法和内存设置,通常来说 Parallel CMS会消耗更多,Serial会消耗更少

延迟

  • 响应时间目标是平均目标吗?是否以百分位数表示,例如第50、90、95 或 99 个百分位数的响应时间? 常见为使用后者
  • 响应时间目标是否是一个永远不应该被超越的绝对最小值? 是否有可能超过响应时间目标? 如果可以的话,可以添加多少? 又可以超过多长时间呢? 完全取决于业务,不过在产品学上400ms是肉眼感知的最慢阈值
  • 如何评估响应时间? 在哪里进行响应时间测量? APM类系统实现监控和告警

吞吐量

  • Java 编程性能目标是否被视为峰值性能目标? 或者吞吐量目标是应用程序必须始终满足的性能目标吗?主要取决于业务(目前横向扩展成本很低,此项的考虑优先级通常会更低)
  • 应用程序预期处理的最高负载是多少?例如,预计有多少并发或活动用户、并发或活动事务?业务预估,建立在完善的监控和稳定业务基础上
  • 如果应用程序的负载超过预计负载,吞吐量是否会下降到性能目标以下?
    • 如果可以的话,它能低于绩效目标多久?或者,应用程序应在其最大容量或负载增加的情况下继续运行多长时间?极限值的边界问题
  • 应用程序在不同负载级别下是否有可以消耗的最大 CPU 量,或者是否有预期的 CPU 量?如果 CPU 使用有上限,超出该限制还可以使用多少 CPU,允许使用多长时间?
  • 如何评估应用程序的吞吐量? 吞吐量的计算在哪里进行? APM系统

内存占用

  • 应用程序中预期使用的内存量是否仅包含 Java 堆大小?或者这个总和是否也考虑了 JVM 或应用程序消耗的本机 RAM?
    • 使用的 RAM 量如何计算? 该统计信息是否会考虑操作系统报告的 JVM 进程驻留内存大小?Java堆上当前数据的数量是否也包括在内?RAM占用量严格来说包含 堆,堆外,元空间,二进制库
  • 有没有可能永远不会超过预期的内存消耗?如果有的话,可能会超过预期的内存消耗多少? 又可以超过多长时间呢?取决于宿主机,通常不建议超限制运行,不利于容器调度
  • 何时评估内存使用情况? 是否会测量应用程序的空闲时间?当程序运行在稳定状态时? 负载何时达到峰值? APM

Memory

Java OOM 排查手册
JVM工具: JMC


CPU

问题:优化一个业务接口的平均延迟,找出CPU成本高的点

  • Arthas trace 指定的方法
    • 偶现或者高并发时才出现怎么办 考虑使用脚本将捕获的调用信息存入日志,在手动解析产生的大量日志统计分析
  • JMC,JProfiler,Visualvm 等工具捕获CPU火焰图
  • APM类监控系统。例如:CAT等

问题: 偶现单个或一批接口无响应

  • 外部资源紧张(高频GC,网络慢,SQL慢,缓存慢)导致这些接口平均耗时突增
  • 外部资源阻塞了,这些接口内部逻辑在阻塞等待。
  • 考虑Web容器线程池是否满了,无法接收新请求,会抛出异常返回500状态码

问题:多个导出文件并行 单页面刷新时,一堆接口里,随机接口无响应其他接口RT正常

  • 另一个场景查询接口并发压测时,单页面刷新 全部接口RT变慢 复合常见逻辑 全链路资源紧张 数据竞争大
  • 原因:
    • 随机接口慢:因为 拦截器 鉴权逻辑里查询权限那块使用到了并行流,业务不合理设计导致前端在轮询后端,就容易导致并行流任务随机积压,影响到随机的接口
    • 随机接口无响应长达5min(前端超时时间),其他接口正常:FJ的队列积压达到了1000+, 由于默认的并行流采用的默认FJ线程池策略是栈
      • 导致在打开一个系统的页面调用的一堆接口时,一旦有一个接口在栈相对底部时,后续接口一直放在栈顶又被消费,导致这个底部的请求永远无法被消费,这个接口就一直在等待响应了。

线程

  1. Jstack 查看栈
  2. Fork Join 排查手册

ClassLoader

加载错误的类

由于开源项目的 groupId artifactId 可能发生变化asm netty commons-io 等,且类结构和设计也有调整,容易引发隐式的类加载错误

【踩坑】 Maven中依赖的隐式冲突 可能导致的 NoClassDefFoundError NoSuchMethodException 等问题 使用easyexcel时遇到Could not initialize class cglib.beans.BeanMap怎么解决

思路

  • Maven Helper IDE 插件检查依赖冲突
  • lsof -p PID | grep jar 项目启动后查看加载到进程的jar
  • -verbose:class 输出运行期加载的class信息

类加载阻塞业务线程

由于类加载是JVM层面同步执行,如果业务行为中会高频用到类加载器的话会大大降低吞吐量,例如 druid连接池引起的线程blocked