ITPub博客

首页 > IT基础架构 > 网络安全 > 关于Smart Upload文件上载应用组件引起CPU资源100%占用问题

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

原创 网络安全 作者:swcracker 时间:2007-03-06 11:17:28 0 删除 编辑

关于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博客 ” ,链接:https://blog.itpub.net/8819325/viewspace-902925/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: 没有了~
请登录后发表评论 登录
全部评论
  • 博文量
    11
  • 访问量
    17049