在某些情况下服务器可能会出现停止响应的情况,会导致所有用户不能登录、所有报表不能打开等现象。在排除服务器已经出现内存溢出的情况下,主要的原因是线程死锁、对象池或连接池满造成的。
1. 信息收集
出现问题后需要收集的是服务器当前的线程堆栈,可以通过以下方法得到:
- 如果服务器还可以正常登录使用,可以在登录后点击管理-工具-导出系统日志并打开ThreadDump.txt得到
- 如果已经不能正常登录但是比较容易重现该问题,请在出现问题请先访问http://ip: port/smartbi/vision/monitor/threaddump.jsp开始将线程堆栈日志打印到临时目录中。在出现问题后可以在该临时目录中找到线程堆栈信息
- 如果不方便重现可以通过以下方法处理:
a) 如果服务器是Windows系统并且非系统服务器方式启动(即登录Windows后双击Bat/Cmd启动的方式),可以在服务器的命令提示符控制台窗口中按下Ctrl+Break打印当前的堆栈。但是应该先清空并设置屏幕缓冲区高度足够大:
i. 点击命令提示符窗口左上角图标,在菜单中点击属性
ii. 在“布局”标签页中,先设置“屏幕缓存区大小”中的高度为1并点击确定,选择“属性仅对当前窗口生效”,这样可以清空当前屏幕
iii. 清空屏幕后,再次点击属性菜单进入设置界面。修改“屏幕缓冲区大小”中高度为3000,“窗口大小”中高度为25。
iv. 按下Ctrl+Break后,JVM会在命令提示符窗口中打印当前的堆栈信息
v. 点击左上角图标,点击菜单编辑-全选,再点击菜单编辑-复制就可以将堆栈信息复制到剪贴板中
vi. 打开UltraEdit等编辑工具粘贴并保存成文件
b) 若服务器是Unix/Linux环境,则可以通过以下方式操作:
i. 先确保服务器启动时将标准输出指定为文件,例如通过nohup startup.sh >nohou.out&
ii. 通过命令ps -ef|grep java找到服务器进程的pid
iii. 运行命令kill -3 pid后,服务器会将当前的线程堆栈打印到标准输出中,可能是nohup.out、SystemOut.log、或者单独一个新的dump文件和javacore文件中
c) 若有可能也可以通过JVisualVM连接到服务器进程并生成线程堆栈
2. 问题诊断
从日志中我们可以得到各个线程当前状态,其中主要分析的是WAIT状态的线程。分析的方法大致如下:
- 搜索所有状态为BLOCKED的Web处理线程(WebLogic中是ExecuteThread: id,WebSphere中是,Tomcat中是http-processor-id)
- 找到这个线程在等待哪个线程释放资源,是否存在循环等待的死锁问题
- 分析是否由于数据库执行导致死锁的现象