SSE 통신을 하기 위해서 백엔드 코드에서는 Spring framework에서 SSE 통신을 제공하는 SseEmitter API를 사용하여 구현할 수 있다.
에러 메세지는 다음과 같았다.
hikaripool connection is not available
에러 확인 후 해결을 위해 여러 방면으로 알아보았지만 해결이 어려웠다.
하지만 같은 팀원의 도움으로 해결할 수 있었다.
connection 관련 문제는 보통 아래의 에러 메시지와 함께 문제가 발생한다.
- org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction
- Unable to acquire JDBC Connection
- HikariPool-1 - Connection is not available, request timed out after 3005ms.
- o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: null
에러의 내용은 트랜잭션을 만드는데 실패했고, JDBC Connection을 획득할 수 없다. hikariPool에서 커넥션을 이용할 수 없고 요청 시간이 지났다는 의미이다.
종종 hikari pool 상태[active, idle, waiting]의 connection 수를 확인해야 하는 경우가 있다.
logging.level.com.zaxxer.hikari.HikariConfig: DEBUG
logging.level.com.zaxxer.hikari: TRACE
(pool이 얼마나 찾는지 확인하는 것)
spring:
datasource:
hikari:
jdbc-url: jdbc:h2:mem:testdb;MODE=MySQL;DATABASE_TO_LOWER=TRUE
username: sa
password:
connection-timeout: 3000
maximum-pool-size: 10 // 5 -> 10으로 증가
max-lifetime: 30000
driver-class-name: org.h2.Driver
spring:
datasource:
hikari:
jdbc-url: jdbc:h2:mem:testdb;MODE=MySQL;DATABASE_TO_LOWER=TRUE
username: sa
password:
connection-timeout: 15000 // 3초 -> 15초로 증가
maximum-pool-size: 5
max-lifetime: 30000
driver-class-name: org.h2.Driver
우리 프로젝트에서 해결 방법은
SseEmitter 생성하는 로직에 프론트쪽에서 user의 nickname 정보를 받아와 DB에서 User를 찾는 로직이 들어가 있었는데, SSE 통신의 경우 세션이 끊어지는것이 아니어서 SseEmitter를 생성하는 API요청이 올 때마다 DB에 연결하는 세션 수가 늘어나 HikariPool Max 임계치에 다다르게 됨.
❗DB에서 User 정보를 찾는 로직을 SseEmitter 생성하는 로직에서 제외시켜서 해결했다.