지난번에 문제가 되었던 아래 링크를 보시면
2023.04.27 - [Spring] - spring vue 연동 게시판 03
마지막에 게시글들이 안보였죠
결론부터말하자면 connection pooling을 사용하지 않았고 entityManager.close();가 되지 않아서 문제가 되었던 헤픈닝이었습니다.
pooling-size 2개로도 충분히 돌아간다는 사실을 알게되었습니다.
public List<Product> findAll(int page, int size) {
List<Product> productList = null;
EntityManager entityManager = entityManagerFactory.createEntityManager();
try{
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Product> criteriaQuery = criteriaBuilder.createQuery(Product.class);
Root<Product> root = criteriaQuery.from(Product.class);
criteriaQuery.select(root);
TypedQuery<Product> typedQuery = entityManager.createQuery(criteriaQuery);
typedQuery.setFirstResult((page - 1) * size);
typedQuery.setMaxResults(size);
// criteriaQuery.where(criteriaBuilder.equal(root.get("id"), 1)); 조건 추가시
// 페이지 조건
productList = typedQuery.getResultList();
}catch (Exception e){
e.printStackTrace();
}finally {
if(entityManager!=null){
entityManager.close();
}
}
return productList;
}
기존에 아래 코드를 넣지 않았습니다.
entityManager.close();
이를 해결하고나서 프로그램들이 해결되었습니다.
이런 비슷한 상황이어서 아래 링크를 보면서 원인을 찾게되었고 해결방법을 알게되었습니다.
원인 및 해결
제가 참고한 사이트
https://techblog.woowahan.com/2664/
문제발생:
Message Queue의 consumer thread 갯수보다 HikariCP의 maximum pool size를 충분하게 설정하지 못해 Dead lock이 발생하여 이번 장애로 이어지게 되었습니다
-우아한 형제들 기술블로그-
해결방법:
HikariCP wiki에서는 이 공식대로 Maximum pool size를 설정하면 Dead lock을 피할 수 있다고 합니다.
위의 공식은 이론적으로 Dead lock을 피할 수 있는 최소한의 Pool size 입니다.
공식대로라면 Thread가 몇 개이든 동시에 필요한 Connection이 1개라면
Pool size가 1개인 Pool을 가지고도 모든 Request를 다 처리할 수 있을 것 입니다.
하지만 효율이 좋지 않겠죠.
어떤 Thread는 운이 없게 할당받지 못해서 30초 후에 SQLTransientConnectionException을 던질 수도 있습니다.
그렇기 때문에 최적의 Pool Size를 설정하기 위해서는 Dead lock을 피할수 있는 pool 갯수 + a가 되어야 합니다.
이에 대한 방법으로는 성능 테스트를 수행하면서 최적의 Pool Size를 찾는 방법이 있을 것 같습니다.
-우아한 형제들 기술블로그-
SQL Error: 0, SQLState: null
HikariPool-1 - Connection is not available, request timed out after 60005ms.
우아한 형제들이란는 기술블로그에서 동일한 오류가 발생했습니다. 이때 아 deadlock이 걸린거구나라는걸 알았게되었습니다.
처음에는 pooling size 문제인가 생각해서 사이즈를 늘려보니 해결은 되었습니다.(임시방편으로는)
그런데 아무리 생각해도 pooling size 100개를 넘길 이유는 없는것 같았습니다.
그 근거로는 tomcat에서 사용하는 스레드 사이즈가 20개 정도라는걸 기억하고 있었고 실제 회사에서도 여러번 요청해도 문제가 없었습니다.
왠지 다른 쪽 문제인것같아서 이것 저것 확인하다보니 아래코드를 집어넣으면 해결된다는 사실을 알게되었습니다.
entityManager.close();
코드를 입력하지않아서 entitymager가 종료되지 않아 스레드가 일처리를 끝내고 있지않는 상태여서 커넥션 풀링야만 제대로 돌아갔습니다.
결론은 connection pooling을 사용하지 않았고 entityManager.close();가 되지 않아서 문제가 되었던 헤픈닝이었습니다.
pooling-size 2개로도 충분히 돌아간다는 사실을 알게되었습니다.
참고링크:
https://techblog.woowahan.com/2664/
'웹 > Spring vue 웹 개발' 카테고리의 다른 글
spring vue 연동 상품 관리,게시판 관리 어드민 페이지 02 (0) | 2023.05.02 |
---|---|
spring vue 연동 게시판 완료(ui는 조금더 수정예정), 상품 관리,게시판관리 어드민 페이지 01 (0) | 2023.04.30 |
spring vue 연동 게시판 03-deadlock 현상 발생 (0) | 2023.04.27 |
spring vue 연동 게시판, 파일 업로드 02 (0) | 2023.04.26 |
spring vue 연동 게시판 , 파일 업로드 백엔드 01 (0) | 2023.04.25 |