如何排查解决线上问题-java版
2016-09-18 16:27
806 查看
摘要: 如何排查线上问题- java版
--
关键需要做好监控和报警,打日志要准确规范。
博客地址
按M按内存排序
按T按cpu时间消耗排序
更多参考
<!-- more -->
进程信息
r: 等待运行的进程数
b: 处于不可以中断的睡眠状态的进程数
内存信息
swpd: 使用的虚拟内存总量
free: 空闲内存总量
buff: 用来当buffer的内存的总量(已经write的IO)
cache: cache的内存,read的IO
swap
swap in
swap out
IO
bi 块设备每秒接收的块的数量
bo 块设备每秒发送的块的数量
系统
cs: context switch 上下文切换次数
us: 用户cpu时间。
sy: 内核系统cpu时间。如果太高表示系统调用时间长
id: 空闲cpu时间
wa: 用来等待io花费的时间
st: time stolen from a virtoal machien.
rxpck: 每秒收到的包的数量
txpck: 传输的包的数量
rxkB: 收到的kB大小
txkB: 传输的kB大小
rxcmp: 压缩的包的收到的数量
txcmp: 压缩的包的传输量
rxmcst: 收到的广播的包的数量
Mem: 是系统角度的内存状态
total 7870M, 使用了7188M, 681M可用,0M共享,273 buffer, 4796 cached.
-/+ buffers/cache: 是算和不算缓存缓冲的情况
2119: 不算时已使用内存
5751: 不算时可用内存
Swap:swap使用情况
http://www.cnblogs.com/coldplayerest/archive/2010/02/20/1669949.html
less /proc/meminfo
netstat -anpt
netstat -ntp | grep 'TIME_WAIT' | awk '{print $5, $6}' | awk -F ':' '{print $1, $2}' | awk '{print $1, $3}' | sort | uniq -c | sort -k 1 -n -r
netstat -nt | grep 11300 | awk '{print $5}' | awk -F ':' '{print $1}' | sort | uniq -c 查看某个端口号的连接的主机数量统计
lsof -i:8080
lsof -p pid
查看磁盘总占用情况
du -h . --max-depth=0
查看当前文件夹下各个文件占用大小,文件夹深度为0
jps -lv
jinfo -flags pid
jstat -gcutil pid 1s
jstat -gccause pid 1s
查看gc.log
jstack -l
查看某个进行内占用cpu最多的进程
top -Hp pid
找到后,转换成16进行
如printf '%x\n' pid
得到2031
再在jstack 结果中查找这个线程号对应的线程是什么
jstack -l 中查看是否有死锁 #TODO
jmap -histo pid
jmap -histo:live pid
jmap -histo:live pid | less
查看对象实例数量占用内存最多的几个类,从中查找可能出现的问题
jmap -heap pid
dump 内存文件
dump下来后可以用MAT来分析内存引用,观察内存占用情况
,那个地方导致了内存泄露等等。
netstat 类 TODO
有root权限时,可以执行tcpdump
查看tcp 端口是8888的来源hostIP是10.0.0.1的请求
更多参考
查看TCP参数
less /etc/sysctl.conf
polysh
调用外部服务、远程方式时,要将参数、结果上打印log出来。日志要注意发生异常时是否能够打印、是否能打出足够信息。
一些关键的步骤,打印参数等
异常处理的地方,打印参数,异常栈
这样就可以在程序抛出异常的时候,通过异常栈以及我们打印的参数快速的判断是哪里出现了问题。
通过异常栈分析那个位置的代码出错了,如果有参数就能分析出为什么出错。通过查找Cause by可以找到最初抛出异常的位置。
通过
防御
在循环处理的地方,如果希望其中一个循环出错不影响其他循环的执行时,要在循环内部catch
防御式拷贝
Defensive copy. 当一个方法返回一个对象时,我们要考虑外部调用方可能会修改这个对象的值,导致其他引用这个对象的地方
观察到状态改变。这种隐含的变化可能带来bug。通过defensive copy,返回一个新的对象,避免了共享对象。但是要注意的是,
copy也有深度copy和浅copy。另一种方式是返回一个不可修改的集合,如
这个时候还是需要在编写代码时就提前注意,有哪些用到了依赖于环境的地方
如
服务依赖,各个环境的服务配置、服务是否存在
端口,是否和已有的程序的端口冲突了
权限,写文件或者日志目录是否有权限
另外还有maven引用jar包冲突的,会出现NoSuchMethodError等错误
这个时候,找到哪个类的版本不一致,在代码中找到对应的依赖的jar包
通过
maven 采用的是按照声明顺序靠前的使用。
当可以进行一定的调试时,只在staging环境或者有一个jsp页面可以调用java代码时,
可以使用Class.forName("xxx").getClassLoader XXX.class.getResource("xxx.yy.ZZZ") 来查看用的是那个地方的class文件
也可以解压jar包,使用javap -v -p -c 查看class文件内容
另外还有一些工具,像BTrace、housemd、greys来帮助我们线上调试
--
关键需要做好监控和报警,打日志要准确规范。
博客地址
性能类
诊断
uptime
查看当前load(cpu负载信息)top
按P 按照cpu排序按M按内存排序
按T按cpu时间消耗排序
更多参考
<!-- more -->
vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 0 0 0 151732 867452 3261568 0 0 0 5 0 0 1 1 98 0 0
进程信息
r: 等待运行的进程数
b: 处于不可以中断的睡眠状态的进程数
内存信息
swpd: 使用的虚拟内存总量
free: 空闲内存总量
buff: 用来当buffer的内存的总量(已经write的IO)
cache: cache的内存,read的IO
swap
swap in
swap out
IO
bi 块设备每秒接收的块的数量
bo 块设备每秒发送的块的数量
系统
cs: context switch 上下文切换次数
us: 用户cpu时间。
sy: 内核系统cpu时间。如果太高表示系统调用时间长
id: 空闲cpu时间
wa: 用来等待io花费的时间
st: time stolen from a virtoal machien.
iostat 1
avg-cpu: %user %nice %system %iowait %steal %idle 1.00 0.00 0.50 0.00 0.00 98.50 Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn vda 0.00 0.00 0.00 0 0 vdb 0.00 0.00 0.00 0 0 vdc 2.00 0.00 16.00 0 16
dstat
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system-- usr sys idl wai hiq siq| read writ| recv send| in out | int csw 1 1 99 0 0 0| 236B 54k| 0 0 | 0 0 | 832 6976 1 0 99 0 0 0| 0 16k|6674B 8590B| 0 0 |1788 3463 1 0 99 0 0 0| 0 16k|6782B 7182B| 0 0 |1824 3443 1 1 98 0 0 0| 0 16k|6882B 8121B| 0 0 |1724 3352
pidstat 1
sar -n DEV 1
统计网络状况16:45:37 IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s 16:45:38 lo 8.00 8.00 0.73 0.73 0.00 0.00 0.00 16:45:38 eth0 1.00 1.00 0.06 0.11 0.00 0.00 0.00
rxpck: 每秒收到的包的数量
txpck: 传输的包的数量
rxkB: 收到的kB大小
txkB: 传输的kB大小
rxcmp: 压缩的包的收到的数量
txcmp: 压缩的包的传输量
rxmcst: 收到的广播的包的数量
free -m
查看状况内存。total used free shared buffers cached Mem: 7870 7188 681 0 273 4796 -/+ buffers/cache: 2119 5751 Swap: 2047 0 2047
Mem: 是系统角度的内存状态
total 7870M, 使用了7188M, 681M可用,0M共享,273 buffer, 4796 cached.
-/+ buffers/cache: 是算和不算缓存缓冲的情况
2119: 不算时已使用内存
5751: 不算时可用内存
Swap:swap使用情况
http://www.cnblogs.com/coldplayerest/archive/2010/02/20/1669949.html
less /proc/meminfo
网络
netstat -nltpnetstat -anpt
netstat -ntp | grep 'TIME_WAIT' | awk '{print $5, $6}' | awk -F ':' '{print $1, $2}' | awk '{print $1, $3}' | sort | uniq -c | sort -k 1 -n -r
netstat -nt | grep 11300 | awk '{print $5}' | awk -F ':' '{print $1}' | sort | uniq -c 查看某个端口号的连接的主机数量统计
lsof -i:8080
lsof -p pid
磁盘
df -h查看磁盘总占用情况
du -h . --max-depth=0
查看当前文件夹下各个文件占用大小,文件夹深度为0
gc
jps -l94422 9671 sun.tools.jps.Jps 96568 com.intellij.rt.execution.application.AppMain
jps -lv
jinfo -flags pid
jinfo -flags 96568 Attaching to process ID 96568, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.45-b02 Non-default VM flags: -XX:CICompilerCount=4 -XX:InitialHeapSize=268435456 -XX:MaxHeapSize=4294967296 -XX:MaxNewSize=1431306240 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=89128960 -XX:OldSize=179306496 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC Command line: -Drebel.base=/Users/liuzhengyang/.jrebel -Drebel.env.ide.plugin.version=6.5.0 -Drebel.env.ide.version=2016.2.2 -Drebel.env.ide.product=IU -Drebel.env.ide=intellij -Drebel.notification.url=http://localhost:17434 -javaagent:/var/folders/lg/wvtqlfn13lx5kfp0p_pf_hx00000gn/T/jrebel-temp/jrebel.jar -Dmaven.home=/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3 -Dclassworlds.conf=/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3/bin/m2.conf -Didea.launcher.port=7532 -Didea.launcher.bin.path=/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8
jstat -gcutil pid 1s
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 0.00 2.47 80.24 44.07 97.73 94.31 27 1.271 3 0.431 1.702 0.00 2.47 80.24 44.07 97.73 94.31 27 1.271 3 0.431 1.702
jstat -gccause pid 1s
查看gc.log
jstack -l
查看某个进行内占用cpu最多的进程
top -Hp pid
找到后,转换成16进行
如printf '%x\n' pid
printf '%x\n' 8241
得到2031
再在jstack 结果中查找这个线程号对应的线程是什么
jstack -l 中查看是否有死锁 #TODO
jmap -histo pid
jmap -histo:live pid
jmap -histo:live pid | less
查看对象实例数量占用内存最多的几个类,从中查找可能出现的问题
jmap -heap pid
dump 内存文件
jmap -dump:format=b,file=dump.bin,live 8176
dump下来后可以用MAT来分析内存引用,观察内存占用情况
,那个地方导致了内存泄露等等。
tcp
ifconfig查看有哪些网卡和相应的参数,ip,mtu等netstat 类 TODO
有root权限时,可以执行tcpdump
查看tcp 端口是8888的来源hostIP是10.0.0.1的请求
tcpdump -i eth0 tcp port 8888 and src host 10.0.0.1
更多参考
查看TCP参数
less /etc/sysctl.conf
查看多台机器的工具
polyshpolysh
代码类
抛异常
编写代码时要在关键的位置调用外部服务、远程方式时,要将参数、结果上打印log出来。日志要注意发生异常时是否能够打印、是否能打出足够信息。
一些关键的步骤,打印参数等
异常处理的地方,打印参数,异常栈
这样就可以在程序抛出异常的时候,通过异常栈以及我们打印的参数快速的判断是哪里出现了问题。
通过异常栈分析那个位置的代码出错了,如果有参数就能分析出为什么出错。通过查找Cause by可以找到最初抛出异常的位置。
防御式编程
不要对外来的参数做假设,不要假设外部参数不是null或者其中任意一个属性不是null,都要进行判断,可以通过
Preconditions类或
StringUtils.isNotEmpty、
CollectionUtils.isNotEmpty等进行
防御
在循环处理的地方,如果希望其中一个循环出错不影响其他循环的执行时,要在循环内部catch
for (e in loop) { try { do loop } catch (Exception e) { log and exception handle } }
防御式拷贝
Defensive copy. 当一个方法返回一个对象时,我们要考虑外部调用方可能会修改这个对象的值,导致其他引用这个对象的地方
观察到状态改变。这种隐含的变化可能带来bug。通过defensive copy,返回一个新的对象,避免了共享对象。但是要注意的是,
copy也有深度copy和浅copy。另一种方式是返回一个不可修改的集合,如
Collections.unmodifiableCollection等。
启动类
java启动报错
经常出现的情况是,在本地开发没有问题、或是在staging测试也没问题,部署到线上启动就报错了。这个时候还是需要在编写代码时就提前注意,有哪些用到了依赖于环境的地方
如
服务依赖,各个环境的服务配置、服务是否存在
端口,是否和已有的程序的端口冲突了
权限,写文件或者日志目录是否有权限
另外还有maven引用jar包冲突的,会出现NoSuchMethodError等错误
这个时候,找到哪个类的版本不一致,在代码中找到对应的依赖的jar包
通过
mvn dependency:tree | grep进行查看有哪些地方引入了jar包。
maven 采用的是按照声明顺序靠前的使用。
当可以进行一定的调试时,只在staging环境或者有一个jsp页面可以调用java代码时,
可以使用Class.forName("xxx").getClassLoader XXX.class.getResource("xxx.yy.ZZZ") 来查看用的是那个地方的class文件
也可以解压jar包,使用javap -v -p -c 查看class文件内容
另外还有一些工具,像BTrace、housemd、greys来帮助我们线上调试
相关文章推荐
- 如何解决java的web项目error-page不显示的问题
- 如何解决J2ME开发中遇到提示 ALERT: java/lang/ClassFormatError: Bad version information.的问题
- 编译工程时报java:[1,0] illegal character: \65279问题排查与解决过程
- 如何排查解决修改表结构,改表名超时的问题
- 第2章 Java编程基础——FAQ2.10 如何解决double和float精度不准的问题?
- java 网络编程【7】 如何检测和解决端口冲突问题?
- 如何解决java.lang.NoClassDefFoundError问题
- Java初学者如何自学和自己定位解决问题 推荐
- java多线程的等待唤醒机制及如何解决同步过程中的安全问题
- 如何解决使用Java Entity不能插入自增列的问题
- myeclipse如何配置解决JAVA乱码问题
- Java文件操作新问题如何解决记事本的换行
- 编译工程时报java:[1,0] illegal character: \65279问题排查与解决过程
- 如何解决java heap space问题
- 标题: 优化 Java 垃圾收集的性能——如何利用 IBM Java 虚拟机检测和解决垃圾收集问题
- 如何解决在java开发中java代码和jsp页面中出现路径因为项目名称的变化(也就是应用名)的问题?
- 我在CSDN上的第一次(如何解决JAVA应用程序中文乱码问题)
- java中是如何解决编码问题的,比如char类型的对象是如何存储的呢?
- 如何解决java.library.path属性在代码中设置不生效问题
- 线上问题排查(1)——java服务器load飚高排查思路