2013-05-16 77 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