커넥션 에러 해결
아래 코드는 org.springframework.boot:spring-boot-autoconfigure 에 기본으로 설정된 쓰레드 풀 관련 필드이다. public static class Tomcat {\n private int maxConnections = 8192;\n\t\t private int acceptCount = 100;\n...\n}\n\npublic static class Threads {\n\t\t\tprivate int max = 200;\n\t\t\tprivate int minSpare = 10;\n...\n} 위 설정처럼 spring boot 는 기본적으로 최소 10개, 최대 200개의 쓰레드를 사용할 수 있고, 최대 8192개의 커넥션이 가능하고, 100 size의 큐를 갖고 있다. 그런데, WAS 에서 유저가 얼마 있지도 않음에도 다음과 같이 커넥션을 연결하지 못한 채 타임아웃이 나버렸다. java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available 기본적으로 HikariCP 는 최대 10개의 DB 커넥션을 지원하고 있다. 하나의 페이지에서 여러 API 를 요청함에 따라 Spring MVC 에서는 요청 별로 쓰레드를 할당하고, nginx를 통해 keep-alive를 90초로 설정해놓았기에 쓰레드에서 커넥션 풀을 잡고 놓아주지 않는 것은 아닐까? 라고 생각했다. 결론 JDBC Template 를 사용하고 있어, Connection 을 언제 꺼내고 반환하는 지 살펴보았다. template.query, template.update 와 같이 쿼리를 실행할 때 전후로 getConnection 과 closeConnection 을 호출하고 있었다. 따라서 쓰레드가 커넥션을 잡고 있는 것은 아닐 것이라 판단하였다. keep-alive 를 90초로 설정한 것은 불필요한 handshaking 을 줄여주는 것이지, 쓰레드를 잡고 있는 것이 아니다. 그렇다면 유저도 얼마 없는데 30초 씩이나 DB 커넥션을 얻지 못할 일이 뭐가 있을까? public static Array createSqlArray(JdbcTemplate template, List<String> tags) throws SQLException {\n Array stringArray = null;\n try {\n stringArray = template.getDataSource().getConnection().createArrayOf(\"varchar\", tags.toArray());\n } catch (SQLException e) {\n throw new SQLException(e);\n }\n return stringArray;\n } 위 코드는 template 에서 datasource를 직접 꺼내고 직접 커넥션을 얻어 사용하였는데, 끝나고 반환을 하지 않았다. 위 같은 경우에 finally 구문에서 close 를 해주거나, DataSource 를 커스터마이징하여 AutoClosable 를 구현하여 try-with-resources 를 사용하는 방법으로 해결할 수 있다. 근데 그냥 저 코드 자체가 문제인듯
0개의 댓글
0개의 질문