Forest Gump?

HikariCP config 상태 확인하기 본문

카테고리 없음

HikariCP config 상태 확인하기

code1010 2023. 2. 19. 23:52

잘안쓰는 레거시 프로그램의 서버가 다운됐다는 소리를 듣고 급하게 repo를 받아서 실행했다.

거의 deprecated된 레거시 프로젝트라 급하게 환경 설정을 맞춘 후 프로젝트를 겨우 실행이 됐다.  gradle 설정이 자꾸 안먹혀서 다시 보니 , gradle.wrapper 폴더가 없어서 최신 환경으로 세팅이 되어 해당 의존성들과 버전 문제로 생각보다 시간 소모를 많이 했다. 환경 설정은 경험을 하면 할수록 조금은 더 빨라지는것 같다. 

 

로그를 보면 특정 메소드에 대한 api 요청이 오고 나서 장렬히 전사했다. 그밖에 다른곳에 문제는 없어 보여서 , 데이터 값에 버퍼가 많이 걸려 부하로 서버가 죽었겠거니 생각했다.  근데 왠걸, 실행을 하고 해당 api 요청을 날려보니 쎄한 느낌이 들었다. 

 

sending request

설마 쿼리 문제인가 생각이 들어, 쿼리 로그를 찍어봤더니 역시나 이런식으로  무한 반복이 되고 있었다.

 

3줄짜리지만 실제 로그는 300줄이 넘는 debug 결과가 server console에 찍혔다.

 

설령 이렇게 반복되어도 서버가 죽은것과 어떤 직접적인 관계일까 라고 계속 고민만 하는 와중에, db라면 hikari Connection Pool문제가 아닐까 불현듯 생각이 들었다. 

혹시나 하는 생각과 함께 구글링해서 hikari pool설정을 yml에 넣고 해당 cp를 조회 하도록 설정해봤다.

 

구글링 할때 application.properties 설정만 많고  yml 은 별로 안보여서 기록용으로 포스팅을 한다. 설정한 yml 파일 코드는 다음과 같다. 

 

 

logging.level.com.everon=DEBUG
logging.level.org.springframework.aop.interceptor=TRACE
logging.level.org.springframework.web.servlet.i18n=DEBUG
logging.level.com.zaxxer.hikari.HikariConfig=DEBUG
logging.level.com.zaxxer.hikari=TRACE
server.port=8080

 

 

설정하고 실행하자마자 WARN 으로 apparent connection leak detected을 찍어준다.

 

 

apparent connection leak detected

 

## Hikari specific settings
spring.datasource.hikari.leak-detection-threshold=30000

HikariPool-1 - Pool stats (total=30, active=1, idle=29, waiting=0)

HikariPool-1 - Pool stats (total=30, active=2, idle=28, waiting=0)

HikariPool-1 - Pool stats (total=30, active=3, idle=27, waiting=0)

HikariPool-1 - Pool stats (total=30, active=4, idle=26, waiting=0)

 

그리고 30초 간격으로 찍어봤는데, request 를 요청할때마다 cp가 하나씩 줄어드는것을 볼 수 있었다. 그래서 어떤 유저가 이 방법을 30번(cp 풀 설정한 max-size) 반복했을때 서버가 죽는 문제가 발생했던 것이다. 

 

유지보수가 잘 안되서 그런지, 프론트단에서 설정한 날짜 데이터가 request header에 빈값이 되어 날아오고, 백단 소스를 보니 null 값이 들어올때  queryDsl where 조건 없이 전체 검색하도록 되어 있었다. 

 

하지만 문제는, 많은 양의 데이터들을 루프 내에서 몇번이고 반복하며 비슷한 쿼리를 도는 코드로 구현되어 있었다.

 게다가 queryProjection를 생성자에 선언했지만 다른  qclass에 선언된 entity 전체를 불러오는 쿼리를 사용하고 있어

불필요한 캐싱 데이터들을 처리하는 코스트가 더 소모되고 있었다. 

 

이 예제는 완벽한 리팩토링 샘플이구나 생각이 들어 시간 날때마다 소스를 바꿔보려고 한다 .

각각의 요청 코스트를 비교해서 같은 데이터를 보내는 하나의 API에서 얼마나 리소스를 절약할 수 있는지 좋은 예제가 될 것 같다. 리팩토링이 완료되면 변경한 코드를 정리해봐야겠다.

 

추가 TODO : 문제는 api 요청도 전에 스프링 실행과 동시에 apparent connection leak detected 이 찍힌다 . 아직은 이유를 모르겠지만 더 찾아봐야 할것 같다.