论坛首页 Java企业应用论坛

[求助]高并发的大数据量查询导致系统频繁宕机,咋办啊

浏览 48031 次
该帖已经被评为良好帖
作者 正文
   发表时间:2007-04-26  
抛个砖:

先确定几个可行的原则:
1、尽早的释放数据库连接
2、尽可能少的创建对象
3、用临时文件来代替jvm中的临时对象,缩短值对象的生命周期
4、缓存

ResultSet循环取值的时候,调用一个callback接口,该接口负责将各字段值直接放入到临时文件中。

interface ResultSetPersistCallback {
  void appendRow(rs);
}

TextPersistCallback的具体实现是将每一行以csv的格式append到临时的文本文件中,这个没啥好说的,直接使用append模式的File即可

XlsPersistCallback的具体实现是每一行附加到临时的Excel中,这个比较麻烦了(POI的实现中,仍然在jvm中构建HSSFWorkbook对象图,最后一次性写入xls文件,并且每个sheet还有65536的最大行限制),貌似没有好的方案能够缩短值对象的生命周期。


rs循环完毕,释放数据库资源,关闭临时文件,维护缓存池,文件流发送到客户端。


缓存池结构:
key: sql key
value: CachedFile

class CachedFile{
String filepath;
long creationTime;
long period;
}

当然还少不了一个scheduler去掉过期的缓存和临时文件。


0 请登录后投票
   发表时间:2007-04-26  
内存爆掉很好解决,使用线程池限制生成xls的并发数量不就得了。
0 请登录后投票
   发表时间:2007-04-26  
to sorphi:
谢谢你提供的方案
事实上类似的方案我也提了 但是由于系统中根本就没考虑到callback的设计 现在的dao都是写死的
改动比较大 已经被我们老大驳回了  :'(
0 请登录后投票
   发表时间:2007-04-26  
fins,写完之后才发现你也提到了xls的写入才是瓶颈。

而且我刚才想了一下,我的方法中callback导致第2/3三条和第1条是冲突的。

既然方法被驳回了,那也说得过去。那就集中解决xls的生成问题吧

刚才google了一下csv -> xls的东西,虽然没找到什么有效的java代码,但是发现一个有趣的事情,有网站专门提供在线的转换。继而想到,何不单独提供一个应用来干这个事情呢?

不过用java来做这种转换,仍然摆脱不了内存占用较大的问题,看poi的API。jxl的我不清楚,照你说的,跟poi的差不多。

既然客户比较“变态”(查询这么贼多数据),那么何不让这种转换拿到client端来做呢?哈哈

继续google,activex+csv+xls

http://www.softinterface.com/Convert-Excel-ActiveX/Convert-Excel-ActiveX.htm

0 请登录后投票
   发表时间:2007-04-26  
考虑生成跟下载分成两个步骤。 另外既然内存占用那么多,jvm的内存调优也要考虑
0 请登录后投票
   发表时间:2007-04-26  
sorphi 写道
fins,写完之后才发现你也提到了xls的写入才是瓶颈。

而且我刚才想了一下,我的方法中callback导致第2/3三条和第1条是冲突的。

既然方法被驳回了,那也说得过去。那就集中解决xls的生成问题吧

刚才google了一下csv -> xls的东西,虽然没找到什么有效的java代码,但是发现一个有趣的事情,有网站专门提供在线的转换。继而想到,何不单独提供一个应用来干这个事情呢?

不过用java来做这种转换,仍然摆脱不了内存占用较大的问题,看poi的API。jxl的我不清楚,照你说的,跟poi的差不多。

既然客户比较“变态”(查询这么贼多数据),那么何不让这种转换拿到client端来做呢?哈哈

继续google,activex+csv+xls

http://www.softinterface.com/Convert-Excel-ActiveX/Convert-Excel-ActiveX.htm



我说的不太准确 其实是两个瓶颈 一个是 collection对象 一个是jxl生成的xls大对象
郁闷中 我打算研究一下excel的生成原理 自己做一个合并xls文件的程序
把多个文件 合并成一个有多个sheet页的xls文件 (用jxl poi做这类操作还是会生成很大很大的对象)
0 请登录后投票
   发表时间:2007-04-27  
解决你的 excel问题,可以考虑生成csv。先在服务器生成一个临时文件来存放csv问题,然后查询数据,取数据放入stringBuffer 当此stringBuffer的数据大到一定程度时候就往文件里输出,然后清空StringBuffer 这样重复处理,直到查询出来的数据都写人文件。这样因该可以避免java的outofmemory。
0 请登录后投票
   发表时间:2007-04-27  
fins 写道

我说的不太准确 其实是两个瓶颈 一个是 collection对象 一个是jxl生成的xls大对象
郁闷中 我打算研究一下excel的生成原理 自己做一个合并xls文件的程序
把多个文件 合并成一个有多个sheet页的xls文件 (用jxl poi做这类操作还是会生成很大很大的对象)


1.
对于生成xls文件,我有一些经验。
我用的POI。我发现,对于同样是将2万行的数据写入一个文件,放在一个sheet里和两个sheet里,内存占用能相差一倍,后者少。经过我的试验,一般一个sheet里1万行(一行有10几列)比较合适,多的就分sheet保存,可以有效的降低内存占用,约1--n倍。
虽然不是终极的解决方案,也是一个可行的方案,不妨试试。


2.
csv是简单文本格式,内存占用量必定比xls少很多倍,但是他基本上无法表达格式。实在不行就用csv好了。


3.
还有一个曲线救国的方法,就是用html格式,技巧是,将html文件保存成xls后缀文件(假装为xls),excel是可以自动识别为html并打开,也可以保存格式。唯一的不同是,用户需要“真实”的xls格式的话,需要用Excel打开后另存为xls格式。其实用户不就是打印么,那么应该没有区别。
0 请登录后投票
   发表时间:2007-04-27  
programmer 写道
解决你的 excel问题,可以考虑生成csv。先在服务器生成一个临时文件来存放csv问题,然后查询数据,取数据放入stringBuffer 当此stringBuffer的数据大到一定程度时候就往文件里输出,然后清空StringBuffer 这样重复处理,直到查询出来的数据都写人文件。这样因该可以避免java的outofmemory。


类似的方法我们用过 我们是直接将 response.getOutputStream传入dao
在dao里生成  printwriter 然后直接 out.print
这个方法应该更好 避免了生成和修改文件
0 请登录后投票
   发表时间:2007-04-27  
Lucas Lee 写道
fins 写道

我说的不太准确 其实是两个瓶颈 一个是 collection对象 一个是jxl生成的xls大对象
郁闷中 我打算研究一下excel的生成原理 自己做一个合并xls文件的程序
把多个文件 合并成一个有多个sheet页的xls文件 (用jxl poi做这类操作还是会生成很大很大的对象)


1.
对于生成xls文件,我有一些经验。
我用的POI。我发现,对于同样是将2万行的数据写入一个文件,放在一个sheet里和两个sheet里,内存占用能相差一倍,后者少。经过我的试验,一般一个sheet里1万行(一行有10几列)比较合适,多的就分sheet保存,可以有效的降低内存占用,约1--n倍。
虽然不是终极的解决方案,也是一个可行的方案,不妨试试。


2.
csv是简单文本格式,内存占用量必定比xls少很多倍,但是他基本上无法表达格式。实在不行就用csv好了。


3.
还有一个曲线救国的方法,就是用html格式,技巧是,将html文件保存成xls后缀文件(假装为xls),excel是可以自动识别为html并打开,也可以保存格式。唯一的不同是,用户需要“真实”的xls格式的话,需要用Excel打开后另存为xls格式。其实用户不就是打印么,那么应该没有区别。


1 3 策略我们现在的系统都用到了
问题就是老系统 我主贴中提到的是一个老系统 郁闷啊

不过还是谢谢大家提供的方案
其实仔细看看,可以说,楼上各位的方案基本上已经涵盖了 所有的 xls的解决方法
我可以把这个帖子作为一个 方法的汇总帖了 呵呵

谢谢各位!!!
如果我们老大允许我们大刀阔斧的改造代码 一切就都OK了
现在也许问题已经不是出在方法和技巧上 而是人的问题了

以前系统设计的不够好 ,让现在的人为过去埋单,似乎也是天经地义的.毕竟我也从前辈那学到过太多的东西
呵呵

再次谢谢大家
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics