코딩항해기
[SpringBoot] HikariCP 본문
HikariCP
HikariCP는 오버헤드 제로의 프로덕션 지원 JDBC 연결 풀(커넥션 풀 관리 프레임워크)이다. 데이터 베이스 연결(Connection)을 관리해주는 라이브러리로 커넥션 풀에 설정된 커넥션 사이즈만큼 연결을 허용해 요청에 대해 순차적으로 DB 커넥션을 처리해준다.
HikariCP는 DBCP(Database Connection Pool)를 관리하며, 여러 라이브러리가 있지만 가볍고 빠르게 처리할 수 있다는 장점을 가지고 있어 Spring Boot 2.0 이후 부터는 기본 옵션으로 채택하고 있다.
(Spring Boot 2.0 이전에는 tomcat-jdbc를 사용했다.)
JDBC (Java Database Connectivity)
데이터 베이스에 접속할 수 있도록 하는 JAVA API로 자료를 쿼리하거나 업데이트하는 방법을 제공한다.
DBCP (Database Connection Pool)
일반적인 데이터 연동에서 필요할 때마다 연결을 진행해 작업하는 비효율적인 방식을 해결한 것으로 미리 연결을 설정해두었다가 해당 상태를 이용해 빠르게 재 연결을 진행하는 것이다. 즉, 미리 데이터베이스와 연결시킨 상태를 유지하는 기술이다. (Connection Pool, CP)
*JAVA에서는 기본적으로 DataSource 인터페이스를 사용해 CP를 관리한다. 이 DataSource를 자동화된 기법으로 관리해주는 것이 tomcat-jdbc, HikariCP 등이다.
HikariCP 장점
HikariCP(이하 히카리)는 다른 커넥션풀 관리 프레임워크에 비해 월등한 성능을 가지고 있다.
이러한 성능이 가능한 이유는 커넥션 풀 관리 방법에 있는데 히카리는 Connection 객체를 한 번 Wrappring한 PoolEntry로 관리하며 이를 관리하는 ConcurrentBag이라는 구조체를 사용하고 있다. 이 ConcurrentBag을 통해 사용가능한 Connection을 리턴하도록 설계되어 있다.
이 과정에서 커넥션 생성을 요청한 스레드에 정보를 저장해두었다가 다음 접근 시에는 저장된 정보를 활용에 더욱 빠르게 Connection을 반환해줄 수 있어 속도에 상당한 이점을 가질 수 있는 것이다.
이때 설정이 잘못되면 Dead lock이 발생할 수 있으므로 주의해야한다.
(우아한 기술블로그 : https://techblog.woowahan.com/2664/)
환경설정
기존 라이브러리 spring-boot-data-jdbc 내에 HikariCP가 포함되어있다.
(gradle)
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
}
*build.gradle 파일
spring.datasource.hikari.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.hikari.jdbc-url=jdbc:oracle:thin:@//localhost:1521/XE
spring.datasource.hikari.username=계정명
spring.datasource.hikari.password=비밀번호
#Oracle
*application.properties
Spring Boot 2.0 이에서는 application.properties의 HikariCP의 설정을 자동으로 읽어들인다. (다만 관련한 다른 의존은 dependencies에 있어야한다.)
DBConfig 파일 생성
서버가 로드되는 시점에 히카리 환경설정을 해주는 과정으로 설저오가 함께 최초 데이터베이스 Connection을 수행한다.
package com.example.menbosa.mybatis;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.RequiredArgsConstructor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
@RequiredArgsConstructor
public class MyBatisConfig {
private final ApplicationContext applicationContext;
@Bean
@ConfigurationProperties(prefix = "spring.datasource.hikari")
public HikariConfig hikariConfig() {
return new HikariConfig();
}
@Bean
public DataSource dataSource() {
return new HikariDataSource(hikariConfig());
}
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource());
sqlSessionFactoryBean.setMapperLocations(applicationContext.getResources("classpath*:/mapper/**/*.xml"));
sqlSessionFactoryBean.setConfigLocation(applicationContext.getResource("classpath:/config/config.xml"));
sqlSessionFactoryBean.setTypeAliasesPackage("com.example.menbosa.dto");
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBean.getObject();
sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true);
sqlSessionFactory.getConfiguration().setJdbcTypeForNull((JdbcType.NULL));
return sqlSessionFactory;
}
}
예전에 히카리로 프로젝트할 때 한 설정인데, 환경설정을 참고한 블로그에서는 조금 다른 방식으로 연결하고 있어 해당 방식도 추가한다.
참고 블로그 : https://adjh54.tistory.com/73#3)%20%ED%99%98%EA%B2%BD%20%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0-1
application.properties
spring:
datasource:
hikari:
driver-class-name: org.postgresql.Driver
jdbc-url: jdbc:postgresql://localhost:8000/test_db
username: test
password: xxxxx
pool-name: Hikari Connection Pool # Pool Name Alias
maximum-pool-size: 20
DBConfig
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
@Configuration
@PropertySource("classpath:/application.properties")
public class DBConfig {
final
ApplicationContext applicationContext;
public DBConfig(ApplicationContext ac) {
this.applicationContext = ac;
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.hikari")
public HikariConfig hikariConfig() {
return new HikariConfig();
}
@Bean
public DataSource dataSource() {
return new HikariDataSource(hikariConfig());
}
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean session = new SqlSessionFactoryBean();
session.setDataSource(dataSource);
session.setMapperLocations(applicationContext.getResources("classpath:mapper/*.xml"));
session.setTypeAliasesPackage("com.test.testApi.model");
session.setConfigLocation(new PathMatchingResourcePatternResolver().getResource("classpath:mybatis/mybatis-config.xml"));
return session.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
'Spring' 카테고리의 다른 글
[Spring] MyBatis 컬럼명 DTO 필드명 불일치 설정 (0) | 2024.11.05 |
---|---|
[Spring] MyBatis (인텔리제이 Intellij) (2) | 2024.11.04 |
[Spring] JDBCTemplate : KeyHolder (0) | 2024.10.28 |
[Spring] 경로 메서드 기록 (ServletContext, request, System) (0) | 2024.10.22 |
[Spring] 파일 입출력 MultipartFile (0) | 2024.10.21 |