2013-10-16 16 views
3

我有一個java網站使用Spring Data來提供與MongoDB的集成。 應用程序運行良好,但不斷積累的線程,直到服務器最終下降,出現此錯誤:MongoCleaner線程在Spring數據應用上積累

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongo': Invocation of init method failed; nested exception is java.lang.OutOfMemoryError: unable to create new native thread 
2013-10-15T14:51:40.305986+00:00 app[web.1]: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongo': Invocation of init method failed; nested exception is java.lang.OutOfMemoryError: unable to create new native thread 
2013-10-15T14:51:40.305986+00:00 app[web.1]: 1343234 [http-nio-55996-exec-6] DEBUG org.springframework.web.servlet.DispatcherServlet - Could not complete request 
2013-10-15T14:51:40.305986+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455) 
2013-10-15T14:51:40.305986+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) 
2013-10-15T14:51:40.305986+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) 
2013-10-15T14:51:40.305986+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) 
2013-10-15T14:51:40.305986+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) 
2013-10-15T14:51:40.305986+00:00 app[web.1]: at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) 
2013-10-15T14:51:40.306169+00:00 app[web.1]: at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) 
2013-10-15T14:51:40.306169+00:00 app[web.1]: at org.springframework.contex 
t.support.GenericXmlApplicationContext.<init>(GenericXmlApplicationContext.java:71) 
2013-10-15T14:51:40.305986+00:00 app[web.1]: at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) 
2013-10-15T14:51:40.305986+00:00 app[web.1]: at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:591) 
2013-10-15T14:51:40.306169+00:00 app[web.1]: at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
2013-10-15T14:51:40.306334+00:00 app[web.1]: at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:424) 
2013-10-15T14:51:40.306169+00:00 app[web.1]: at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:469) 
2013-10-15T14:51:40.306169+00:00 app[web.1]: at com.jux.model.Signin.persistSignin(Signin.java:40) 
2013-10-15T14:51:40.306169+00:00 app[web.1]: at com.intuit.controller.LoginController.authenticateUser(LoginController.java:71) 
2013-10-15T14:51:40.306169+00:00 app[web.1]: at java.lang.reflect.Method.invoke(Method.java:616) 
2013-10-15T14:51:40.306169+00:00 app[web.1]: at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176) 
2013-10-15T14:51:40.306334+00:00 app[web.1]: at org.springframework.web.servlet.FrameworkServlet. 
processRequest(FrameworkServlet.java:882) 
2013-10-15T14:51:40.306334+00:00 app[web.1]: at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789) 
2013-10-15T14:51:40.306169+00:00 app[web.1]: at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
2013-10-15T14:51:40.306169+00:00 app[web.1]: at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
2013-10-15T14:51:40.306334+00:00 app[web.1]: at javax.servlet.http.HttpServlet.service(HttpServlet.java:728) 
2013-10-15T14:51:40.306334+00:00 app[web.1]: at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852) 
2013-10-15T14:51:40.306334+00:00 app[web.1]: at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:436) 
2013-10-15T14:51:40.306334+00:00 app[web.1]: at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) 
2013-10-15T14:51:40.306727+00:00 app[web.1]: at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) 
2013-10-15T14:51:40.306334+00:00 app[web.1]: at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
2013-10-15T14:51:40.306334+00:00 app[web.1]: at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923) 
2013-10-15T14:51:40.306727+00:00 app[web.1]: at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) 
2013-10-15T14:51:40.306727+00:00 app[web.1]: at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) 
2013-10-15T14:51:40.306334+00:00 app[web.1]: at javax.servlet.http.HttpServlet.service(HttpServlet.java:647) 
2013-10-15T14:51:40.306727+00:00 app[web.1]: at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) 
2013-10-15T14:51:40.306875+00:00 app[web.1]: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146) 
2013-10-15T14:51:40.306875+00:00 app[web.1]: Caused by: java.lang.OutOfMemoryError: unable to create new native thread 
2013-10-15T14:51:40.306875+00:00 app[web.1]: at java.lang.Thread.start0(Native Method) 
2013-10-15T14:51:40.306727+00:00 app[web.1]: at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
2013-10-15T14:51:40.306727+00:00 app[web.1]: at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) 
2013-10-15T14:51:40.306875+00:00 app[web.1]: at com.mongodb.Mongo.<init>(Mongo.java:192) 
2013-10-15T14:51:40.306875+00:00 app[web.1]: at java.lang.Thread.start(Thread.java:657) 

我嘗試更新我使用了Spring數據的版本,並與這兩個1.3.1嘗試。 RELEASE和1.3.2.BUILD-SNAPSHOT - 同樣的問題。

我也讀過,Mongo驅動程序應該關閉這些線程,並且在我的最後關閉線程時不需要做任何事情,但我開始懷疑。 任何想法如何解決這個問題?

這裏是我的mongodb.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:context="http://www.springframework.org/schema/context" 
      xmlns:mongo="http://www.springframework.org/schema/data/mongo" 
      xsi:schemaLocation= 
      "http://www.springframework.org/schema/context 
      http://www.springframework.org/schema/context/spring-context-3.0.xsd 
      http://www.springframework.org/schema/data/mongo 
      http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd 
      http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> 

    <!-- Default bean name is 'mongo' --> 
    <mongo:mongo host="xxxxxx.mongolab.com" port="12345"> 
     <mongo:options connections-per-host="8" 
        threads-allowed-to-block-for-connection-multiplier="4" 
        connect-timeout="1000" 
        max-wait-time="1500" 
        auto-connect-retry="true" 
        socket-keep-alive="true" 
        socket-timeout="1500" 
        slave-ok="true" 
        write-number="1" 
        write-timeout="0" 
        write-fsync="true"/> 
    </mongo:mongo> 
    <mongo:db-factory id="myMongoDbFactory" 
        host="xxxxx.mongolab.com" 
        port="12345" 
        dbname="zzzz" 
        username="yyyy" 
        password="xxxx"/> 

    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"> 
     <constructor-arg ref="myMongoDbFactory"/> 
    </bean> 

</beans> 

這就是如何使查詢的MongoDB的控制器:

@RequestMapping(value = "/deletePart.htm", method = RequestMethod.GET) 
public String deletePart(String part_id) { 
    LOG.debug("in deletePart, part_id: "+part_id); 
    ApplicationContext ctx = new GenericXmlApplicationContext("mongodb.xml"); 
    MongoOperations mongoOps = (MongoOperations)ctx.getBean("mongoTemplate"); 
    Part p = mongoOps.findOne(new Query(where("id").is(part_id)), Part.class); 
    mongoOps.remove(p);  
    return "redirect:/parts.htm"; 
} 

這裏是線程不斷積累如何,從來沒有關閉圖片: Threads accumulating:

從線程轉儲,這裏是一個掛線的細節:

"MongoCleaner1448498515" daemon prio=5 tid=0x00007f939f888000 nid=0x12f03 waiting on condition [0x00000001ac920000] 
    java.lang.Thread.State: TIMED_WAITING (sleeping) 
    at java.lang.Thread.sleep(Native Method) 
    at com.mongodb.Mongo$CursorCleanerThread.run(Mongo.java:770) 

    Locked ownable synchronizers: 
    - None 

回答

1

如果您關閉應用程序上下文中,將關閉蒙戈實例,並防止無節制的線程增長:

@RequestMapping(value = "/deletePart.htm", method = RequestMethod.GET) 
public String deletePart(String part_id) { 
    LOG.debug("in deletePart, part_id: "+part_id); 
    GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("mongodb.xml"); 
    try { 
     MongoOperations mongoOps = (MongoOperations)ctx.getBean("mongoTemplate"); 
     Part p = mongoOps.findOne(new Query(where("id").is(part_id)), Part.class); 
     mongoOps.remove(p);  
     return "redirect:/parts.htm"; 
    } finally { 
     ctx.close(); // close the context, will close the Mongo instance 
    } 
} 

但是,即使這會工作,你的應用程序仍然不應該創建每個請求的應用上下文實例。

1

我不確定這是否是原因,但您絕對不應該爲每個請求創建新的上下文。

將您的mongodb.xml添加到您的根應用程序上下文中。