请教:tomcat并发性问题.
环境是apache2.0+tomcat4.1+oracle8i
用户量是比较多的需要支持在500左右,
由于查询的数据量比较大,
一般是在几亿条中通过一定条件,聚组,排序生成几百条数据(sql语句速度
比较慢,sqlplus测试,优化也做了很多)
当用户并发请求多的时候,系统的链接池(用改造后的jive链接池)就被占光,系统就处于僵死状态.
做过很多改进但效果也不是很理想.
不知道大家有什么好的建议,十分感谢,由于做这方面的开发不久,还请大家
多多指教.
为什么有的系统直接使用Tomcat的连接池就可以了呢?因为这个系统2/3操作都是数据库操作,没有在内存中的运算,而数据库连接池基本缓解提升系统方面的性能。
如果这样的系统日益复杂,要么自己做缓存,要么使用EJB了。
你这个案例就是明显需要优化逻辑运算的JavaBeans,不要把系统压力都通过数据库访问来解决,这样的系统和以前数据库系统没有什么区别了。
tomcat有平衡的,但效果不明显,有很多问题。
从你的这句话看:"一般是在几亿条中通过一定条件,聚组,排序生成几百条数据"
你这里说的“一定条件,聚组,排序”是指一条SQL中完成的情况吧,如果不是一条你就变成一条。
这里的问题不在连接池,不在缓存,所以你提的“两套数据链接池(一部分提供给小型快速的操作,一部分提供给大数据查询)”也会不明显。
另外我可以明确告诉你一点,这里cmp对你没帮助,几亿中抽出的结果是没任何缓存意义的。
我相信你的tomcat服务器的cpu的使用率也不高,相反,你的DB服务器的CPU在忙不过来,你去查一下看看。
解决DB上的问题,用下面的一些方法:
1. 由一个表变成多个表,比方变成A200401,A200402。。。,然后在查之前,在java函数中依条件判断一下要调哪几个表,再查DB
2. SQL语句的优化,比方where子句,过滤最多的条件放在最前。
3. DB做机群,小型快速的操作涉及的表 大数据查询涉及的表放不同的表空间和不同机器上。做oracle机群网上资料多的是
同时我们也检测到即使tomcat僵死的时候,oracle还是在正常运行,只是有一些进程是bufferbuzy的.
唉想不到好办法了.
系统几乎没有什么大的业务逻辑,感觉用不上ejb,缓存机制也没什么用.
在我_l系y的^念中
哆@N大量Y料碓
通常是另外一台 database 砉芸
@幼 db loading 档
也可以提N效能
如果你ο到y架o法袢∽更的手段 不具溆 application server
不裼 hibernate 砣〈愕 jdbc access
或是自己撰相P的 cache C制
不^前提是 RAM 要虼 否t也是R上消耗殆M
500 user concurrnets 算是很少了
Y料再怎N大 都不是太大的}
而是你如何去{配控制每次出的n案大小
裼梅猪 或是一些技巧肀苊
至於 tomcat 僵死
我猜是因 request ^多
不^你可以加大 tomcat 的 jvm 的绦 memory
假O server 是 2Gb 的 ram
你可以更改 java -Xmx 2048 -Xms 1024 ....
因为J2EE的集群目前都是针对EJB服务器的,而你的业务核心和数据库访问都是在Web层,所以,通用的J2EE集群对你无能为力,也就是说,无法通过简单地增加服务器就能提供性能。
Jive这方面做了探索,在其3.1等版本中,使用了大概叫tango的商业分布式缓存系统,所谓分布式缓存系统,就是可以在多台机器上实现缓存,使用这个缓存系统好处:可以增加多台服务器;也提高单台机器性能。
因为无法知道你这个系统的设计,不能给出具体之道,但是引入Cache缓存机制是根本之道,单纯依赖数据库层提升不是永久之道,将那些反复读取的数据放在内存中,Web层其实是一个大的线程池,你还需要为每个线程分配一个缓存对象。
现在我不清楚楼主的应用程式的类型是什么
但是与其想尽办法做查询资料的效率调校
还不如想说有什么方法可以避开资料的查询...
如果有些查询的资料是变动性不大
但是重复浏览性很多
(如新闻网站)
那可以把这些资料直接转成静态网页
或是大部分相同 少部分不同的话
(如portal)
可以转成velocity的template
并不是所有资料都要向资料库去要资料的
可以用一些小技巧大大的改进效能
而ejb的cache是以物件为对象的
但是还有另一种cache是以document为对象的
我刚刚提到的都是
希望可以给你另一个方向
还是通过优化数据库,将查询的数据放到一个独立数据库中,oracle不是有一种建库类型叫“数据仓库”吗?不知道这个会不会专门针对查询进行优化?
创建表分区,合适的地方建立索引。还有starfeng 提到的建立数据库集群(这个我也不懂)
ejb是有用,但有用他的地方,要是什么地方都他最大,我们做设计就不用这么麻烦,sun公司也不必又弄ejb3.0又弄jsp2.0。
cache是有用,但cache还有个命中率的问题。没有cache,那么cache的命中率当然是0,如果加上cache,但cache的命中率只有1%,那还不如不用。因为,cache的同步涉及的问题就不是一点点,处理起来也是要时间,当然,更要内存。
再回到你的问题:
操作:几亿条中,经一些条件,选出几百条。
问题:访问一多,web服务器的链接池占光,系统僵死
对吧,是这个问题
这里有一点点,我还有点不清楚,“僵死”,具体指的是什么
对于其它的不带DB查询的jsp也“僵死”了?还是说,只是那些带查询的死了。我想你说的应该是后者吧。
补充问一下,你的Web服务器和DB服务器是分开的吧,如果在一台机器上,想想应是不会有人这么做,我有些太多心。
好,怎么处理呢
首先,不太可能的方法:
EJB不太可能,原因很简单,cache命中率,
有人也许会说,银行呢,那用户还不多啊,ejb运用常见例子啊,不过,要注意一点是,那里主要体现了事务,另外一点是数据持久。当然最后一点,也有与cache相关的:用户进行一系列业务操作,他要重得用到那几个数据实体,虽然第一次业务操作的cache命中率几乎为0,但随后的几次就100%了!当然提速。
但,上面的一切说话,在你这里不通用。你这里就是一个查询,就是因为这个查询,在很多用户同事来访问时,服务器“僵死”
那么,要怎么做呢,我觉得你可以从以下方面着手:
一是对于用户重复点击的处理。
二是tomcat连接池的配置。
关于一:
你只要在那几个会涉及大量数据查询的jsp引入一些判断,比方,同一个人在5秒之内不许连续查。在session中加个变量记录下时间就可以了,查询前做一下判断,就可以做到防止重复点击,实现很简单是吧:)
关于二:
要用两套连接池,一个给大量数据查询的用,这个连接池你就要限制严格些,比方,将最大连接数就设为5,最多5个人同时查。
与此同时,你的那几个涉及大量数据查询的jsp页面也要改动一点点代码。另外还要注意的就是,改动的代码中要注意到这样一个问题:如果你的jsp在取连接池没有取到连接时,jsp要立即结束运行,注意是立即,不要因为在等着连接池给你连接而挂在那里,千万要注意!!!不然,WEB服务器也会因为挂的线程变多而“僵死”。
另一个供数据量少查询用,连接池就可设多些,可以设50或100,就看你oracle的能力了。
这样做以后,可能依然会有一个问题:大量数据查询的jsp,会经常出现查不到,这时,如果用户还不能接受,那么你要将这几亿数据的表单独放一DB服务器,甚至做集群了。
但从你们的业务看应该不会到做集群的地步。我觉得你们的DB,还是做得不够优化。
为什么呢,因为,像计费系统,里面的表数据相对一般业务可以算是很大了。几亿数据的查询都不会到做集群的地步。
我建议,在oracle配置方面、SQL的优化、表索引这些方面,你们还是要再考虑一下。
我上帖曾提过一下表的拆分,效果应该是比较明显的,只是拆分要注意是根椐查询条件的设定做表的拆分,拆得不好等于没拆,但我不知你们的实际查询业务是怎么个样子,在表拆分后相应的逻辑语句,查询语句是怎么个改法。所以不好下结论。
另外,在oracle 9i中,数据分区对性能会有比较大的提高,