2013-05-16 73 views
1

所以,我试图让Mongo连接在应用程序的几次使用(页面访问)中保持不变。我厌倦了在测试过程中建立起来的所有这些连接,并且我希望通过建立单一的持久连接来使用正确的过程。最佳实践和所有。ServletContext属性和静态属性

这是我有:

的web.xml

<listener> 
    <listener-class>com.core.tools.MyServletContextListener</listener-class> 
</listener> 

com.core.tools.MyServletContextListener

public class MyServletContextListener implements ServletContextListener { 
    private static Logger log = org.apache.log4j.Logger.getLogger(MyServletContextListener.class); 
    public void contextInitialized(ServletContextEvent sce){ 
     try { 
      EntityManager.setupMongoClient(sce); 
     } catch (UnknownHostException e) { 
      log.error("Error setting up Servlet Context"); 
     } 
    } 

    public void contextDestroyed(ServletContextEvent sce){ 
     EntityManager.closeMongoClient(sce); 
    } 
} 

的EntityManager

public class EntityManager { 
    private static MongoClient  mongoConnection = null; 
    private static Jongo   jongoDatasource = null; 

    public static void setupMongoClient(ServletContextEvent sce) throws UnknownHostException{ 
     if(sce.getServletContext().getAttribute("mongo") == null){ 
      mongoConnection = new MongoClient("localhost"); 
      sce.getServletContext().setAttribute("mongo", mongoConnection); 
     }else if (mongoConnection == null) { 
      mongoConnection = (MongoClient) sce.getServletContext().getAttribute("mongo"); 
     } 
    } 

    public static Jongo getJongoDatasource(){ 
     if(jongoDatasource == null){ 
      jongoDatasource = new Jongo(mongoConnection.getDB("coreTest")); 
     } 
     return jongoDatasource; 
    } 

    public static void closeMongoClient(ServletContextEvent sce){ 
     if(sce.getServletContext().getAttribute("mongo") != null){ 
      mongoConnection = (MongoClient) sce.getServletContext().getAttribute("mongo"); 
      mongoConnection.close(); 
     } 
    } 
} 

会发生什么:

好消息 - 现在我的连接在服务器关闭时被清理干净。

坏消息 - 我仍然一直在获取大量和大量的连接。每次按下按钮时,它都会建立一个新的连接......但仅限于4或5个连接。然后突然停止添加新的连接一段时间。然后它会再添加3个。然后等待。然后是另一个2.然后没有。几分钟后,突然间又增加了5个连接。

令人困惑:我甚至不知道它是如何管理到使这些连接。跟踪方法调用 - setupMongoClient仅被称为一次 - 当apache服务器启动时。它是整个系统中唯一设置mongoConnection的地方。

每当我按下按钮,mongoConnection没有设置。然而,这些数据是从mongo数据库中提取的,测试mongoConnection表明它不是null。

mongoConnection如何不为空?为什么新的连接零星地被建立?

回答

1

MongoClient是一个连接池;它维护了许多与数据库打开连接以获得性能(创建新连接代价高昂)。

当您调用mongoConnection.getDB(“DB”)时,MongoClient将从连接池中检索数据库连接。如果连接池中没有可用连接,它将创建一个新连接并将其添加到池中。

当您调用mongoConnection.close()时,连接不会被拆除。它只是返回到连接池以供重用。

默认情况下,池大小为5.这解释了为什么即使您已关闭它们(请记住,“已关闭”连接返回到池),最终还是会有5个打开的连接。你可以改变这个尺寸

+0

Hrm。 (回顾并查看历史记录)我最多可以打开11个连接...我在哪里可以找到池大小设置为?它们并不都是同时产卵的,它们有那种零星的模式。 'mongoConnection.close()'只在apache关闭时调用一次。然后所有这些额外的连接都会消失。我应该更频繁地关闭吗? –

+0

另外 - 关于另一个问题的任何想法?为什么'mongoConnection'不为null?我很高兴它的工作原理......但我只是在进行一项不应该工作的测试。当它真的很惊讶。我很想知道为什么。 –

+0

有一个MongoClient构造函数,它有一个MongoClientOptions作为第二个参数。您可以在选项中设置connectionsPerHost。您应该在使用后立即关闭连接,而不是仅在关机期间关闭连接。我不知道你如何达到11个并发连接。 – happymeal