线上事故处理总结
来源:互联网 发布:nb仿真实验室软件 编辑:程序博客网 时间:2024/06/10 08:32
1、线上有些机器cpu idle(cpu空闲时间)和load avg(系统负载)报警;这个跟业务逻辑还不太一样,如果业务逻辑错误还可以看 error日志,看看zabbix上监控的上游服务时间相应等等
到底是什么原因引起的呢?我们必须知道系统现在到底在干啥?思路无非就是通过JVM的工具:
1、jstack看进程中的各个线程都在干啥?
2、jmap 看看内存是不是满了?young区&old区等。。。
3、jstat 看看gc次数和时间是否频繁?
但是问题来了,jstack可以dump所有线程的运作情况,但是比较繁忙的是哪些?用用户线程、垃圾回收线程等,很难清晰看出来;jmap 可以看出各区的内存状况,以及存活对象统计等,但是为什么这个对象没有被回收,也很难直观看出来;jstat可以看出gc时间和次数,这只是结果的表现,根本原因还是没找到,特别是处理线上问题,有时候不冷静情况下。
问题采取的手段还是还是有的:
1、查看进程id,如ps aux |grep java
2、查看进程中各线程占用cpu状态, 选出最繁忙的线程程id,top -Hp pid
3、把进程转成16进制,printf “ %x\n” {线程id}
4、下一步终于轮到jstack上场了,它用来输出进程{线程id}的堆栈信息,然后根据线程ID的十六进制值grep。
这样就可以定位到我们代码是在哪一块线程消耗最多啦,顺藤摸瓜就能找到问题啦。
就这个线上问题,如下图,我们看到idService.putPoiIdsInfoIntoCache()函数频繁试用,原因是之前留了一历史问题没处理好,就是job模块当产生新的poi或者poi信息变更的时候通过zeromq队列发送poiid给thrift模块,使thrift更新poiId,现在已经不用这样机制了,改成直接超苦了。当job频繁发送消息,时候会对thrift模块产生压力,可能就处理不过来了。(修改逻辑之后,报警解除,后续看看产生的影响)
PS:
上面解决问题的那几个套路,可以在VM上运行一个脚本,就可以知道进程中繁忙的top n 线程在搞些啥,供以后排查问题可以试用:
#!/bin/bash# @Function# Find out the highest cpu consumed threads of java, and print the stack of these threads.## @Usage# $ ./show-busy-java-threads.sh## @author Jerry LeePROG=`basename $0`usage() { cat <<EOFUsage: ${PROG} [OPTION]...Find out the highest cpu consumed threads of java, and print the stack of these threads.Example: ${PROG} -c 10Options: -p, --pid find out the highest cpu consumed threads from the specifed java process, default from all java process. -c, --count set the thread count to show, default is 5 -h, --help display this help and exitEOF exit $1}ARGS=`getopt -n "$PROG" -a -o c:p:h -l count:,pid:,help -- "$@"`[ $? -ne 0 ] && usage 1eval set -- "${ARGS}"while true; do case "$1" in -c|--count) count="$2" shift 2 ;; -p|--pid) pid="$2" shift 2 ;; -h|--help) usage ;; --) shift break ;; esacdonecount=${count:-5}redEcho() { [ -c /dev/stdout ] && { # if stdout is console, turn on color output. echo -ne "\033[1;31m" echo -n "$@" echo -e "\033[0m" } || echo "$@"}## Check the existence of jstack command!if ! which jstack &> /dev/null; then [ -n "$JAVA_HOME" ] && [ -f "$JAVA_HOME/bin/jstack" ] && [ -x "$JAVA_HOME/bin/jstack" ] && { export PATH="$JAVA_HOME/bin:$PATH" } || { redEcho "Error: jstack not found on PATH and JAVA_HOME!" exit 1 }fiuuid=`date +%s`_${RANDOM}_$$cleanupWhenExit() { rm /tmp/${uuid}_* &> /dev/null}trap "cleanupWhenExit" EXITprintStackOfThread() { while read threadLine ; do pid=`echo ${threadLine} | awk '{print $1}'` threadId=`echo ${threadLine} | awk '{print $2}'` threadId0x=`printf %x ${threadId}` user=`echo ${threadLine} | awk '{print $3}'` pcpu=`echo ${threadLine} | awk '{print $5}'` jstackFile=/tmp/${uuid}_${pid} [ ! -f "${jstackFile}" ] && { jstack ${pid} > ${jstackFile} || { redEcho "Fail to jstack java process ${pid}!" rm ${jstackFile} continue } } redEcho "The stack of busy(${pcpu}%) thread(${threadId}/0x${threadId0x}) of java process(${pid}) of user(${user}):" sed "/nid=0x${threadId0x}/,/^$/p" -n ${jstackFile} done}[ -z "${pid}" ] && { ps -Leo pid,lwp,user,comm,pcpu --no-headers | awk '$4=="java"{print $0}' | sort -k5 -r -n | head --lines "${count}" | printStackOfThread} || { ps -Leo pid,lwp,user,comm,pcpu --no-headers | awk -v "pid=${pid}" '$1==pid,$4=="java"{print $0}' | sort -k5 -r -n | head --lines "${count}" | printStackOfThread}
- 线上事故处理总结
- 线上Mysql数据库崩溃事故的原因和处理
- 线上问题处理整理总结
- 关于一次线上事故总结,以及对于mysql索引的总结(序言一)
- 线上事故的善后——事故通告
- 记两次Erlang服务器线上事故
- 风扇常见事故处理
- 如何处理运营事故
- 小车事故处理参考
- 线上MYSQL同步报错故障处理总结
- 一次共享内存引起的线上事故分析
- 一次线上Mysql数据库崩溃事故的记录
- 我的物联网项目(七)前期线上事故
- 道路交通事故处理程序规定
- city-数据库迁移事故总结
- 线上故障处理
- 线上问题处理
- 事故
- nginx 清理日志
- 基于bootstrap的网页开发(导航条和下拉菜单)
- 关于fragment与activity的思考,以及出现的问题
- a[href*=javablackbelt]{color:red};
- [ASM]Linux平台内联汇编实例
- 线上事故处理总结
- Linux 截图
- http协议详讲
- 1159 Common Subsequence
- LIBMAD解码播放器
- 关于NSString的一些用法
- VIM 使用技巧
- HOG特征+SVM训练过程
- JavaEE面试题,