当前位置: 首页 > 科技观察

重启大法好!上网常见问题故障排除手册

时间:2023-03-21 21:30:58 科技观察

本文从实际上网问题和故障的排查入手,分享如何快速定位和修复上网常见问题和故障,总结了很多实用的方法,希望对大家有用。一线常见问题FAQ1:CPU利用率高CPU利用率是衡量系统繁忙程度的重要指标。一般简单的高CPU是没有问题的,说明系统一直在不断的处理我们的任务,但是如果CPU值过高,任务就无法处理,负载就高了。这是非常危险的,需要引起注意。CPU使用率的安全值没有标准值。这取决于你的系统是计算密集型还是IO密集型。一般计算密集型应用的CPU占用率高,负载低,IO密集型应用则相反。问题原因及位置:1.频繁的FullGC/YongGC查看gc日志jstat-gcutilpid查看内存使用情况和gc状态2.代码消耗,比如无限循环,md5等内存状态操作1)arthas(开源:https://github.com/alibaba/arthas)thread-n5查看CPU占用率最高的前5个线程(包括stack,详见第二部分)2)jstacksearchps-ef|grepjava查找Java进程idtop-Hppid查找使用的CPU最高线程printf'0x%x'tid将线程id转换为十六进制jstackpid|greptid查找线程栈ps:输入“1”查看各个CPU的情况,之前有团队遇到过单个CPUboundbymiddleware导致CPU飙升的情况。常见问题2:负载负载高是指单位时间内活跃的进程数,包括运行状态(runnable和running)和不可中断状态(IO,内核态锁)。关键字是运行状态和不可中断状态。运行状态可以关联Java线程的6种状态。如下,线程new后处于NEW状态,执行start进入runnable等待CPU调度。因此,如果CPU很忙,可运行的进程数就会增加。;不可中断状态主要包括网络IO、磁盘IO、内核态锁,如synchronized。问题原因及定位:1、CPU使用率高,处于runnable状态的进程数过多。排错方法见FAQ1。2.iowait,等待IOvmstat查看被阻塞进程的状态。jstack-lpid|grepBLOCKED查看阻塞线程的堆栈。3.等待内核态锁,如synchronizedjstack-lpid|grepBLOCKED查看阻塞线程栈profilerdump线程栈,分析线程锁情况FAQ3:ContinuousFullGC在了解FullGC原因之前,先花点时间回顾一下jvm的内存相关知识:内存模型新对象放在Eden区.当Eden区满时,进行一次MinorGC,将存活的对象放入S0;当下一个Eden区满了,再次进行MinorGC,将存活的对象和S0的对象放入S1中(S0和S1始终有一个为空);依次循环直到S0或S1快满了,将对象放入老区,然后进行FullGC,直到老区满为止。在jdk1.7之前,Java的类信息、常量池、静态变量都存放在Perm永久代中。类的原始数据和静态变量在类加载时放在Perm区,类卸载时清理;在1.8中,MetaSpace替换了Perm区,使用本地内存、常量池和静态变量进入堆区,一定程度上解决了反射、代理等运行时产生或加载大量类导致的FullGC问题,groovy等。收集器的年轻代常用ParNew,复制算法,多线程并行;oldgeneration常用CMS,mark-and-sweep算法(会产生内存碎片),concurrentcollection(用户线程在收集过程中产生对象)。关键公共参数CMSInitiatingOccupancyFraction表示当老年代使用率达到时,将进行FullGC;UseCMSCompactAtFullCollection表示老年代内存在FullGC后进行排序,避免内存碎片。问题原因及定位:1、从S区提升的对象,由于提升失败,无法放入老年代,导致FullGC(如果fgc回收无效,会抛出OOM)。1)survivor区太小,对象过早进入老年代。jstat-gcutilpid1000观察内存运行情况;jinfopid查看SurvivorRatio参数;2)大对象分配内存不足。在日志中搜索关键字“allocatinglarge”;profiler检查大对象在内存配置文件中的分布情况;3)老区对象较多。按实例数量排名前10的类:jmap-histopid|排序-n-r-k2|head-10按实例容量排名前10的类:jmap-histopid|排序-n-r-k3|head-10dumpheap,Profiler分析对象占用情况2concurrentmodefailedCMSGC过程中,业务线程将对象放入老年代(并发收集的特性),内存不足。详细原因:1)fgc的触发比例过大,导致老年代占用过多,并发收集时用户线程不断产生对象,导致FGC的触发比例。jinfo查看CMSInitiatingOccupancyFraction参数,一般70~80就够了2)老年代存在内存碎片。jinfo查看UseCMSCompactAtFullCollection参数,整理一下FullGC后的内存FAQ4:线程池满了Java线程池以有界队列的线程池为例,提交新任务时,如果运行线程数少比corePoolSize,创建一个新线程来处理它。如果正在运行的线程数等于corePoolSize,则将新任务添加到队列中,直到队列满为止。当队列满时,会继续创建新的线程来处理任务,但不会超过maximumPoolSize。当任务队列已满,已经开启了最大线程数,又有新的任务到来时,ThreadPoolExecutor会拒绝服务。问题原因及定位:1下游RT高,超时时间不合理业务监控sunfireeagleeye2数据库sql慢或数据库死锁日志关键字“尝试获取锁时发现死锁”Jstack或zprofiler查看阻塞线程3Java代码死锁jstack–l进程号|grep-i–E'阻塞|deadlock'dumpthread使用zprofiler分析阻塞线程和锁常见问题5:NoSuchMethodException原因及位置:1jar包冲突java加载的顺序完全由操作系统决定。mvndependency:tree分析报错方法所在的jar包版本,留下新的arthas:sc-dClassNameXX:+TraceClassLoading2类似问题ClassNotFoundExceptionNoClassDefFoundErrorClassCastException两个常用工具简介常用命令1tail-ftracefile2grep-i忽略大小写入-v反向搜索-E扩展正则表达式:grep-E'pattern1|pattern2'filename3pgm-b启用并发-p指定并发数-A启用askpass4awk-F指定分隔符:awk-F"|"'{打印$1}'|排序-r|uniq-c5sed时间段匹配:sed'/2020-03-0210:00:00/,/2020-03-0211:00:00/p'filenamearthasAlibaba开源Java诊断工具(开源地址:https://github.com/alibaba/arthas),基于javaAgent方法,使用Instrumentation方法修改字节码,用于Java应用诊断。基本功能介绍dashboard:系统实时数据面板,可以查看thread、memory、gc等信息thread:jvm线程堆栈信息,比如查看最忙的topn个线程可用于在线查看开关的实际值sc:查看jvm加载的类信息,可用于排查jar包冲突sm:查看jvm加载的类的方法信息jad:反编译类jvm加载的信息,排查代码逻辑不执行的原因watch:观察方法执行数据,包括输入输出参数、异常等;watchxxxClassxxxMethod“{params,throwExp}”-e-x2watchxxxClassxxxMethod“{params,returnObj}”“params[0].sellerId.equals('189')”-x2watchxxxClassxxxMethodsendMsg'@com.taobao.eagleeye.EagleEye@getTraceId()'trace:方法内部调用时长,输出各节点耗时,用于性能分析tt:用于记录方法,并做回放三个常见问题恢复1线程池已满。rpc框架线程池满,RT接口受限。应用中线程池满了,重启可以暂时缓解。具体问题取决于问题的原因。2.高CPU高负载。单机更换或重启可暂时缓解。查看recovery具体原因是集群高,流量明显增加。详见扩容回收的具体原因。3下游RT高限流降级4数据库死锁kill进程慢sqlsql限流线上问题排查是一个积累的过程,只有了解问题背后的原理才能更快的定位和恢复,另外还有一些得心应手的工具辅助排查,所以从而降低问题定位的门槛和整个团队的快速恢复。【本文为专栏作者《阿里巴巴官方技术》原创稿件,转载请联系原作者】点此查看作者更多好文