高分求助,急 急 急,tomcat
老问题,没解决。求高手帮忙,万分感激。
问题描述:
1.web工程,ssh框架,c3p0连接池,firebird数据库,extjs前台框架。
2.工程访问人数不多,最多20多个,但是每次访问的数据量很大。
3.虽然数据量大,但是数据库的操作很简单,全程存储过程,所有数据访问都是同步ajax。
4.如果一直操作、访问,那么不会有任何问题。
5.任何一个访问者,就算当前只有一个人来访问,如果查询了数据后长时间不动也不关闭网页就会出现tomcat死掉的情况。
6.tomcat死掉状况:(tomcat、数据库、cs工程分别在不同的服务器上)
a.访问web工程,提示浏览器无法打开该网页。
b.访问tomcat管理页,提示浏览器无法打开网页。
c.在tomcat所在服务器上用数据库访问工具连接数据库,提示"系统缓冲区空间不足或队列已满、无法执行套接字操作"。
d.数据库和cs工程可以正常运行。
e.需要重起tomcat所在服务器。
以前针对这个问题已经发了一个帖子,但是没能解决问题,在以前的那个帖子中,朋友们提供的思路都试过了,问题还在存在。针对以前的帖子,这里贴出一部分配置文件、源码和日志。
web.cfg
- XML code
<!-- HIBERNATE 延迟加载 --> <filter> <filter-name>hibernateFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>hibernateFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- SPRING 加载 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml;</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
hibernate.cfg.xml配置文件:
- XML code
<property name="hibernate.dialect">org.hibernate.dialect.FirebirdDialect</property> <property name="connection.driver_class">org.firebirdsql.jdbc.FBDriver</property> <property name="connection.url">jdbc:firebirdsql:10.106.115.2/3050:pim</property> <property name="connection.username">SYSDBA</property> <property name="connection.password">masterkey</property> <!-- 配置连接池 --> <property name="hibernate.c3p0.acquire_increment">1</property> <property name="hibernate.c3p0.idle_test_period">100</property> <!-- seconds --> <property name="hibernate.c3p0.max_size">10</property> <property name="hibernate.c3p0.max_statements">50</property> <property name="hibernate.c3p0.min_size">3</property> <property name="hibernate.c3p0.timeout">300</property> <!-- milliseconds --> <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> <!-- 其他 --> <property name="show_sql">true</property> <property name="format_sql">true</property> <property name="current_session_context_class">thread</property> <!-- 二级缓 --> <property name="hibernate.cache.use_second_level_cache">true</property> <property name="hibernate.cache.use_query_cache">true</property> <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> <property name="hibernate.generate_statistics">true</property>
spring配置文件:
- XML code
<!-- 配置 sessionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="configLocations" value="classpath:hibernate.cfg.xml" /> <property name="packagesToScan" value="com.tljw.table.bean" /> </bean> <!-- 配置事务管理 --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"> <ref bean="sessionFactory" /> </property> </bean>
最常用的一个查询方法:
- Java code
public String getMeterCopyDetailsOfLowELec(String startDate,String endDate,Integer meterId){ Session session = null; List<Object[]> result = null ; List rt = new ArrayList(); String sql = "select * from PC_CMRSCOPRSULTQRY('"+startDate+"','"+endDate+"','"+meterId+"')where SREADING is not null order by SDATETIME"; //sql方式调用存储过程 try{ session = HibernateSessionFactory.getSession(); SQLQuery sqlQuery = session.createSQLQuery(sql); result = sqlQuery.list(); }catch(Exception e){ e.printStackTrace(); }finally{ if(session!=null){ session.close();//关闭连接 } } for(Object[] obj : result) { Map map = new HashMap(); map.put("sdateTime", obj[0]); map.put("sreading",obj[1]); map.put("meterDiffData",obj[2]); map.put("meterQuantity",obj[3]); map.put("beilv",obj[4]); rt.add(map); } String r1 = CstJSONObject.list2String(rt); return r1; }
[解决办法]
TOMCAT死掉 一般是程序代码本身的问题
很多资源没释放 例如一些流对象为关闭 或者形成死循环
[解决办法]
估计是 代码的问题,可能是 什么地方 没有关闭资源 造成大量浪费内存
仔细 检查下 尤其是跟数据库关联这块
[解决办法]
[解决办法]
有可能是连接池的问题
[解决办法]
java.sql.SQLException: Connections could not be acquired from the underlying database!
数据库连接池!或者连接没释放!或者查询数据量太大
[解决办法]
是不是hibernate.session创建后没有被及时关闭?或者你是不是每次访问数据库时hibernate都重新打开?或者是不是每个人都单独开起了hibernate.session?
[解决办法]
tomcat 系统缓冲区空间用完
像这样的错误,除了检查代码之外
可以考虑下面的处理
1.换一个app server,如jboss,goldfish,resin之类,看有没有问题
2.看你自己的代码,优化一下,找一下BUG
3.重建你的数据结构,web方式一下子返回给客户端巨大的数据集,是不好的
[解决办法]
LZ的代码给人的一种感觉:不够优化。
1)SQL。
你常用的那个DB操作接口,动不动是select *... 这东西不要小看,就算你后面有where过滤掉,但是你字段多的情况下,*比指定字段要慢很多。你还是优化下SQL,不要随便的全拿出来,只拿你想要的,真正想要的字段出来。
2)集合大量嵌套
ArrayList 里面丢HashMap, HashMap里面丢大量对象。要知道,java的gc效率是很低的。你这样塞下去,内存会消耗的很快,虽然不会造成c/c++的那种泄露,但是你已经造成了java的“内存泄露”了。因为没有用的对象迟迟得不到销毁,在那里占用内存---尽管gc已经知道这些内存需要销毁。
优化:java的集合框架用起来确实很方便,但是类似LZ这样的“偷懒”方式,根本原因还是系统设计不够好。否则用不着这么大量的集合嵌套。 优化下你的系统设计,集合对象退出前,手动clean掉。一层层clean出来。
3)关于一个人不关浏览器,导致tom死机。貌似用到了长会话。你把HttpSession会话周期设置合理一点,而且Session里面不要丢大对象。只保存必须的用户信息跟踪等短小但重要的信息。
4)还有,就是楼上人说的,资源关闭。不过既然用到了SSH,这些应该不是关键的。
能想到的就这些了,抛砖引玉。
[解决办法]
tomcat死的时候检查系统内存和CPU,看资源占用情况,你可能需要定期抓一些服务器CPU/IO/内存数据,比如Vmstat,iostat
如果发现确实是tomcat吃光内存造成死掉,用JRocket启动,检查哪个实例在一直增长,查代码中new这个实例的行,找出内存泄漏的代码
数组ArrayList中放的实例对象被循环引用是一个常见的内存泄漏的原因
[解决办法]
上面的高手都是从服务器的知识进行分析,从哪个异常看,我觉得有必要去看一下你的网络。你的应用和数据库是分开的,网络用的是动态ip还是静态ip,如果是动态ip,长时间不操作,说不定在路由器重新分配ip的时候应用会连不上数据库,可能导致链接报错,导致tomcat数据库模块崩溃。看一下DHCP配置策略。
希望能帮上忙,遇到这种事情的确郁闷!大家都帮一下吧·