개요

connectionTestQuery property 를 사용하지 않기위해 내가 이것저것 찾아본 이야기

  • springboot
  • springboot jpa (jdbc)
  • hikari cp

설명

개요에 설명한 connectionTestQuery 는 JDBC4 버전에서는 사용을 지양하는 속성이다. 왜냐하면 hikari CP 의 리드미를 살펴보면 아래와 같은 문구를 찾을 수 있다. 만약 현재 애플리케이션이 JDBC4 버전을 사용하고 있지 않다면 에러가 발생될 것이라고 한다.

 

그러면 현재 나의 애플리케이션이 jdbc4 를 사용하고 있는지 확인이 더불어서 필요하다. 일반적으로 jdbc driver 는 우리가 두 개를 사용하고 있다.

  • Connector/J 5.1
  • Connector/J 8.0

그리고 스프링 애플리케이션 단에서는 아래와 같은 yml 설정을 통해 사용을 하고 있다면, 저 connectionTestQuery 속성은 필요가 없어진다. spring.datasource.driver-class-name: com.mysql.cj.jdbc.Driver Connector/J 8.0 의 경우에는 jdbc 4.2 버전의 스펙을 구현하고 있기 때문이다. 레퍼런스를 살피면, MySQL Connector/J is a JDBC Type 4 driver, implementing the JDBC 4.2 specification 라고 적혀있다.

 

잠깐. hikari cp 가 무엇인지 설명을 안했다.

 

cp 는 connection pool 의 약자이다. 사용자가 증가함에 따라서 매번 서버는 디비와 커넥션을 맺고 끊기를 반복하게 되는 것은 속도 및 자원 측면에서 일일히 디비 접속을 수행하는 것은 비효율적이다. 이러한 방법을 해결하기 위한 수단으로 풀이라는 개념을 이용하는데 미리 일정한 개수의 커넥션을 확보해놓고 거기에서 커넥션을 재사용하는 것이다. 이렇게 한다면 서버 자원의 고갈을 막을 수 있을 뿐만 아니라 매번 새롭게 연결을 수행하지 않아도 되기 때문에 속도의 측면에서도 그렇게 느리지 않다. hikari cp 는 사용자에게 커넥션 풀을 가능하도록 해준다. 현재 스프링 2.x 부터 기본으로 제공되는 datasource 이다.

 

하지만 커넥션풀에도 장점이 있다면 단점도 있을 것인데, 너무 많은 커넥션풀을 잡아버리게 되면 메모리의 소모가 크게 되고 (커넥션이라는 것도 객체이기 때문에 메모리에 올려놓고 쓴다), 그렇다고 너무 작게하면 사용자 요청의 대기시간이 길어진다 (커넥션풀에 있는 커넥션들은 모두 다 사용 중이게 될 수 있기 때문이다.) 는 단점이 있다. 따라서 둘 사이의 적절한 트레이드 오프가 필요하다.

 

위의 내용에서 connectionTestQuery 속성의 경우 hikari CP 가 커넥션 풀에서 연결자체를 안정적으로 유지하기 위한 하나의 수단이다. 현재 애플리케이션을 사용하는 사람이 없는 경우에 커넥션 풀이 제공할 수 있는 연결의 개수를 줄이기는 하지만 커넥션 풀에 있는 연결들을 다 끊어버릴순 없다. 그래서 그것 막기 위한 방편이 현재 서비스에 영향을 끼치지 않고 간단한 실행문장 SELET 1 쿼리를 날림으로써 애플리케이션 단에서 디비와의 연결을 유지시킨다.

 

그래서 내가 알아본 것은 jdbc4 버전을 사용한다면 connectionTestQuery 를 사용하지 않더라도 알아서 애플리케이션에서 디비로 일정시간마다 핑을 날리고 있다는 사실이었다.

 

PoolBase.java 소스코드 쪽을 살피면, 아래와 같은 코드가 있다.

   boolean isConnectionAlive(final Connection connection)
   {
      try {
         try {
            setNetworkTimeout(connection, validationTimeout);

            final int validationSeconds = (int) Math.max(1000L, validationTimeout) / 1000;
			
            // 해당 부분에서 
            // ConnectionImpl 의 isValid() 가 호출되고 있었다.
            if (isUseJdbc4Validation) {
               return connection.isValid(validationSeconds);
            }

reference

Posted by doubler
,