NameLock을 세팅하고 분산 락을 처리하려고 테스트하는데.. 테스트 코드가 자꾸 멈춘다
SQL Error: 0, SQLState: null
Connection is not available, request timed out after 30006ms.
뭐지...? 난 잘못 설정한 게 없는데, 혹시나 poolSize를 확인해보았다.
minimum-idle
maximum-pool-size
maxLifetime
이외에도 다양한 값이 있는데 여길 참조하자.
나의 경우 NamedLock을 사용하는데 다음과 같이 짜여 있다.
즉 한 기능을 처리하기 위해 한 쓰레드에서 Connection 을 2개 잡고 있다.
근데 나는 동시성 테스트를 하기 위해 10개 이상의 쓰레드를 동시에 실행하고 있고,
순간적으로 3개를 얻은 후, 추가 커넥션을 얻기위해 대기하는 쓰레드, 커넥션을 대기하지 못하고 큐에 쌓아있는 쓰레드의 상태로 timeOut 상태까지 동작이 안하는 것이 었다..
그럼 대체 커넥션은 몇개를 설정해야 할까?
나랑 같은 상황을 겪으신 분이 이것에 대한 해답을 주었다.
HikariCP팀은 아래와 같은 DBCP 최소 사이즈 공식을 제안하였는데 다음과 같다.
필요한 풀사이즈 = 스레드 수 * (하나의 작업에 필요한 커넥션 수 - 1) + 1(교착상태를 피하기 위한 여유 공간)
나의 코드는 10개 이상의 클라이언트가 동시에 수행하고, 네임드락을 사용하면
네임드락의 락을 걸기 위한 커넥션, 이외 추가 커넥션이 1개 더필요하므로
즉 나의 경우, 10 * (2 - 1) + 1 = 총 11개이면 정상 동작한다는 것이다.
테스트 결과, 이제 정상 동작한다.
다만 이 공식은 실무에서는 그대로 적용해서는 안된다. 실무에서는 예상한 인원만큼 안들어오고 수많은 쿼리가 돌고있기 때문에 커넥션이 내 의도대로 사용되지 않으므로 항상 꾸준한 테스트와 모니터링을 위해 커넥션 수를 유지해야겠다.
우아한 형제들에서 HikariCP 데드락 케이스가 있는데 나중에 꼭 읽어보도록 해야겠다.
https://techblog.woowahan.com/2663/
참조한 책 및 사이트
https://velog.io/@hhg1993/%EC%A0%81%EC%A0%88%ED%95%9C-ConnectionPool-%EC%84%A4%EC%A0%95%EC%9D%98-%EC%A4%91%EC%9A%94%EC%84%B1