05.JSP2008. 10. 19. 15:38
반응형

JSP 페이지를 실행할 때마다 커넥션을 생성해서 사용하게 되면 커넥션을 생성하고 닫는데 시간이 소모되기 때문에 동시 접속자 수가 많은 웹 사이트의 경우 전체 성능을 떨어뜨리는 원인이 된다. 성능문제를 해결하기 위해 사용하는 일반적인 방식으로 커넥션 풀 기법이 있는데, 이 글에서는 자카르타 프로젝트의 DBCP API를 이용하여 커넥션 풀을 사용하는 방법에 대해 살펴보도록 하겠다.

 

 

1. 커넥션 풀이란?

-- 커넥션 풀 기법이란, 데이터베이스와 연결된 커넥션을 미리 만들어서 풀(pool) 속에 저장해 두고 있다가 필요할 때에 커넥션을 풀에서 가져다 쓰고, 다시 풀에 반환하는 기법을 말한다.

 

[그림 1] 커넥션 풀 기법

 

풀 속에 데이터베이스와 연결된 커넥션을 미리 생성해 놓고 있다가, 커넥션이 필요할 경우 풀 속에 미리 생성되어 있는 커넥션을 가져다가 사용하고 다 사용한 커넥션은 다시 풀에 반환한다. 풀에 반환된 커넥션은 다음에 다시 사용된다.

 

◆ 커넥션 풀의 특징

-- 풀 속에 미리 커넥션이 생성되어 있기 때문에 커넥션을 생성하는데 드는 연결 시간이 소비되지 않는다.

-- 커넥션을 계속해서 재사용하기 때문에 생성되는 커넥션 수가 많지 않다.

 

커넥션을 생성하고 닫는데 필요한 시간이 소모되지 않기 때문에 그 만큼 어플리케이션의 실행 속도가 빨라지며, 또한 한번에 생성될 수 있는 커넥션 수를 제어하기 때문에 동시 접속자 수가 몰려도 웹 어플리케이션이 쉽게 다운되지 않는다. 커넥션 풀을 사용하면 전체적인 웹 어플리케이션의 성능 및 처리량이 높아지기 때문에 많은 웹 어플리케이션에서 커넥션 풀을 기본으로 사용하고 있다.

 

 

2. DBCP API의 사용 방법

자카르타 프로젝트의 DBCP API를 사용할 때에는 다음과 같은 과정을 거치면 된다.

 

① DBCP 관련 Jar 파일 및 JDBC 드라이버 Jar 파일 설치하기

② 커넥션 풀 관련 설정 파일 초기화하기

③ 커넥션 풀 관련 드라이버 로딩하기

④ 커넥션 풀로부터 커넥션 사용하기

 

이 네 가지 절차에 대해서 차례대로 살펴보도록 하자.

 

 

2.1 필요한 Jar 파일 복사

DBCP API를 사용하기 위해서는 다음과 같은 라이브러리가 필요하다.

 

- DBCP API 관련 Jar 파일                                                 DBCP 1.2.2        Download

- DBCP API가 사용하는 자카르타 Pool API의 Jar 파일              Pool 1.3           Download 

- Pool API가 사용하는 자카르타 Collection API의 Jar 파일        Collections 3.2  Download

 

이들 라이브러리의 최신 버전은 http://jakarta.apache.org/site/binindex.cgi 에서 다운로드 받을 수 있다.

파일의 압축을 풀면 다음과 같은 Jar 파일들을 발견할 수 있는데, 이들 Jar 파일들을 사용하면 된다.

 

- common-dbcp-1.2.2.jar

- common-pool-1.3.jar

- common-collections-3.2.jar

 

이 파일들을 WEB-INFlib 폴더에 복사해 넣는다.

 

 

2.2 설정 파일 작성하기

DBCP를 사용하는 방법에는 소스 코드 상에서 커넥션 풀을 설정하는 방법과 설정 파일을 통해서 커넥션 풀을 설정하는 방법 두 가지 존재하는데 여기서는 설정 파일을 이용한 커넥션 풀 설정 방법에 대해서 살펴보도록 하겠다.

 

DBCP Pool API에서 사용되는 커넥션 풀 설정 파일의 기본 골격은 다음과 같다.

 

[참고 1] WEB-INFclassespool1.jocl

---------------------------------------------------------------------------------------------------------------------------

01  <object class = "org.apache.common.dbcp.Poolable ConnectionFactory"

02             xmlns = "http://apache.org/xml/xmlsn/jakarta/commons/jocl">

03

04       // DBMS와 연결할 때 사용할 JDBC URL 및 사용자 계정, 암호

05       <object class = "org.apache.commons.dbcp.DriverManagerConnectionFactory">

06             <string value = "jdbc:mysql://localhost:3306/myRoot?.." />

07             <string value = "jspexam" />

08             <string value = "jspex" />

09       </object>

10

11       // 커넥션 풀과 관련된 추가 설정 정보 지정

12       <object class = "org.apache.commons.pool.implGenericObjectPool">

13             <object class = "org.apache.commons.pool.PoolableObjectFactory"  null="true" />

14       </object>

15

16       <object class = "org.apache.commons.pool.impl.GenericKeyedObjectPoolFactory"  null="true" />

17

18       // 커넥션이 유효한지의 여부를 검사할 때 사용할 쿼리. 쿼리를 지정하고 싶은 경우에는

19       // <string value = "SELECT count(*) FROM member" /> 와 같은 코드를 입력해 주면 된다.

20       <string null="true" />

21

22       // 커넥션을 읽기 전용으로 생성할지의 여부를 지정한다.

23       // insert, update, delete 작업이 있다면 false로 지정해 주어야 한다.

24       <boolean value="false" />

25

26       // 커넥션을 자동 커밋 모드로 설정할 경우 true를, 그렇지 않을 경우 false를 지정한다. 일반적으로 true를 사용한다.

27       <boolean value="true" />

28  </object>

---------------------------------------------------------------------------------------------------------------------------

 

[참고1] 설정 파일에서 나머지 부분은 그대로 입력하고 라인 05~09 부분만 알맞게 변경하면 된다.

 

05       <object class = "org.apache.commons.dbcp.DriverManagerConnectionFactory">

06             <string value = "jdbc:mysql://localhost:3306/myRoot?.." />

07             <string value = "jspexam" />

08             <string value = "jspex" />

09       </object>

 

위 코드에는 세 개의 <string> 태그가 사용되는데, 이들 태그는 각각 순서대로 JDBC URF, 데이터베이스 사용자 계정, 암호를 나타낸다. JDBC URL 부분의 값이 길어서 생략해서 표시했는데 다음과 같이 사용할 수 있다.

 

jdbc:mysql://localhost:3306/myRoot?useUnicode=true&amp;characterEncoding=euc-kr

 

*** NOTE

DBCP 커넥션 풀 설정 파일은 XML 문서로 처리된다. XML 문서에서는 엠퍼샌드 기호('&')를 표시할 때 &amp;를 사용해야 하기 때문에 JDBC URL 입력 부분에 useUnicode=true&characterEncoding 대신 useUnicode=true&amp;char...를 사용하였다.

 

하나의 설정 파일은 하나의 커넥션 풀에 해당한다. 새로운 커넥션 풀을 생성하고 싶다면 [참고 1]과 같은 파일을 하나 새롭게 생성하면 된다.

 

 

2.3 설정 파일의 위치

DBCP API는 클래스 패스로부터 설정 파일을 읽어 온다. 따라서 앞서 작성한 커넥션 풀 설정 파일은 클래스 패스에 위치해 있어야 한다. 웹 어플리케이션에서 DBCP API와 관련된 설정 파일의 위치로 가장 좋은 곳은 WEB-INFclasses 폴더이다.

 

 

2.4 커넥션 풀 초기화하기

DBCP API를 통해서 커넥션 풀을 사용하기 위해서는 커넥션 풀과 관련된 JDBC 드라이버를 로딩해 주어야 한다. DBCP API를 사용할 때에 로딩해 주어야 할 JDBC 드라이버는 다음과 같다.

 

- org.apache.commons.dbcp.PoolingDriver  -- DBCP API의 JDBC 드라이버

- DBMS에 연결될 때 사용될 JDBC 드라이버

 

DBCP API를 사용할 때에는 웹 어플리케이션 시작할 때 위에서 언급한 두 가지 형태의 JDBC 드라이버를 로딩하도록 하면 편리하다.

DBCP API와 관련된 JDBC 드라이버를 로딩하는 코드는 다음 [참고 2]와 같다.

 

[참고 2] WEB-INFjdbcdriverDBCPInit.java

---------------------------------------------------------------------------------------------------------------------------

01  package jdbcdriver;

02

03  import javax.servlet.http.HttpServlet;

04  import javax.servlet.ServletConfig;

05  import javax.servlet.ServletException;

06  import java.util.StringTockenizer;

07 

08  public class DBCPInit extends HttpServlet {

09

10       public void init (ServletConfig config) throws ServletException {

11            try {

12                 // DBMS와 연결할 때 사용될 JDBC 드라이버 로딩

13                 String drivers = config.getInitParameter("jdbcdriver");

14                 StringTockenizer st = new StringTokenizer(drivers, ",");

15                 while (st.hasMoreTokens()) {

16                      String jdbcDriver = st.nextToken();

17                      Class.forName(jdbcDriver);

18                 }

19

20                 // DBCP API에서 풀 기능을 제공하기 위해 사용되는 PoolingDriver 로딩

21                 Class.forName("org.apache.commons.dbcp.PoolingDriver");

22

23                 // 톰캣 5.0.19에서는 주석을 그대로 두어도 올바르게 실행되지만 톰캣 5.0.2x 버전부터는

24                 // 주석을 없애고 SAX 파서를 지정해 주어야 올바르게 실행된다.

25                 // System.setProperty("org.xml.sax.driver", "org.apache.crimson.parser.XMLReaderImpl");

26            } catch (Exception ex) {

27                 throw new ServletException(ex);

28            }

29       }

30  }

---------------------------------------------------------------------------------------------------------------------------

 

[컴파일]

C:>cd jakarta-tomcat-5.0.19webappsmyRootWEB-INF

C:..WEB-INF> set PATH=c:j2sdk1.4.2_04bin;%PATH%

C:..WEB-INF> set CLASSPATH=c:jakarta-tomcat-5.0.19commonlibservlet-api.jar;c:jakarta-tomcat-5.0.19commonlibjsp-api.jar;classes

C:..WEB-INF> javac -d classes jdbcdriverDBCPInit.java

 

컴파일에 성공하면 WEB-INFclassesjdbcdriver 폴더에 DBCPInit.class 파일이 생성될 것이다.

WEB-INFweb.xml 파일에 DBCPInit 서블릿 클래스에 대한 설정 정보를 추가함으로써 웹 어플리케이션이 시작될 때 DBCPInit 서블릿 클래스가 시작될 수 있도록 할 수 있다. 예를 들면, 아래와 같은 코드를 web.xml 파일에 추가해 주면 된다.

 

---------------------------------------------------------------------------------------------------------------------------

<servlet>

     <servlet-name>DBCPInit</servlet-name>

     <servlet-class>jdbcdriver.DBCPInit</servlet-class>

     <load-on-startup>1</load-on-startup>

     <init-param>

          <param-name>jdbcdriver</param-name>

          <param-value>com.mysql.jdbc.Driver</param-value>

     <init-param>

</servlet>

---------------------------------------------------------------------------------------------------------------------------

 

위와 같이 코드를 추가해 주면 웹 어플리케이션이 시작할 때 DBCPInit 서블릿 클래스가 자동으로 시작되고 init() 메소드가 호출된다.

 

 

2.5 커넥션 사용하기

커넥션 풀을 위한 JDBC 드라이버 및 DBMS에 연결할 때 사용할 JDBC 드라이버를 로딩하면 커넥션 풀로부터 커넥션을 가져와 사용할 수 있다. 커넥션 풀로부터 커넥션을 가져오는 코드는 별반 다르지 않으며, 다음과 같은 형태의 코드를 사용하면 된다.

Posted by 1010