반응형
해당 글에서는 Spring Boot JPA 환경에서 HikariCP를 적용하는 방법에 대해 알아봅니다.
💡 [참고] 퍼시스턴스 프레임워크로 MyBatis를 이용하여 설정을 하는 경우 아래의 글을 참고하시면 도움이 됩니다.
1) 개발 환경
💡 해당 글에서는 Spring Boot 내에서 HikariCP를 사용하기 위해 구성한 개발 환경입니다.
- 해당 환경에서는 추가적으로 QueryDSL을 사용하였습니다
개발환경 | 버전 |
java | 17 |
Spring Boot | 3.3.1 |
빌드관리도구 | Gradle 8.8 |
개발 툴 | IntelliJ IDEA 2024.1 |
spring-boot-starter-data-jpa | 3.3.1 |
spring-boot-starter-jdbc | 3.3.1 |
spring-boot-starter-data-jdbc | 2.7.4 |
com.mysql:mysql-connector-j | 8.4.0 |
com.querydsl:querydsl-jpa | 5.1.0 |
com.querydsl:querydsl-apt | 5.1.0 |
jakarta.annotation:jakarta.annotation-api | 2.1.0 |
jakarta.persistence:jakarta.persistence-api | 3.1.0 |
2) HikariCP, DBCP(DataBase Connection Pool)
1. HikariCP
💡 HiKari
- Hi·ka·ri [hi·ka·'lē] ( 원산지: 일본어 ): 빛;이라는 의미입니다.
💡 HiKariCP(Hikari Connection Pool
- 데이터베이스 연결(Connection)을 관리해 주는 도구(라이브러리)입니다. 이는 커넥션 풀(Connection Pool)이 설정된 커넥션의 사이즈만큼의 연결을 허용하며 HTTP 요청에 대해 순차적으로 DB 커넥션을 처리해 주는 기능을 수행합니다.
- DBCP(Database Connection Pool)이며 HikariCP, Common DBCP 등 라이브러리가 존재하는데 가볍고 빠르게 처리할 수 있다는 장점이 있는 HikariCP를 사용합니다.
- 빠르고, 간단하고 믿을 수 있는 HikariCP는 "오버헤드 제로"의 프로덕션 지원 JDBC 연결 풀입니다. 대략 130KB이며 이 라이브러리는 매우 가볍습니다.
2. 데이터베이스 커넥션 풀 (DBCP: Database Connection Pool)
2.1. JDBC(Java DataBase Connetion) 과정
💡 JDBC(Java DataBase Connetion) 과정
- JDBC 연결은 드라이버를 로드하고 연결하여 객체를 받아와야 하는 과정을 가지고 있습니다. 이 과정은 매번 사용자가 요청할 때마다 드라이버를 로드하고 커넥션 객체를 생성하여 연결하고 종료하는 과정이 불편하고 속도와 자원 소모에 대한 단점이 있었습니다.
- 그래서 이 단점을 보완하기 위해 ‘데이터 베이스 커넥션 풀(DBCP)’을 사용합니다
2.2. DBCP(Database Connection Pool) 이해 및 처리 과정
💡 DBCP(Database Connection Pool) 이해
- 데이터베이스 커넥션 풀은 최초 Pool 내에서 연결(Connection)들을 하여 HTTP 요청에 따라 응답을 제공하고 반환받아서 이를 재 사용하는 것을 의미합니다.
💡 DBCP(Database Connection Pool)의 처리과정
1. 애플리케이션이 실행되면서 Pool 내에 Connection들을 생성해 둡니다.
2. HTTP의 요청이 올 때 Pool 내에서 Connection 객체를 가져다가 사용합니다.
3. 사용이 완료된 Connection 객체는 Pool 내에 반환합니다.
2.3. DBCP의 장점
💡 DBCP의 장점
1. 애플리케이션과 데이터 베이스와의 연결(Connection)을 줄여서 비용을 줄입니다.
2. 'Pool'내에 미리 연결(Connection)되어 있기에 매번 생성하는 비용을 줄일 수 있습니다.
3. 연결(Connection)에 대해서 조정을 할 수 있습니다. (단, 인프라의 DB Connection 수와 맞추어야 합니다.
-Connection Pool을 크게 설정하면 메모리 소모가 큰 대신 많은 사람의 대기시간이 줄어듭니다.
- Coonection Pool을 적게 설정하면 사용자의 대기시간이 길어집니다.
2.4. HikariCP Benchmark
💡 HikariCP Benchmark
- 해당 이미지는 JDBC와 HikariCP 간의 밴치마크를 수행한 결과입니다.
- Connection Cycle ops/ms는 DataSource.getConnection(), Connection.close()에 대한 DB 연결과 연결해제를 비교 측정한 내용입니다.
- Statement Cycle ops/ms는 Connection.prepareStatement(), Statement.execute(), Statement.close() 데이터 베이스의 상태로 준비 > 수행 > 종료 단계를 비교 측정한 내용입니다
[ 더 알아보기 ]
💡 벤치마크(benchmark)
- 컴퓨팅에서 특정 오브젝트(하드웨어 또는 소프트웨어 등)에 대해 일반적으로 수많은 표준 테스트와 시도를 수행함으로써 오브젝트의 상대적인 성능 측정을 목적으로 컴퓨터 프로그램을 실행하는 행위입니다.
3) 환경 설정하기
💡환경 설정하기
- 기존의 JDBC로 연결된 MySQL을 DBCP의 HikariCP로 변경하는 과정을 설정합니다.
1. 라이브러리 추가 : build.gradle
💡 라이브러리 추가 : build.gradle
- 주요 라이브러리로 spring-boot-starter-data-jpa와 spring-boot-starter-jdbc를 추가하였습니다.
- 이외에는 QueryDSL 설정이니 JPA & Hibernate를 이용하는 경우에는 두 개의 설정만 추가하시면 됩니다.
// 프로젝트에서 사용하는 전역 변수를 설정
ext {
set('queryDslVersion', "5.1.0")
set('springBootVersion', "3.3.1")
}
dependencies {
implementation "com.querydsl:querydsl-jpa:${queryDslVersion}:jakarta"
annotationProcessor "com.querydsl:querydsl-apt:${queryDslVersion}:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api:2.1.1"
annotationProcessor "jakarta.persistence:jakarta.persistence-api:3.1.0"
implementation "org.springframework.boot:spring-boot-starter-web:${springBootVersion}" // Spring Boot Web
implementation "org.springframework.boot:spring-boot-starter-data-jpa:${springBootVersion}" // Spring Boot JPA
implementation "org.springframework.boot:spring-boot-starter-jdbc:${springBootVersion}" // Spring Boot JDBC
implementation 'com.mysql:mysql-connector-j:8.4.0' // MySQL Connection
}
2. application.properties(yml)
💡 application.properties(yml)
- datasource 내에 hikari 속성으로 각각 연결정보를 추가하였습니다.
spring:
datasource:
hikari:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://127.0.0.1:3306/multiflex_scma
username: localmaster
password: qwer1234
pool-name: Hikari Connection Pool # Pool Name Alias
maximum-pool-size: 3
jpa:
database: mysql
open-in-view: false
generate-ddl: true
hibernate:
ddl-auto: create # or create, update, create-drop, validate
properties:
hibernate:
show_sql: true
format_sql: true
use_sql_comments: true
generate_statistics: true
💡 [참고] 해당 설정파일에서 사용한 속성들에 대한 설명
속성 | 설명 |
spring.datasource.hikari.driver-class-name | 사용할 JDBC 드라이버 클래스의 이름을 지정합니다. |
spring.datasource.hikari.jdbc-url | 데이터베이스에 연결할 JDBC URL을 지정합니다. |
spring.datasource.hikari.username | 데이터베이스에 접속할 때 사용할 사용자 이름을 지정합니다. |
spring.datasource.hikari.password | 데이터베이스에 접속할 때 사용할 비밀번호를 지정합니다. |
spring.datasource.hikari.pool-name | HikariCP 커넥션 풀의 이름을 지정합니다. |
spring.datasource.hikari.maximum-pool-size | HikariCP 커넥션 풀에서 유지할 최대 커넥션 수를 지정합니다. |
spring.jpa.database | 사용할 데이터베이스 유형을 지정합니다. |
spring.jpa.open-in-view | JPA 엔티티를 뷰에서 열어 둘지 여부를 지정합니다. |
spring.jpa.generate-ddl | JPA가 데이터베이스 DDL을 생성할지 여부를 지정합니다. |
spring.jpa.hibernate.ddl-auto | Hibernate가 DDL을 자동으로 생성, 업데이트, 삭제할지 여부를 지정합니다. |
spring.jpa.properties.hibernate.show_sql | 실행된 SQL 쿼리를 출력할지 여부를 지정합니다. |
spring.jpa.properties.hibernate.format_sql | 출력된 SQL 쿼리를 형식화할지 여부를 지정합니다. |
spring.jpa.properties.hibernate.use_sql_comments | SQL 쿼리에 주석을 추가할지 여부를 지정합니다. |
spring.jpa.properties.hibernate.generate_statistics | Hibernate 통계 정보를 생성할지 여부를 지정합니다. |
3. DataSourceConfig.java
💡 DataSourceConfig.java
- 해당 클래스에서는 JPA와 HikariCP간의 연결을 설정하는 환경 클래스입니다.
1. DataSourceConfig
- @Configuration 어노테이션을 통해 HikariCP의 설정을 담당합니다.
- @ConfigurationProperties(prefix = "spring.datasource.hikari") 어노테이션을 통해서 application.properties의 속성 값을 가져와서 객체와 바인딩을 수행합니다.
2. hikariConfig
- @ConfigurationProperties(prefix = "spring.datasource.hikari") 어노테이션을 통해서 application.properties의 속성 값을 가져와서 객체와 바인딩을 수행합니다.
- 클래스 내의 추가 설정이 필요한 경우 해당 생성한 객체 내에 setXX 메서드를 통해서 속성을 수정합니다.
3. dataSource()
- HikariConfig 객체를 통해 설정된 hikariConfig 객체 정보를 가져와서 데이터베이스 연결 풀을 설정합니다.
package com.adjh.multiflex.config;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
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 javax.sql.DataSource;
/**
* Spring Boot 애플리케이션에서 HikariCP를 사용하여 데이터베이스 연결 풀을 설정하고 관리하는 역할을 합니다.
*
* @author : lee
* @fileName : DataSourceConfig
* @since : 24. 7. 18.
*/
@Configuration
// application.properties 파일을 소스 경로에서 불러와 사용할 수 있도록 합니다.
@PropertySource("classpath:/application.properties")
public class DataSourceConfig {
final ApplicationContext applicationContext;
public DataSourceConfig(ApplicationContext ac) {
this.applicationContext = ac;
}
/**
* spring.datasource.hikari 설정을 HikariConfig 객체에 바인딩합니다.
*
* @return {HikariConfig}
*/
@Bean
@ConfigurationProperties(prefix = "spring.datasource.hikari")
public HikariConfig hikariConfig() {
HikariConfig hikariConfig = new HikariConfig();
// [참고] 소스코드 내에서 수정이 필요한 경우 이를 이용합니다.
// hikariConfig.setDriverClassName("com.mysql.cj.jdbc.Driver");
// hikariConfig.setJdbcUrl("jdbc:mysql://localhost:3306/multiflex");
// hikariConfig.setUsername("root");
// hikariConfig.setPassword("root");
// hikariConfig.setAutoCommit(true);
// hikariConfig.setMaximumPoolSize(5);
// hikariConfig.setMinimumIdle(1);
// hikariConfig.setConnectionTestQuery("SELECT 1");
// hikariConfig.addDataSourceProperty("useUnicode", "true");
return hikariConfig;
}
/**
* hikari의 설정정보를 받아서 HikariDataSource 객체로 생성하고 반환합니다.
*
* @return {DataSource}
*/
@Bean
public DataSource dataSource() {
HikariDataSource dataSource = new HikariDataSource(hikariConfig());
return dataSource;
}
}
[ 더 알아보기 ]
💡 위에 메서드들은 application.properties 파일 내에 있는 속성들을 가져오는데 추가적으로 속성을 지정할 필요가 없지 않은가?
- 위에 메서드들은 application.properties 파일 내에 있는 속성들을 가져오므로, 일반적으로 추가적인 속성을 지정할 필요는 없습니다. 그러나 특정한 상황에서는 추가적인 커스터마이징이 필요할 수도 있습니다.
- 예를 들어, 기본 설정 외에 추가적인 설정이 필요하거나, 특정 상황에 맞게 설정을 조정해야 할 때는 메서드 내에서 속성을 지정할 수 있습니다. 그렇지 않다면, application.properties 파일에 정의된 속성들만으로 충분히 설정이 가능합니다.
4) 수행 결과
1. 서버 실행 시 확인
💡 서버 실행 시 확인
- 설정을 마친 뒤 서버를 실행하였을때 Hikari Connection Pool이 시작됨을 확인하였습니다.
2. Logging을 속성을 추가하여 Connection Pool 확인
💡 Logging을 속성을 추가하여 Connection Pool 확인
- logging.level.com.zaxxer.hikari.pool.HikariPool 속성을 debug로 지정하였습니다.
- 로컬 서버를 실행한 후에 Hikari Connection Pool이 시작이 되고 지정한 3개의 Connection이 생성됨을 확인하였습니다.
spring:
datasource:
hikari:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://127.0.0.1:3306/multiflex_scma
username: localmaster
password: qwer1234
pool-name: Hikari Connection Pool # Pool Name Alias
maximum-pool-size: 3
jpa:
database: mysql
open-in-view: false
generate-ddl: true
hibernate:
ddl-auto: create # or create, update, create-drop, validate
properties:
hibernate:
show_sql: true
format_sql: true
use_sql_comments: true
generate_statistics: true
# HikariPool에 대한 로깅을 수행함
logging:
level:
com.zaxxer.hikari.pool.HikariPool: debug
3. 참고 수행 사항
💡 MySQL 내에서 활성화된 Pool의 정보를 확인하는 방법
SELECT *
FROM information_schema.processlist
WHERE db = 'DB Name';
💡 MySQL 내에서 실제 Connection 수를 확인하는 방법
SELECT COUNT(*)
FROM information_schema.processlist
WHERE db = 'DB Name';
오늘도 감사합니다😀
반응형