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

阿里员工排查问题工具一览,总有一款适合你!

时间:2023-03-21 23:09:35 科技观察

本文来自阿里巴巴内部技术论坛。原创文章得到了阿里巴巴内部的一致好评。作者已将本文开放云栖社区对外开放。文章内容删掉了一部分,主要是只能在阿里内部使用的工具介绍,以及一些只能通过阿里内网访问的链接。前言在平时的工作中,我经常会遇到很多棘手的问题。在解决问题的同时,一些工具发挥了相当大的作用。我把它们写在这里。一个是作为笔记,以便我以后忘记它们时可以快速阅读它们。二是分享。希望看到这篇文章的同学们能够想出自己觉得对日常生活很有帮助的工具,让大家一起进步。废话不多说,开始吧。最常用的Linux命令tail-ftail-300fshopbase.log#倒数300行进入实时监控文件写入模式grepgrepforestf.txt#文件搜索grepforestf.txtcpf.txt#多文件搜索grep'log'/home/admin-r-n#查找目录catf.txt|grep-ishopbasegrep'shopbase'/home/admin-r-n--include*.{vm,java}#指定文件后缀grep'shopbase'/home/admin-r-n--exclude*.{vm,java}#anti-matchseq10|grep5-A3#uppermatchseq10|grep5-B3#lowermatchseq10|grep5-C3#upperandlowermatch,一般用这个catf.txt|grep-c'SHOPBASE'awk1,基本命令awk'{print$4,$6}'f.txtawk'{printNR,$0}'f.txtcpf.txtawk'{printFNR,$0}'f.txtcpf.txtawk'{printFNR,FILENAME,$0}'f.txtcpf.txtawk'{printFILENAME,"NR="NR,"FNR="FNR,"$"NF"="$NF}'f.txtcpf.txtecho1:2:3:4|awk-F:'{print$1,$2,$3,$4}'2,匹配awk'/ldb/{print}'f.txt#匹配ldbawk'!/ldb/{print}'f.txt#not匹配ldbawk'/ldb/&&/LISTEN/{print}'f.txt#匹配ldb和LISTENawk'$5~/ldb/{print}'f.txt#第五列匹配ldb3,内置变量NR:NR表示从awk开始执行后,根据记录分隔符读取的数据条数,默认记录分隔符为换行符,所以默认为数据条数rowsread,NR可以理解为NumberofRecord的缩写。FNR:当awk处理多个输入文件时,处理完第一个文件后,NR不是从1开始,而是不断累加,所以出现FNR,每当处理一个新文件时,FNR从1开始计数,FNR可以这样理解作为记录的文件编号。NF:NF表示当前记录被划分为多少个字段,NF可以理解为NumberofField。findsudo-uadminfind/home/admin/tmp/usr-name\*.log(多目录查找)find.-iname\*.txt(两种情况匹配)find.-typed(当前目录下所有子目录)find/usr-typel(当前目录下的所有符号链接)find/usr-typel-name"z*"-ls(符号链接的详细信息eg:inode,directory)find/home/admin-size+250000k(超过250000k的文件,当然+改成-更小了)find/home/adminf-perm777-execls-l{}\;(根据权限查询文件)find/home/admin-atime-filesaccessedwithin11daysfind/home/admin-ctime-filesstatehavechangedin11daysfind/home/admin-mtime-filesmodifiedwithin11daysfind11分钟内访问的/home/admin-amin-filesfind/home/admin-cmin-11分钟内状态发生变化的文件find/home/admin-mmin-files11分钟内修改过的文件pgm批量查询满足条件的vm-shopbase日志pgm-A-fvm-shopbase'cat/home/admin/shopbase/logs/shopbase.log.2017-01-17|grep2069861630'tsartsar是我们公司自带的采集工具。将历史收集的数据持久化到磁盘上是非常有用的,这样我们可以快速查询历史系统数据。当然也可以查询实时申请状态。它安装在大多数机器上。tsar###可以查看最后一天的指标tsar--live###可以查看实时指标,默认是五秒刷新tsar--memtsar--loadtsar--cpu###的当然这个也可以配合-d参数配合查询某天单个指标的情况tsar--memtsar--loadtsar--cpu###当然这个也可以配合-d查询某日单个指标情况的参数toptop除了看一些基本信息,剩下的就是配合查询vm的各种问题print$6}'|sort|uniq-c|sort-rn#Check当前连接,注意close_wait高的情况,例如下面排查首当其冲的btrace工具就是btrace。真的是生产环境&发布前排查的大杀器。简介我就不多说了。直接上代码做1.查看谁调用了ArrayList的add方法,只打印当前ArrayList大小大于500的线程的调用栈@OnMethod(clazz="java.util.ArrayList",method="add",location=@Location(value=Kind.CALL,clazz="/.*/",method="/.*/"))publicstaticvoidm(@ProbeClassNameStringprobeClass,@ProbeMethodNameStringprobeMethod,@TargetInstanceObjectinstance,@TargetMethodOrFieldStringmethod){if(getInt(field("java.util.ArrayList","size"),instance)>479){println("checkwhoArrayList.addmethod:"+probeClass+"#"+probeMethod+",method:"+method+",size:"+getInt(field("java.util.ArrayList","size"),instance));jstack();println();println("============================");println();}}2.监听调用当前服务方法时的返回值和请求的参数@OnMethod(clazz="com.taobao.sellerhome.transfer.biz.impl.C2CApplyerServiceImpl",method="nav",location=@Location(value=Kind.RETURN))publicstaticvoidmt(longuserId、intcurrent、intrelation,Stringcheck,StringredirectUrl,@ReturnAnyTyperesult){println("parameter#userId:"+userId+",current:"+current+",relation:"+relation+",check:"+check+",redirectUrl:"+redirectUrl+",result:"+result);}更多内容,感兴趣的可以去https://github.com/btraceio/btrace看到正确的结果,当正则表达式匹配trace类时,必须控制scope,否则很有可能CPU被占满导致应用卡死。由于字节码注入的原理,想要恢复正常需要重启应用。ApplicationGrays说了几个很棒的功能(部分功能与btrace重叠):sc-dfxxx:输出当前类的详细信息,包括源代码位置和类加载器结构trace类方法:我非常喜欢这个功能!我很早以前就在JProfiler中看到过这个功能。打印出当前方法调用的耗时情况,细分到每个方法。javOSize指的是一个功能类:通过修改字节码,改变类的内容,并立即生效。因此,您可以快速在某处创建日志以查看输出。缺点是对代码的侵入性太大。但如果你知道自己在做什么,那确实是一件好事。greys和btrace可以轻松完成其他功能,更不用说了。以前JProfiler很多问题都是通过JProfiler来判断的,现在Grays和btrace基本可以搞定。另外,问题基本出在生产环境(网络隔离),所以基本上用的不多,不过还是要标注一下。请到官网https://www.ej-technologies.com/products/jprofiler/overview.html大杀器eclipseMAT可以作为eclipse插件使用,也可以作为单独的程序打开。详情请上http://www.eclipse.org/mat/java三轴,哦不,我只用一条命令七jps:sudo-uadmin/opt/taobao/java/bin/jps-mlvVjstackcommonusage:sudo-uadmin/opt/taobao/install/ajdk-8_1_1_fp1-b52/bin/jstack2815native+javastack:sudo-uadmin/opt/taobao/install/ajdk-8_1_1_fp1-b52/bin/jstack-m2815jinfo可以看到系统启动参数,如下sudo-uadmin/opt/taobao/install/ajdk-8_1_1_fp1-b52/bin/jinfo-flags2815jmap两个目的1、查看堆状态sudo-uadmin/opt/taobao/install/ajdk-8_1_1_fp1-b52/bin/jmap-heap28152.dumpsudo-uadmin/opt/taobao/install/ajdk-8_1_1_fp1-b52/bin/jmap-dump:live,format=b,file=/tmp/heap2.bin2815或sudo-uadmin/opt/taobao/install/ajdk-8_1_1_fp1-b52/bin/jmap-dump:format=b,file=/tmp/heap3.bin28153。看看谁在占用堆?配合zprofiler和btrace,排错如虎添翼sudo-uadmin/opt/taobao/install/ajdk-8_1_1_fp1-b52/bin/jmap-histo2815|head-10jstatjstat参数很多,但一个就够用sudo-uadmin/opt/taobao/install/ajdk-8_1_1_fp1-b52/bin/jstat-gcutil28151000jdb即使在今天,jdb也经常被使用。jdb可以用来预发布调试,假设你的预发布java_home是/opt/taobao/java/,远程调试端口是8000。然后sudo-uadmin/opt/taobao/java/bin/jdb-attach8000。以上表示jdb启动成功。然后您可以设置断点进行调试。具体参数可以看oracle的官方说明http://docs.oracle.com/javase/7/docs/technotes/tools/windows/jdb.htmlCHLSDBCHLSDB感觉在很多情况下可以看到更有趣的东西,所以我赢了'详细描述它们。查询数据听说jstack、jmap等工具都是基于它的。sudo-uadmin/opt/taobao/java/bin/java-classpath/opt/taobao/java/lib/sa-jdi.jarsun.jvm.hotspot.CLHSDB更多详细信息可以在这篇文章http://rednaxelafx中找到。iteye.com/blog/1847971intellijideaypromoter的插件快捷键一次记不住,几次总能记住?Mavenhelper是分析maven依赖的好帮手。虚拟机选项1。你的类从哪个文件加载?-XX:+TraceClassLoading结果就像[Loadedjava.lang.invoke.MethodHandleImpl$LazyfromD:\programme\jdk\jdk8U74\jre\lib\rt.jar]2,应用程序挂起并输出转储文件-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=/home/admin/logs/java.hprofjarpackageconflict单独写这个作为标题是不是太过分了?每个人都或多或少处理过这样一个恼人的案例。如果我不相信下面这么多解决方案,我无法为您解决?mvndependency:tree>~/dependency.txt显示所有依赖mvndependency:tree-Dverbose-Dincludes=groupId:artifactId只显示指定groupId和artifactId的依赖-XX:+TraceClassLoadingvm添加了启动脚本。加载类的详细信息可以在tomcat启动脚本中看到——添加了verbosevm启动脚本。加载类的详细信息可以在tomcat启动脚本中看到。scgreys的sc命令也可以清楚的看到当前类是从哪里加载的。tomcat-classloader-locate可以通过下面的URL知道当前类是从哪里加载的。//localhost:8006/classloader/locate?class=org.apache.xerces.xs.XSObjec其他dmesg如果你发现你的java进程悄悄消失了,几乎没有留下任何蛛丝马迹,那么dmesg就非常有用,可能有你想要的。sudodmesg|grep-ikill|less找到关键字oom_killer。找到的结果类似如下:[6710782.021013]javainvokedoom-killer:gfp_mask=0xd0,order=0,oom_adj=0,oom_scoe_adj=0[6710782.070639][]?oom_kill_process+0x68/0x140[6710782.257588]Taskin/LXC011175068174killedasaresultoflimitof/LXC011175068174[6710784.698347]Memorycgroupoutofmemory:Killprocess215701(java)score854orsacrificechild[6710784.707978]Killedprocess215701,UID679,(java)total-vm:11017300kB,anon-rss:7152432kB,file-rss:1232kB以上表明,对应的java进程被系统的OOMKiller给Killed,分数是854。解释一下OOMkiller(Out-Of-Memorykiller),这个机制会监控机器的内存资源消耗。在机器的内存耗尽之前,该机制会扫描所有进程(根据一定的规则计算,内存使用,时间等),选择得分最好的进程,然后杀死它以保护机器。dmesg日志时间换算公式:日志实际时间=格林威治1970-01-01+(当前时间秒-系统启动后的秒数+dmesg打印的日志时间)秒数:date-d"1970-01-01UTC`echo"$(date+%s)-$(cat/proc/uptime|cut-f1-d'')+12288812.926194"|bc`seconds"剩下的就是看内存这么大为什么会触发OOM-杀手。新技能getRateLimiter想精细控制QPS?比如这样一个场景,你调用某个接口,对方明明需要你限制你的QPS在400以内,你怎么控制?这个时候RateLimiter就派上用场了。详情可以移步http://ifeve.com/guava-ratelimite