-
[Camel][JSP] Connection Pool (커넥션 풀) with DBCPJSP 2020. 3. 16. 22:26
1. Connection Pool(커넥션 풀)이란?
JSP 페이지를 실행할 때마다 Connection을 생성하고 닫는다면 시간적 비용이 많이 들기 때문에 접속자 수가 많은 웹 사이트의 경우 성능 저하가 발생할 수 있습니다. 이러한 성능 저하를 막기 위해서 커넥션 풀이라는 것이 사용됩니다.
커넥션 풀은 데이터베이스와 연결된 Connection을 미리 생성한 뒤 Pool이라는 곳에 저장해 두고, 필요할 때마다 꺼내서 사용한 뒤 사용이 끝나면 다시 Pool에 반환하는 기법입니다. 즉, 데이터베이스의 커넥션이 필요할 때 커넥션을 새로 생성하는 것이 아니기 때문에 생성을 위한 시간적 비용이 절감됩니다. 생성뿐만 아니라 커넥션의 종료를 위해 소모되는 시간도 절감할 수 있습니다.
이러한 특징은 한번에 생성될 수 있는 커넥션의 수를 제한하는 것이고, 이는 동시 접속자의 증가로 인한 웹페이지 다운을 완전하지는 않더라도 어느정도 방지할 수 있습니다.
2. DBCP (DataBase Connection Pool)
2-1. Connection Pool 라이브러리 다운로드 및 추가
DBCP API를 사용하기 위해서는 아래의 라이브러리가 필요합니다. Apache Commons 다운로드 페이지에서 다운받을 수 있습니다. 두 압축파일을 다운로드 받은 후 압축을 풀어보면 그 안에는 jar 형태의 파일이 있습니다. jar 파일을 WEB-INF/lib 디렉터리에 복사해서 넣어줍니다.
- commons-dbcp-버전-bin.zip
- commons-pool-버전-bin.zip
2-2. Connection Pool 설정 파일 작성
다음으로는 커넥션 풀 설정파일을 작성해야 합니다. 아래와 같이 커넥션 풀 설정파일을 작성하겠습니다.
ch2/WEB-INF/classes/pool.jocl
<object class="org.apache.commons.dbcp.PoolableConnectionFactory" xmlns="http://apache.org/xml/xmlns/jakarta/commons/jocl"> <object class="org.apache.commons.dbcp.DriverManagerConnectionFactory"> <string value="jdbc:mysql://localhost:3306/ch2?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&characterEncoding=utf8"/> <string value="camel"/> <string value="1234"/> </object> <object class="org.apache.commons.pool.impl.GenericObjectPool"> <object class="org.apache.commons.pool.PoolableObjectFactory" null="true" /> </object> <object class="org.apache.commons.pool.KeyedObjectPoolFactory" null="true"/> <string null="true"/> <boolean value="false"/> <boolean value="true"/> </object>
DBMS와 연결할때 사용할 JDBC URL과 사용자 계정, 패스워드를 지정해줍니다. 그리고 커넥션 풀과 관련된 추가 설정 정보 또한 지정해줬습니다.
<string null="true"/>는 커넥션의 유효 여부를 검사하기 위해 사용할 Query입니다. Query를 지정하고 싶다면 <string value="select count(*) from member"/>와 같이 지정할 수 있습니다.
처음 <boolean value="false"/>는 커넥션을 읽기 전용으로 생성할지 말지를 결정하는 부분입니다. false로 지정함으로써 insert, update, delete와 같은 작업을 수행할 수 있습니다.
두번째 <boolean value="true"/>는 커넥션 자동 commit 모드를 설정하는 부분입니다. true로 설정함으로써 자동 commit이 됩니다.
또한 한가지 주의할 점이 있다면 커넥션 설정 파일은 XML 문서로 처리되기 때문에 JDBC URL을 표현할 때 사용되는 '&' 기호 대신에 '&'를 사용한다는 점입니다.
2-3. Connection Pool 초기화
이제 커넥션 풀 설정파일까지 적절할 위치에 위치시켜 주었다면 커넥션 풀을 초기화해줘야 합니다. 커넥션 풀을 사용하기 위해서는 커넥션풀과 관련된 JDBC 드라이버를 로딩해줘야 합니다. 그러므로 아래의 두 드라이버를 로딩해줘야 합니다.
- DBMS에 연결할 때 사용될 JBDC 드라이버
- DBCP API의 JDBC 드라이버
웹 어플리케이션이 시작될 때 자동으로 DBMS JDBC 드라이버를 로딩하는 것처럼, DBCP API의 JDBC 드라이버 역시 웹 어플리케이션이 시작될 때 자동으로 로딩되도록 하는 것이 편리하다고 할 수 있습니다. JDBC 드라이버 로딩과 관련된 내용은 이전 포스팅을 참고하시면 되겠습니다.
2020/03/15 - [JSP] - [Camel][JSP] JDBC 프로그래밍 2부 in JSP
package jdbc.loader; import javax.servlet.http.HttpServlet; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import java.util.StringTokenizer; public class DBCPInit extends HttpServlet { public void init(ServletConfig config) throws ServletException { try { String drivers = config.getInitParameter("jdbcdriver"); StringTokenizer st = new StringTokenizer(drivers, ","); while (st.hasMoreTokens()) { String jdbcDriver = st.nextToken(); Class.forName(jdbcDriver); } Class.forName("org.apache.commons.dbcp.PoolingDriver"); } catch(Exception ex) { throw new ServletException(ex); } } }
이전 포스팅에서와 마찬가지로 WEP-INF/web.xml 파일에 DBCPInit 클래스에 대한 설정 정보를 추가해 줘야합니다. 그렇게 되면 이제 웹 어플리케이션이 시작될 때 DBCPInit 클래스가 시작되도록 할 수 있습니다.
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"> <servlet> <servlet-name>JDBCDriverLoader</servlet-name> <servlet-class>jdbc.loader.Loader</servlet-class> <init-param> <param-name>jdbcdriver</param-name> <param-value>com.mysql.jdbc.Driver</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet> <servlet-name>DBCPInit</servlet-name> <servlet-class>jdbc.loader.DBCPInit</servlet-class> <init-param> <param-name>jdbcdriver</param-name> <param-value>com.mysql.jdbc.Driver</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> </web-app>
2-4. Connection Pool의 Connection 사용
커넥션 풀을 생성하고 초기화 했다면 커넥션풀의 Connection을 이제 사용할 수 있습니다. 커넥션 풀의 Connection은 일반적인 Connection과 사용방법이 동일합니다.
하지만, 한가지 차이점이 있습니다. JDBC URL에서 차이가 있습니다. 일반 커넥션 풀을 사용할 경우 JDBC URL을 아래와 같은 형식으로 입력해줘야 합니다.
String jdbcDriver = "jdbc.apsche:commons:dbcp:/[pool이름]";
저의 경우는 pool.jocl 파일으로 설정한 커넥션 풀을 사용하기 때문에 아래와 같이 코드를 작성했습니다.
String jdbcDriver = "jdbc.apsche:commons:dbcp:/pool";
커넥션 풀에서 생성된 Connection의 close 메소드를 호출하면 일반 커넥션의 경우 커넥션이 종료되지만, 커넥션 풀의 Connection의 경우에는 커넥션 풀로 Connection을 반환합니다.
2-5. Connection Pool의 속성
앞서 작성했던 커넥션 풀 설정 파일인 pool.jocl 에서는 커넥션 풀의 속성을 아무것도 지정하지 않았었습니다. 하지만 DBCP의 커넥션 풀은 다양한 속성을 지정할 수 있으며 지정방법은 아래의 태그 사이에 커넥션 풀 속성 값을 지정해 주면 됩니다.
<object class="org.apache.commons.pool.impl.GenericObjectPool"> <object class="org.apache.commons.pool.PoolableObjectFactory" null="true" /> </object>
속성 값을 지정해 준 예제 코드는 아래와 같습니다.
pool2.jocl
<object class="org.apache.commons.pool.impl.GenericObjectPool"> <object class="org.apache.commons.pool.PoolableObjectFactory" null="true" /> <int value="10" /> <!-- maxActive --> <byte value="1" /> <!-- whenExhaustedAction --> <long value="10000" /> <!-- maxWait --> <int value="10" /> <!-- maxIdle --> <int value="3" /> <!-- minIdle --> <boolean value="true" /> <!-- testOnBorrow --> <boolean value="true" /> <!-- testOnReturn --> <long value="600000" /> <!-- timeBetweenEvctionRunsMillis --> <int value="5" /> <!-- numTestsPerEvictionRun --> <long value="3600000" /> <!-- minEvictableIdleTimeMillis --> <boolean value="true" /> <!-- testWhileIdle --> </object>
각 속성에 대한 설명은 아래의 표를 참고하기실 바랍니다.
속성 설명 maxActive 커넥션 풀의 최대 커넥션의 수. DMBS의 수용가능 수준에 맞게 지정해야 성능저하를 막을 수 있다. whenExhaustedAction 커넥션 풀에서 가져올 수 있는 커넥션이 없을 경우의 동작을 결정. maxWait whenExhaustedAction 속성의 값이 1이면 사용되는 대기시간. 음수 입력시 무한 대기. maxIdle 사용되지 않고 풀에 저장될 수 있는 최대 커넥션의 수. 음수일 경우 무한 minIdle 사용되지 않고 풀에 저장될 수 있는 최소 커넥션의 수. testOnBorrow true일 경우 커넥션 풀에 커넥션을 가져올 때 커넥션의 유효 여부 검사 testOnReturn true일 경우 커넥션 풀에 커넥션을 반환할 때 커넥션의 유효 여부 검사 timeBetweenEvctionRunsMillis 사용되지 않은 커넥션을 추출하는 쓰레드의 실행 주기를 지정. 양수일 때만 실행. numTestsPerEvictionRun 사용되지 않는 커넥션을 몇 개 검사할지 지정 minEvictableIdleTimeMillis 사용되지 않는 커넥션을 추출할 때 이 속성에서 지정한 시간 이상 비활성화 상태인 커넥션만 추출. 양수로 입력 되어야지만 이 속성으로 추출 가능. testWhileIdle true일 경우 비활성화 커넥션을 추출할 때 커넥션의 유효 여부를 검사한 후, 유효하지 않은 커넥션은 커넥션 풀에서 제거. 'JSP' 카테고리의 다른 글
[Camel][JSP] JSTL(표준 태그 라이브러리) 1부 - Core Tag(코어 태그) (0) 2020.03.21 [Camel][JSP] 표현 언어 ( Expression Language) (0) 2020.03.20 [Camel][JSP] JDBC 프로그래밍 2부 in JSP (0) 2020.03.15 [Camel][JSP] JDBC 프로그래밍 1부 in JSP (0) 2020.03.14 [Camel][JSP] MySQL JDBC 연동 in JSP, Java (0) 2020.03.14