커넥션 풀을 설정해주지 않아서 데이터베이스 서버의 접속이 제한됐던 적이 있다.
connection pool을 사용하면 DB Connection 수를 제한할 수 있어서 과도한 접속으로 인한 서버 자원 고갈을 예방할 수 있다
DB Connection
- DB를 사용하기 위해 DB와 애플리케이션 간 통신을 할 수 있는 수단
- DB Connection은 Database Driver와 Database 연결 정보를 담은 URL이 필요함
- Java의 DB Connection은 JDBC를 주로 이용하는데, URL 타입을 사용함
JDBC의 실행구조
- DB 벤더에 맞는 드라이버 로드
- DB 서버의 IP, ID, PW 등을 DriverManager 클래스의 getConnection() 메소드를 사용하여 Connection 객체 생성
- Connection에서 PreparedStatement 객체를 받음
- executeQuery를 수행하고 ResultSet 객체를 받아 데이터를 처리
- 사용하였던 ResultSet, PreparedStatement, Connection을 close
* 이 때, getConnection()은 자바 프로그램과 실제 데이터베이스를 네트워크 상으로 연결해준다. 연결에 성공하면 DB와의 연결 상태를 Connection 객체로 표현하여 반환한다.-> 이 과정이 가장 부하가 많이 걸리는 작업이다.
Connection Pool
- 웹 컨테이너(WAS)가 실행되면서 일정량의 Connection 객체를 미리 만들어서 pool에 저장했다가, 클라이언트 요청이 오면 Connection 객체를 빌려주고 해당 객체의 임무가 완료되면 다시 Connection 객체를 반납 받아서 pool에 저장하는 프로그래밍 기법이다.
- Container 구동 시 일정 수의 Connection 객체를 생성하게 되며 클라이언트의 요청에 의해 애플리케이션이 DBMS 작업을 수행해야 하면, Connection Pool에서 Connection 객체를 받아와 작업을 진행한다. 이후 작업이 끝나면 Connetion Pool에 Connection 객체를 반납한다.
Connection Pool 장점
- DB 접속 설정 객체를 미리 만들어 연결하여 메모리 상에 등록해 놓기 때문에 불필요한 작업(커넥션 생성, 삭제)이 사라지므로 클라이언트가 빠르게 DB에 접속이 가능하다.
- DB Connection 수를 제한할 수 있어서 과도한 접속으로 인한 서버 자원 고갈 방지가 가능하다.
- DB 접속 모듈을 공통화하여 DB 서버의 환경이 바뀔 경우 쉬운 유지 보수가 가능하다.
- 연결이 끝난 Connection을 재사용함으로써 새로 객체를 만드는 비용을 줄일 수 있다.
Connection Pool 유의사항
동시 접속자가 많을 경우
너무 많은 DB 접근이 발생할 경우에는 커넥션은 한정되어 있기 때문에 쓸 수 있는 커넥션이 발납될 때까지 기다려야 한다. 너무 많은 커넥션을 생성할 시에는 커넥션 또한 객체이므로 많은 메모리를 차지하게 되고, 프로그램의 성능을 떨어뜨리는 원인이 된다.
즉, WAS에서 커넥션 풀을 크게 설정하면 메모리 소모가 큰 대신 많은 사용자가 대기 시간이 줄어 들고, 반대로 커넥션 풀을 작게 설정하면 그 만큼 대기 시간이 길어진다. 따라서 사용량에 따라 적정량의 커넥션 객체를 생성해 두어야 한다.
* connection의 주체는 thread이다.
[Spring] Connection Pool 설정
1. maven dependency
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.8.0</version>
</dependency>
2. DataSourceConfig 설정
@Slf4j
@Configuration
@RequiredArgsConstructor
public class DataSourceConfig {
private final DbProperties dbProperties;
private final KeyManager keyManager;
@Bean
public DataSource dataSource() {
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setDriverClassName(keyManager.keyStore(dbProperties.getDriver()));
basicDataSource.setUrl(keyManager.keyStore(dbProperties.getUrl()));
basicDataSource.setUsername(keyManager.keyStore(dbProperties.getUsername()));
basicDataSource.setPassword(keyManager.keyStore(dbProperties.getPassword()));
basicDataSource.setInitialSize(dbProperties.getInitialSize());
basicDataSource.setMaxTotal(dbProperties.getMaxTotal());
basicDataSource.setMaxIdle(dbProperties.getMaxIdle());
basicDataSource.setMinIdle(dbProperties.getMinIdle());
basicDataSource.setTestOnBorrow(true);
basicDataSource.setValidationQuery("SELECT 1");
basicDataSource.setMaxWaitMillis(dbProperties.getMaxWait());
return basicDataSource;
}
}
3. DbProperties 설정
@Getter
@Setter
@ConfigurationProperties(prefix = "leather.mysql")
public class DbProperties {
private String driver;
private String url;
private String username;
private String password;
private Integer initialSize;
private Integer maxTotal;
private Integer maxIdle;
private Integer minIdle;
private Long maxWait;
}
- application.properties 설정
3. key manager 설정
'Spring' 카테고리의 다른 글
[Spring] Spring Security 동작 원리 (1) | 2024.07.01 |
---|---|
[Spring] POJO, Java Bean, Spring Bean (0) | 2024.06.01 |
Thymeleaf - layout 구조 나누기 (0) | 2024.05.01 |
요청 DTO의 기본 설정과 이유 (4) | 2024.04.28 |
AWS RDS(mySql) 프리티어 생성하기 (0) | 2024.04.22 |