일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- html
- reactor
- reactive
- r
- 네트워크
- mybatis
- network
- github
- Heap
- javascript
- mongodb
- spring
- libuv
- effective
- VCS
- AWS
- 데이터통신
- socket
- redis
- NoSQL
- HTTP
- ajax
- Elk
- cache
- nodejs
- Static
- Lombok
- Linux
- git
- Java
- Today
- Total
빨간색코딩
Commons DBCP2 (dbcp 정의, 커넥션 속성, Evictor, 트랜잭션, Statements Pool, 예제) 본문
Commons DBCP2 (dbcp 정의, 커넥션 속성, Evictor, 트랜잭션, Statements Pool, 예제)
빨간색소년 2018. 4. 11. 16:48참조문서
- http://d2.naver.com/helloworld/5102792
- https://www.holaxprogramming.com/2013/01/10/devops-how-to-manage-dbcp/
1. DBCP 란?
Database Connection Pool 의 약자이다. 요청이 올때마다 Connection 객체를 얻는 것이 아닌, 미리 일정 갯수 찍어내서 Connection Pool 로 관리하는 것이다. DBCP를 사용치 않으면 아래와 같은 과정을 거친다.
- DB 서버 접속을 위해 JDBC 드라이버를 로드한다.
- DB 접속 정보와 DriverManager.getConnection() Method를 통해 DB Connection 객체를 얻는다.
- Connection 객체로 부터 쿼리를 수행하기 위한 PreparedStatement 객체를 받는다.
- executeQuery를 수행하여 그 결과로 ResultSet 객체를 받아서 데이터를 처리한다.
- 처리가 완료되면 처리에 사용된 리소스들을 close하여 반환한다.
하지만, DBCP 를 사용하면
- WAS가 실행되면서 미리 일정량의 DB Connection 객체를 생성하고 Pool 이라는 공간에 저장해 둔다.
- HTTP 요청에 따라 필요할 때 Pool에서 Connection 객체를 가져다 쓰고 반환한다.
이와 같은 방식으로 HTTP 요청 마다 DB Driver를 로드하고 물리적인 연결에 의한 Connection 객체를 생성하는 비용이 줄어들게 된다.
2. Commons 의 DBCP
apache commons DBCP 는 커넥션 풀 구현체 오픈소스 중 가장 많이 쓰인다. 여기서는 현재 기준 최신버전인 Commons DBCP 2.2 를 기준으로 다뤄보자.
2-1. Commons DBCP 버전
현재 기준으로 dbcp 홈페이지에 가보면 Last Published: 27 December 2017 | Version: 2.2.0 라고 되어있다. dbcp2 는 Commons Pool2 를 기반으로 하며, 1.x보다 성능이 좋아졌다고한다. 또한 JMX(Java Management eXtensions)를 지원한다.
Commons DBCP 버전 | JDK 버전 | JDBC 버전 |
---|---|---|
2.x | 7 | 4.1 |
1.4 | 6 | 4 |
1.3 이하 | 1.4 ~ 1.5 | 3 |
maven 설정
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.2.0</version>
</dependency>
2-2. 커넥션에 관련된 속성들
아래 속성에서 1~4번 속성은 통일해도 무방하다. 여기서 커넥션은 java.sql.Connection 이다.
- initialSize : 최초 시점에 getConnection() 를 통해 커넥션 풀에 채워 넣을 커넥션 개수 (default = 0)
- maxTotal (1.x에서는 maxActive): 동시에 사용할 수 있는 최대 커넥션 개수 (default = 8)
- maxIdle : Connection Pool에 반납할 때 최대로 유지될 수 있는 커넥션 개수 (default = 8)
- minIdle : 최소한으로 유지할 커넥션 개수 (default = 0)
- maxWaitMillis (1.x에서는 maxWait) : pool이 고갈되었을 경우 최대 대기 시간 (ms단위, default = -1 = 무한정)
- 이걸 설정하지 않았는데, pool이 고갈되었고, 엔드유저의 요청은 계속 들어온다면?
- tomcat 스레드 풀이 고갈되어 죽는다. 엔드유저 요청마다 무한정 대기중일 테니...
2-3. 커넥션의 검사와 정리에 관련된 속성들
- validationQuery : 풀에 커넥션을 반환하기 전이나, 풀을 획득하기 전에 커넥션이 valid한지를 검사, mysql 기준으로 보통 select 1 설정
- validationQueryTimeout
- testOnCreate
- testOnBorrow : 커넥션 풀에서 커넥션을 얻어올 때 테스트 실행 (default = true)
- testOnReturn : 커넥션 풀로 커넥션을 반환할 때 테스트 실행 (default = false)
- testWhileIdle : Evictor 가 실행될 때 커넥션 풀 안에 있는 유휴 상태의 커넥션을 대상으로 테스트 실행 (default = false)
- maxConnLifetimeMillis : 커넥션의 최대 라이프타임을 지정 (default = -1)
- logExpiredConnections : 로그로 maxConnLifetimeMillis를 초과한 경우에 커넥션이 닫혔음을 남김 (default = true)
- connectionInitSqls
- lifo
2-4. Evictor 스레드와 관련된 속성
Evictor 스레드는 Commons DBCP 내부에서 커넥션 자원을 정리하는 구성 요소이며 별도의 스레드로 실행된다.
- timeBetweenEvictionRunsMillis : Evictor 가 동작하는 간격 (default = -1, 비활성화)
- numTestsPerEvictionRun : Evictor 동작 시 한 번에 검사할 커넥션의 개수 (default = 3)
- minEvictableIdleTimeMillis : Evictor 동작 시 커넥션의 유휴 시간을 확인해 설정 값 이상일 경우 커넥션을 제거 (ms단위, default = 30분) -1 로 설정할 경우 사용하지 않음. (권장)
- softMiniEvictableIdleTimeMillis : Evictor 가 커넥션을 제거하기 전에 minIdle 수 만큼의 커넥션은 남기도록 한다. 이때 설정값 시간만큼 존재한다. (default = -1)
2-5. 트랜잭션에 관련된 속성들
- defaultAutoCommit : true 이면 풀에 의해서 생성된 커넥션은 autocommit 된다. 커넥션이 종료되기 전에 commit 처리된다. (default = 드라이버기본값)
- defaultReadOnly : 풀에 의해서 생성된 커넥션의 read-only상태를 설정 (default = 드라이버기본값)
- defaultTransactionIsolation
- defaultCatalog : 풀에 생성된 커넥션의 기본 카탈로그를 설정
- cacheState
- defaultQueryTimeout
- enableAutocommitOnReturn
- rollbackOnReturn
2-6. PreparedStatements Pool 에 관련된 속성들
- poolPreparedStatements : statement 풀링여부 설정 (default = false)
- maxOpenPreparedStatements : 커넥션 당 최대 pooling 할 PreparedStatement 의 갯수를 설정 (default = 무한정, 무한정일 경우 OOM 발생할 수 있음)
3. DataSource
JDBC API 를 이용하여 DB 연동을 처리하려면 DB로부터 커넥션을 얻어야 한다. 따라서 DB정보를 bean으로 등록하여 스프링 컨테이너가 생성하도록 해야한다. 이렇게 생성된 bean은 트랜잭션, mybatis, jpa 등등 범용적으로 사용될 수 있다.
4. 예제 설정
<!-- DataSource 설정 -->
<bean id="sampleDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.sample.driverClassName}"/>
<property name="url" value="${jdbc.sample.url}${jdbc.sample.connectionProperties}"/>
<property name="username" value="${jdbc.sample.username}"/>
<property name="password" value="${jdbc.sample.password}"/>
<!-- 4개의 설정은 동일하게 설정하는 것이 예외 케이스를 줄일 수 있음 -->
<property name="initialSize" value="20"/>
<property name="maxTotal" value="20"/>
<property name="maxIdle" value="20"/>
<property name="minIdle" value="20"/>
<property name="defaultReadOnly" value="true"/>
<!-- pool이 고갈되었을 경우 최대 대기 타임 ms -->
<property name="maxWaitMillis" value="3000"/>
<property name="validationQuery" value="SELECT 1"/>
<!-- Evictor 설정 -->
<property name="testOnBorrow" value="false"/>
<property name="testOnReturn" value="false"/>
<!-- testWhileIdle 설정. 150초마다 4개의 connection 꺼내 validation query를 날려 확인 -->
<property name="testWhileIdle" value="true"/>
<property name="timeBetweenEvictionRunsMillis" value="150000"/>
<property name="numTestsPerEvictionRun" value="4"/>
<property name="minEvictableIdleTimeMillis" value="-1"/>
<!-- preparedStatement 풀링 여부 -->
<property name="poolPreparedStatements" value="true"/>
<property name="maxOpenPreparedStatements" value="50"/>
</bean>
'database' 카테고리의 다른 글
Kafka 기본 개념 (토픽, 파티션, 성능, 고가용성, 프로듀서, 컨슈머) (1) | 2021.07.11 |
---|---|
Redis 기본 개념 (기초, Collection 타입, Expire, Persistence) (2) | 2020.06.25 |
CentOS 7에 MongoDB 설치 (0) | 2017.08.04 |
MongoDB 명령어 (database, collection, document, query, cursor, index) (1) | 2017.08.04 |
MongoDB (RDB와 비교, 특징과 장단점, 메모리성능 이슈, 주요용어) (3) | 2017.07.26 |