2013-05-16 1 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번만 - 아파치 서버가 시작될 때만 호출됩니다. 그것은 전체 시스템에서 mongoConnection을 설정하는 유일한 장소입니다.

버튼을 누를 때마다 mongoConnection이 설정되지 않습니다. 그리고 데이터는 mongo 데이터베이스에서 가져오고, mongoConnection 테스트는 null이 아님을 보여줍니다.

mongoConnection은 null이 아닌가요? 그리고 새로운 연결이 산발적으로 만들어지는 이유는 무엇입니까?

답변

1

MongoClient는 연결 풀입니다. 그것은 성능을 위해 데이터베이스에 많은 수의 연결을 유지합니다 (새로운 연결을 만드는 것은 값 비쌉니다).

mongoConnection.getDB ("DB")를 호출하면 MongoClient가 연결 풀에서 데이터베이스 연결을 검색합니다. 연결 풀에 사용 가능한 연결이없는 경우 새 연결을 만들어 풀에 추가합니다.

mongoConnection.close()를 호출하면 연결이 끊어지지 않습니다. 다시 연결 풀로 리턴되어 재사용됩니다.

기본적으로 풀 크기는 5입니다. 이렇게하면 닫은 후에도 결국 5 개의 연결이 열리게됩니다 (풀에 "닫힌"연결이 반환됨을 기억하십시오). 이 크기를 변경할 수 있습니다

+0

Hrm. (돌아가서 역사를 들여다 본다.) 한 번에 최대 11 개의 연결을 열었습니다 ... 풀 크기를 어디에서 설정할 수 있습니까? 그들은 모두 동시에 산란하지 않으며, 산발적 인 패턴을 가지고 있습니다. 'mongoConnection.close()'는 아파치가 종료 될 때 한 번만 호출됩니다. 그런 다음 모든 여분의 연결이 사라집니다. 나는 더 자주 닫히기로되어 있나? –

+0

- 다른 질문에 대한 아이디어가 있습니까? 'mongoConnection'이 null이 아닌 이유는 무엇입니까? 나는 그것이 효과가있어 행복하다. .. 그러나 나는 단지 아직 일하기로되어 있지 않은 테스트를 달리게하고 있었다.그리고 놀랐습니다. 왜 그런지 알고 싶어. –

+0

두 번째 매개 변수로 MongoClientOptions가있는 MongoClient 생성자가 있습니다. 옵션에서 connectionsPerHost를 설정할 수 있습니다. 종료 직전이 아니라 사용 직후에 연결을 닫아야합니다. 11 개의 동시 연결 수를 어떻게 확신 할 수 없습니다. – happymeal