커넥션 풀이란 db와 연결하는 커넥션을 미리 생성해두고 풀에 저장해두었다 필요할때 꺼내쓰고, 사용후에는 다시 풀에 반환하는 기법을 말한다.
(멀티쓰레드의 쓰레드풀과 유사하다.)
커넥션을 미리 생성해두기 때문에 커넥션을 사용자가 db를 사용할때마다 매번 생성을 하는것보다 더 빠른 속도를 보장한다.
또한 커넥션의 최대 생성 갯수도 제어해주기 때문에 많은 사용자가 몰려도 과부화를 방지할 수 있다.



커넥션 풀의 오픈소스에는 대표적으로 DBCP와 C3P0이 있는데 여기선 DBCP를 사용하였다. DBCP는 아파치 사이트에서 받을수 있는데, 그 외에 DBCP에서 사용한 Pool인 Commons Pool이 필요하고, 부가적으로 로그 기록에 사용되는 Commons Logging도 필요하다.
각각의 API는 아래 링크에서 받을 수 있다.



1. DBCPInit.java
package jdbc;

import java.sql.DriverManager;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import org.apache.commons.dbcp2.ConnectionFactory;
import org.apache.commons.dbcp2.DriverManagerConnectionFactory;
import org.apache.commons.dbcp2.PoolableConnection;
import org.apache.commons.dbcp2.PoolableConnectionFactory;
import org.apache.commons.dbcp2.PoolingDriver;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

public class DBCPInit extends HttpServlet {

    @Override
    public void init() throws ServletException {
            loadJDBCDriver();
            initConnectionPool();
    }
    private void loadJDBCDriver() {
        try {
            //커넥션 풀에서 사용할 jdbc 드라이버를 로딩
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException("fail to load JDBC Driver", ex);
        }
    }
    private void initConnectionPool() {
        try {
            String jdbcUrl = "jdbc:mysql://localhost:3306/chap14?" + "useUnicode=true&characterEncoding=utf8";
            String username = "phs1116";
            String pw = "1234";
            
            //커넥션팩토리 생성. 커넥션 팩토리는 새로운 커넥션을 생성할때 사용한다.
            ConnectionFactory connFactory = new DriverManagerConnectionFactory(jdbcUrl, username, pw);
            
            //DBCP가 커넥션 풀에 커넥션을 보관할때 사용하는 PoolableConnectionFactory 생성
            //실제로 내부적으로 커넥션을 담고있고 커넥션을 관리하는데 기능을 제공한다. ex)커넥션을 close하면 종료하지 않고 커넥션 풀에 반환
            PoolableConnectionFactory poolableConnFactory = new PoolableConnectionFactory(connFactory, null);
            //커넥션이 유효한지 확인할때 사용하는 쿼리를 설정한다.
            poolableConnFactory.setValidationQuery("select 1");
            
            
            //커넥션 풀의 설정 정보를 생성한다.
            GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
            //유휴 커넥션 검사 주기
            poolConfig.setTimeBetweenEvictionRunsMillis(1000L * 60L * 1L);
            //풀에 있는 커넥션이 유효한지 검사 유무 설정
            poolConfig.setTestWhileIdle(true);
            //커넥션 최소갯수 설정
            poolConfig.setMinIdle(4);
            //커넥션 최대 갯수 설정
            poolConfig.setMaxTotal(50);

            //커넥션 풀 생성. 인자로는 위에서 생성한  PoolabeConnectionFactory와 GenericObjectPoolConfig를 사용한다.
            GenericObjectPool<PoolableConnection> connectionPool = new GenericObjectPool<>(poolableConnFactory,
                    poolConfig);
            
            //PoolabeConnectionFactory에도 커넥션 풀을 연결
            poolableConnFactory.setPool(connectionPool);
            
            //커넥션 풀을 제공하는 jdbc 드라이버를 등록.
            Class.forName("org.apache.commons.dbcp2.PoolingDriver");
            
 
            PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");
            //위에서 커넥션 풀 드라이버에 생성한 커넥션 풀을 등룍한다. 이름은 cp이다.
            driver.registerPool("cp", connectionPool);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}


2. web.xml에 서블릿 실행 설정
    <servlet>
        <servlet-name>DBCPInit</servlet-name>
        <servlet-class>jdbc.DBCPInit</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>


3. 커넥션 사

String jdbcDriver = "jdbc:apache:commons:dbcp:cp";
...
conn = DriverManager.getConnection(jdbcDriver);

커넥션을 사용할땐 기존 db 주소가 아닌 커넥션 풀의 주소를 사용한다.


'JAVA > JSP,Servlet' 카테고리의 다른 글

JSP 모델1과 모델2, 그리고 MVC 패턴  (2) 2016.02.15

+ Recent posts