二、“死”的问题 “死”通常是对进程没了或是进程在但没反应而进行的描述。实际是进程崩溃、假死、产 生僵尸进程这三类情况,其主要原因有以下几点: 1. 最低级的“死”法 (1) 有人偷偷停了TongWeb,别的运维人员不知道。 (2) 把系统慢当成了“死”,TongWeb还在运行,只是慢的跟"死"一样,其实还没死,误 报。 (3) TongWeb不是以nohup ./startserver.sh & 或 startservernohup.sh后台方式启动,造成ssh或 telnet断开后,TongWeb进程停止。 (4) 应用代码里有System.exit(0)代码,危险代码。 这是退进程的,会导致整个TongWeb进 程退出。从TongWeb6日志中可以明显看到如下日志: [20160113 10:50:56] [INFO] [deployment] [Undeploying app:C:\TongWeb6.0\deployment\tran] [20160113 10:50:56] [SEVERE] [webcontainer] [The web application [/tran] is s till processing a request that has yet to finish. This is very likely to create a memory leak. You can control the time allowed for requests to finish by using the unloadDelay attribute of the standard Context implementation.] [20160113 10:50:56] [INFO] [webcontainer] [Stopping ProtocolHandler ["httpnio9060"]] [20160113 10:50:57] [INFO] [webcontainer] [Stopping ProtocolHandler ["httpnio8080"]]
这种问题两种解决办法选其一: A. 找出应用代码用System.exit的地方并删掉; B. startserver启动脚本中加参数: Djava.security.manager禁止执行System.exit代码。
1 个回复
nccloud
一、问题现象描述
常见的反馈问题说法:现在TongWeb上的应用好慢呀,好像死了。
这种问题描述不够清晰,慢有多种慢的现象,“死”也不是一个专业的说法。下面我们将
对这类问题进行分类说明,不同的“死”法,慢法有不同的分析方式。
基本要求:熟悉Linux基本操作、Java编程、JDK基本命令、TongWeb使用,后面我们会
用到。
二、“死”的问题
“死”通常是对进程没了或是进程在但没反应而进行的描述。实际是进程崩溃、假死、产
生僵尸进程这三类情况,其主要原因有以下几点:
1. 最低级的“死”法
(1) 有人偷偷停了TongWeb,别的运维人员不知道。
(2) 把系统慢当成了“死”,TongWeb还在运行,只是慢的跟"死"一样,其实还没死,误
报。
(3) TongWeb不是以nohup ./startserver.sh & 或 startservernohup.sh后台方式启动,造成ssh或
telnet断开后,TongWeb进程停止。
(4) 应用代码里有System.exit(0)代码,危险代码。 这是退进程的,会导致整个TongWeb进
程退出。从TongWeb6日志中可以明显看到如下日志:
[20160113 10:50:56] [INFO] [deployment] [Undeploying app:C:\TongWeb6.0\deployment\tran]
[20160113 10:50:56] [SEVERE] [webcontainer] [The web application [/tran] is s
till processing a request that has yet to finish. This is very likely to create
a memory leak. You can control the time allowed for requests to finish by using
the unloadDelay attribute of the standard Context implementation.]
[20160113 10:50:56] [INFO] [webcontainer] [Stopping ProtocolHandler ["httpnio9060"]]
[20160113 10:50:57] [INFO] [webcontainer] [Stopping ProtocolHandler ["httpnio8080"]]
这种问题两种解决办法选其一:
A. 找出应用代码用System.exit的地方并删掉;
B. startserver启动脚本中加参数: Djava.security.manager禁止执行System.exit代码。
2. 进程崩溃问题
排除以上低级死法,发现TongWeb的Java进程确实崩溃了,通常是由于JVM本身不稳定
造成的,这时在TongWeb的进程起始目录(通常是TongWeb的bin目录)会生成javacore开头
的文本文件,收集这个javacore文件分析。
3. 僵尸进程
进程会变成僵尸进程(defunct),具体说明可百度。解决办法:A.找到其父进程并杀掉。
B. 若杀不掉,只能重启机器。
三、慢的问题
TongWeb上的应用系统慢也分多种情况,需要根据不同的现象进行不同的分析处理,重
点是先要理清慢的现象,做好基本检查。
1. 最低级的慢
(1)TongWeb没有做基本的优化,两大影响性能的参数:
A. 没有改启动脚本JVM内存,默认只有Xmx512m,至少先设2G(Xms2048m
Xmx2048m) ;
B. linux 系统没有改open files值(默认1024),通常改法是修改/etc/security/limits.conf,在文
件中加上两 行:
* soft nofile 65535
* hard nofile 65535
修改完后通过linux系统命令ulimit a查看open files值生效后重启 TongWeb。
(2)数据库没有做基本优化。
(3)应用没有做基本优化,如:数据源连接池配置过小、日志还是DEBUG级别输出。
(4) 网速不够。通过网络测试软件,带宽太小,或是在TongWeb本机上访问(linux也可以
用firefox)看慢不慢? 若本机快,能过其它网段访问慢,则基本可以判断是网络问题。
(5) 基本的性能测试都不做,直接上线,肯定出问题。
2. CPU占用高引起的慢
通过top命令查看到TongWeb的java进程占用CPU很高,这时可以通过阿里的分析脚本
showbusyjavathreads.sh来分析, 该脚本可用于快速排查Java的CPU性能问题(top us值过
高),自动查出运行的Java进程中消耗CPU多的线程,并打印出其线程栈,从而确定导致性能
问题的方法调用。 用法:
showbusyjavathreads.sh p <Java进程Id> c <要显示的线程栈数> a <输出记录到的文件>
要点:查看CPU确实高,脚本可百度查找下载,要在出现CPU高的问题时打该命令,学会看
线程栈。
3. 线程阻塞引起的慢
这种现象通常表现为CPU使用不高,TongWeb控制台访问正常,但应用所有页面访问都
慢,这种情况通常是应用的http线程池出现阻塞导致的。出现这种问题时可使用JDK的jstack
命令打出线程栈来分析。 如:jstack <java进程id> > log.txt, 输出到指定文件。 重点看是
不是BLOCKED线程很多,这些线程是不是lock在同一地址上, 偶尔几个BLOCKED线程对
系统不影响。
要点:会用jstack命令,要在出现慢的问题时打该命令,学会看线程栈。
4. 数据源引起的慢
这种现象通常表现为CPU使用不高,TongWeb控制台访问正常,但应用跟数据库无关的
页面访问正常,跟数据库有关的页面访问慢。这种分种情况:
(1). 数据源连接池占满,TongWeb的server.log中可以看到数据源占满的日志(开源和
TongWeb数据源都会有),通过jstack可以看到线程阻塞在数据源上。可能是连接数过小引起
的,若加大后还出现就有可能是存在连接泄露问题了,找应用代码泄露的地方改掉。 改不
了应用代码就把“泄漏超时”“泄漏回收”同时设置上,这样到达超时时间后,强制回收数据库
连接。开源连接池也有这参数。
当超时后,以WARNING级别将该堆栈信息输出到日志。从日志中可以分析到哪里存在未关
闭的连接。日志示例如下:
(2). 若部分数据库业务慢,TongWeb数据源可记录下执行时间长的SQL,针对SQL进行
优化。
要点:熟悉TongWeb数据源和开源数据源的配置,会从数据库端分析。
5. 内存引起的慢
这种现象通常是TongWeb控制台和应用访部都很慢,日志中有“OutOfMemoryError:Java
heap space”,就跟前面说的“死”一样,但进程还在。通过查看bin下gc.log日志,或通过jstat
命令,查看内存是否占满,Full GC是否频繁。
gc.log中有Full GC过于频繁的日志如下:
1004277.657: [Full GC 7442688K>7326004K(7909312K), 14.7484964 secs]
1004292.491: [Full GC 7442688K>7234814K(7909312K), 17.6059770 secs]
1004310.273: [Full GC 7442687K>7327296K(7909312K), 14.6444008 secs]
1004325.036: [Full GC 7442687K>7328115K(7909312K), 14.6859322 secs]
jstat:用于输出java程序内存使用情况,包括新生代、老年代、元数据区容量、垃圾回收情
况。
例: jstat gcutil 进程号 2000 20
上述命令输出进程ID为3618的内存使用情况(每2000毫秒输出一次,一共输出20次)
S0:幸存1区当前使用比例 S1:幸存2区当前使用比例
E:伊甸园区使用比例 O:老年代使用比例
M:元数据区使用比例 CCS:压缩使用比例
YGC:年轻代垃圾回收次数 FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间 GCT:垃圾回收消耗总时间
当 确认内存满了,执行以下操作:
(1) 要求出现OutOfMemoryError:Java heap space时不要重启Java进程,保留进程继续执行如
下操作。
(2) 利用JDK的jps –v命令查出Java的进程号。
(3) 通过jmap –histo <PID> > mem.txt 打出文本日志,生成过程很快,文件很小。
(4) 采用jmap生成完整的内存镜像文件
jmap dump:live,format=b,file=heap.bin <PID>
在当前执行命令目录下生成,如果内存设为2G,则生成的内存镜像文件也有2G。
(5) 生成的mem.txt文件可以用文本工具打开直接看,内存镜像文件可以用MemoryAnalyzer内
存分析工具分析。下载地址如: http://www.eclipse.org/mat。 分析这些文件需要用大内存机
器才行,建议用64位windows机器,安装64位MemoryAnalyzer软件,物理内存至少为内存镜
像文件的3倍。
误区:JVM内存够不够用主要看GC(垃圾回收)情况,并非JVM内存设越大越好、并非JVM
内存设越大越好、并非内存设越大越好,看内存使用量的曲线意义也不大。
要点:熟悉JVM的GC、会用jstat、jmap、MemoryAnalyzer分析JVM内存。
6. "大部分业务正常,只有个别业务慢", 这显然是应用该部分业务的问题,与中间件无
关。推荐阿里开源的 java 诊断工具Arthas,可做源码级性能分析。
7. 除以上手工方式,TongWeb快照功能、TongAPM功能也可提供部分日志,具体请看
《TongWeb用户手册》《TongAPM用户使用手册》
四、总结
通过以上说明,主要是让各位了解一下出现系统问题时,该如何描述问题,针对不同的
问题现象该如何处理。处理这些问题的最基本要求是:
1. 理清问题现象。
2. 会通过Linux基本命令、jstack、jstat、jmap、showbusyjavathreads.sh、jps、Arthas、
MemoryAnalyzer等工具和命令收集日志。具体使用方法可百度 。
3. 会查看GC日志、线程日志、内存镜像日志,并熟悉JVM、TongWeb参数的调优、应用代
码 的优化。