3

Spring Data を使用して MongoDB との統合を提供する Java Web サイトがあります。アプリケーションは正常に動作しますが、サーバーが最終的に次のエラーでダウンするまで、スレッドを蓄積し続けます。

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 Data のバージョンを更新しようとしましたが、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";
}

以下は、スレッドが蓄積され続け、閉じられない様子を示しています。 累積するスレッド:

スレッド ダンプから、ハングしたスレッドの詳細を次に示します。

"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
4

2 に答える 2

1

アプリケーション コンテキストを閉じると、Mongo インスタンスが閉じられ、無制限のスレッドの成長が防止されます。

@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
   }
}

ただし、これは機能しますが、アプリケーションはリクエストごとにアプリケーション コンテキスト インスタンスを作成するべきではありません。

于 2013-11-11T20:09:20.243 に答える
1

これが原因かどうかはわかりませんが、リクエストごとに新しいコンテキストを作成するべきではありません。

mongodb.xml をルート アプリケーション コンテキストに追加します。

于 2013-11-06T00:06:46.697 に答える