Java常见线上问题总结 绝⼤多数Java线上问题从表象来看通常可以归纳为4个方面:CPU、内存、磁盘、网络。比如,应用上线 后突然CPU使用率99%、内存泄漏、STW时间过长,这些问题通常可以分为两大类: 系统异常 (CPU占用率过高、磁盘使用率100%、系统可用内存低等) 业务异常 (服务运⾏⼀段时间⾃动退出、服务间调⽤时间过⻓、多线程并发异常、死锁等)
1.如何去定位问题
解决问题的第⼀步是定位问题,排查手段⼀般包括以下⼏项,也可以将此理解为排查顺序:
- 业务⽇志分析排查
- APM分析排查
- 物理环境排查
- 应⽤服务排查
- 云⼚商或运营商问题排查
1.1 业务⽇志分析排查
这个没啥说的,看日志不会吗?
1.2 APM分析排查
APM,全称Application Performance Management,应⽤性能管理 在分布式系统中,需要用到APM进行全链路分析 ⽬前市场上使⽤较多的链路跟踪⼯具有如下⼏个: Apache Skywalking:https://skywalking.apache.org Pinpoint:https://pinpoint.com/product/for-engineers SpringCloud Zipkin:https://docs.spring.io/spring-cloud-sleuth/docs/current-SNAPSHOT/reference/html/#sending-spans-to-zipkin
1.3 物理环境排查
物理环境是指⼯程所依附的物理环境,⽐如服务器、宿主机、容器等,细分为服务器负载、CPU、内存、磁盘、⽹络⼏个⽅⾯。 CPU分析 排查CPU的⽬的主要是查看服务器CPU的使⽤率, 使⽤top命令分析CPU使⽤情况 内存分析 使⽤free -m命令查看内存使⽤情况 磁盘分析 使⽤df -h、iostat、lsof等命令查看磁盘IO情况,找到读写异常的进程 ⽹络分析 使⽤dstat、vmstat等命令查看⽹络流量、TCP连接等情况,分析异常流量
1.4 应⽤服务排查
应⽤排查,排查应⽤本身最有可能引发的问题,针对各种场景进⾏对应分析 CPU分析 使⽤jstack等命令进⾏JVM分析 内存分析 使⽤jmap等命令分析内存使⽤情况
1.5 云⼚商或运营商问题排查
排查到了这⼀步的话,只需关注云⼚商或运营商官⽅公告即可。
2. 使用Arthas诊断工具协助定位问题
Arthas 是Alibaba开源的Java诊断⼯具,深受开发者喜爱。 当你遇到以下类似问题⽽束⼿⽆策时,Arthas 可以帮助你解决: 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception? 我改的代码为什么没有执⾏到?难道是我没 commit?分⽀搞错了? 遇到问题⽆法在线上 debug,难道只能通过加⽇志再重新发布吗? 线上遇到某个⽤户的数据处理有问题,但线上同样⽆法 debug,线下⽆法重现! 是否有⼀个全局视⻆来查看系统的运⾏状况? 有什么办法可以监控到JVM的实时运⾏状态? 怎么快速定位应⽤的热点,⽣成⽕焰图? Arthas⽀持JDK 6 ,⽀持Linux、Mac、Winodws,采⽤命令⾏交互模式,同时提供丰富的 Tab ⾃动补 全功能,进⼀步⽅便进⾏问题的定位和诊断。
3. 使用JVM工具协助定位问题
在 JDK 安装⽬录的 bin ⽬录下默认提供了很多有价值的命令⾏⼯具。 每个⼩⼯具体积基本都⽐较⼩,因为这些⼯具只是 jdklibtools.jar 的简单封装。 其中,定位排查问题时最为常⽤命令包括:jps(进程)、jmap(内存)、jstack(线程)、jinfo(参数)等。 jps:查询当前机器所有Java进程信息 jmap:输出某个 Java 进程内存情况 jstack:打印某个 Java 线程的线程栈信息 jinfo:⽤于查看 jvm 的配置参数
4. GC分析
ava 虚拟机GC⽇志是⽤于定位问题重要的⽇志信息,频繁的GC将导致应⽤吞吐量下降、响应时间增 加,甚⾄导致服务不可⽤。 我们可以在 Java 应⽤的启动参数中增加-XX: PrintGCDetails 可以输出 GC 的详细⽇志,例外还可以增 加其他的辅助参数,如 -Xloggc 制定 GC ⽇志⽂件地址。如果你的应⽤还没有开启该参数,下次重启时请 加⼊该参数。 -XX: PrintGCDetails -XX: PrintGCDateStamps -Xloggc:/apps/logs/gc/gc.log -XX: UseConcMarkSweepGC ⽆论是 minor GC 或者是 Full GC,我们主要关注 GC 回收实时耗时, 如 real=0.02secs,即 stop the world 时间,如果该时间过⻓,则严重影响应⽤性能。
经典案例分析1。OOM如何定位?
1.查看JVM分配的内存是否合理
通过:jmap -heap pid 这个命令查看即可。 如果需要调整内存大小,可以使用如下命令。 设置初始空间1024m -Xms1024m 设置最大空间2048m -Xmx2048m 设置初始元空间20m -XX:MetaspaceSize=20m 设置最大元空间512m -XX:MaxMetaspaceSize=512m
2.找到最占用内存空间的对象进行分析
设置了-XX: HeapDumpOnOutOfMemoryError参数,当发生OOM后就会生成java_pid42868.hprof文件 打开eclipse mat,导入java_pid42868.hprof文件 实际场景内存中的对象非常多,所以我们一般会根据饼图分析哪些对象占用的内存比较可疑,然后再根据此对象的引用情况进一步分析。对象的引入关系 shallow heap:对象自身占用内存大小。 retained heap:自身与所有引用对象占用内存大小。