关于Smart Upload文件上载应用组件引起CPU资源100%占用问题

关于Smart Upload文件上载应用组件引起CPU资源100%占用问题

文件上载应用引起CPU资源100%占用问题

问题现象:
1.不定时出现内存异常增长、GC无法释放并导致JVM崩溃现象,JVM Heap堆被Upload类及其中间数据占满。
2.偶尔出现CPU占用率异常,达到100%,但没有发生JVM崩溃,其他应用也能较正常进行,JVM中有多个Upload进程在持续运行。

[@more@]
问题出现的区域:文档上传过程

问题出现的源头:1.网络传输延迟/错误
2.操作人员连续多次点击,造成同一文件在数秒内多次上传引起的传输错误。

问题出现的原因:
应用服务器之前装有IHS HTTP服务器,用户在访问过程中,在没有得到后台服务器相应的情况下断开连接,而重新发起新的请求。但由于IHS HTTP中间起着缓冲的作用,客户强行断开连接的异常,后台并不能及时得到,而认为连接正常,导致SmartUpload类持续读InputStream(造成CPU占用异常), 或读取了不完整的文件内容在处理过程中无法结束(造成内存泄漏)。


问题发生机制:
SmartUpload类主体代码可分为两部分(具体代码可参见相关类文件):
Part 1:从ServletHttpStream中连续读取字节流,直至读完。如果其中发生传输或其他系统错误,由Try,Catch进行错误处理。
Part 2:将取出的内容按照Post Content的统一规范进行处理,根据文件的开始、结束标志逐个进行处理,放入File对象(支持多个文件同时上传)。

通过跟踪我们发现,如果在上传文件过程中出现了传输错误(网络延迟、或操作失误),后台应用服务器并没有截获错误,没有触发Try、Catch机制,由此产生了两种错误及其现象,所以我们不能仅仅通过Try/Catch方式来进行判断:
1.ServletHttpStream中一直读不到字节流,相关后台应用服务器没有截获错误,导致SmartUpload类Part1一直在执行,造成CPU一直占用。在这样的情况发生多次后,CPU占用100%。
2.ServletHttpStream没有读完或读取错误,相关后台应用服务器没有截获错误,认为正常读取完成。导致上传文件的开始、结束标志残缺或不匹配,在SmartUpload类Part2处理过程中一直找不到文件结束标志,而不断增加新的File。最终造成内存泄漏。


问题解决方法:
改写SmartUpload代码,增加更全面、合理的条件判别,具体代码如下。(smartupload.jar,SmartUpload Java源代码)

package com.jspsmart.upload;
……
public class SmartUpload
{
……
public void upload()
throws SmartUploadException, IOException, ServletException
{
int totalRead = 0;
int readBytes = 0;
long totalFileSize = 0L;
boolean found = false;
……
----- Begin ----- Add for protecting Endless Do While Clause
int protectEndlessDoWhile = 0;
----- End ----- Add for protecting Endless Do While Clause

Add condition to determinate the InputStream status, to protect endless reading closed InputStream
Original code shows as this:
for(; totalRead < m_totalBytes; totalRead += readBytes)
Revised code shows as:
for(; totalRead < m_totalBytes && readBytes >=0; totalRead += readBytes)

for(; totalRead < m_totalBytes && readBytes >=0; totalRead += readBytes)
try
{
m_request.getInputStream();
readBytes = m_request.getInputStream().read(m_binArray, totalRead, m_totalBytes - totalRead);

}
catch(Exception e)
{
throw new SmartUploadException("Unable to upload.");
}

……
do
{
----- Begin ----- Add for protecting Endless Do While Clause
protectEndlessDoWhile ++;
----- End ----- Add for protecting Endless Do While Clause


Add condition to protect endless multiple files processing
Original code shows as this:
if(m_currentIndex >= m_totalBytes)
Revised code shows as:
if(m_currentIndex >= m_totalBytes || protectEndlessDoWhile >20)
if(m_currentIndex >= m_totalBytes || protectEndlessDoWhile >20)
break;
dataHeader = getDataHeader();
m_currentIndex = m_currentIndex + 2;
isFile = dataHeader.indexOf("filename") > 0;
fieldName = getDataFieldValue(dataHeader, "name");
……
} while(true);
}
……
private Request m_formRequest;
}

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/8819325/viewspace-902925/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/8819325/viewspace-902925/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值