Weekly I Learned/2023's(1. ~ 12.) WIL

2023년 12월 2주차(12/11 ~ 12/15) Weekly I Learned "즐거운 문제해결 과정 🔧"

ikjo 2023. 12. 18. 04:47

지난 한 주 되돌아보기

벌써 2023년이 얼마남지 않았다. 👀 매년 그래왔듯이(?) 2023년 역시 많은 일들(자취, SSAFY 입과, Pullanner 프로젝트, 취업, 자기개발 스터디 등)이 있었기에, 벌써 2023년에 대한 회고 글 작성이 기대된다. ☕

 

다른 서비스팀의 백엔드 이슈의 원인을 찾는데 기여해보았다..!! 🔧

다른 서비스를 운영하는 백엔드 개발자로부터 원인을 알 수 없는 몇가지 에러가 발생했다는 것을 전해 듣고 에러 원인을 찾는 시간을 가졌다. 우리 팀의 서비스와는 무관한 이슈지였지만, 그쪽 팀 역시 우리팀과 같은 기술 스택을 사용하고있었기에 해당 이슈의 원인이 무엇일지 관심이 많이 갔다.

 

우선 첫 번째 이슈는 같은 조회 쿼리임에도 불구하고 로컬 환경에서는 데이터 정렬이 정상적으로 되는 반면, 개발 서버 환경에서는 데이터 정렬이 정상적으로 되지 않는다는 것이었다. 결론적으로, 이렇게 차이가 나는 원인은 join buffer 사용 유무의 차이 때문이었다. 각각의 환경에서 쿼리 실행계획을 보면 로컬 환경에서와 달리 개발 서버 환경에서는 테이블 조인 시 join buffer 를 사용하고있었는데, 이는 드리븐 테이블의 조인되는 칼럼에 적절한 인덱스가 없을 경우 (풀 테이블 스캔 또는 인덱스 풀 스캔이 일어나는 경우) MySQL 의 옵티마이저가 join buffer 를 통해 조인 성능을 최적화(블록 네스티드 루프 조인)시키는 것이다. 반면 로컬 환경에서는 join buffer 를 사용하지 않았는데, 이는 로컬 환경에서의 MySQL 버전이 8.0.3xx 이었는데, 8.0.2 버전부터 블록 네스티드 루프 조인이 사용되지 않고 해시 조인 알고리즘이 도입되었기 때문이었다. 실제로 개발 환경에서의 MySQL 버전은 그 이하였다. 👀

 

또 다른 이슈는 스프링 부트의 기본 데이터베이스 커넥션 풀인 히카리 풀의 active 된 일부 커넥션들이 release 되지 않고 계속 active 상태로 남아 있어 다른 스레드들이 db 커넥션을 못 얻어 timeout 이 발생되는 것이었다. 결론적으로, 이러한 원인은 스프링에서 비동기 처리를 지원하는 ThreadPoolTaskExcutor 스레드 풀의 적당한 크기를 설정하지 못했기 때문이었다. 별도로 설정하지 않을 경우, 스프링에서 제공하는 ThreadPoolTaskExcutor 의 스레드 풀 최대 사이즈는 8 인데, 비지니스 코드에서는 iterator 를 통해 @Async 가 붙은 메서드를 동시에 8 번 이상 호출하는 것이었다. 더욱이, @Async 가 붙은 메서드 내에는 또 다른 @Async 가 붙은 메서드(외부 서버와 통신 수행)를 호출하기에 한 번의 메서드 호출로 2 개의 task 스레드가 생성되는 것이었다. 즉, iterator 를 통해 해당 메서드를 8 번 호출하면 이미 ThreadPoolTaskExcutor 스레드 풀의 유휴 스레드는 없는데 또 다른 스레드를 얻기 위해 대기 상태에 놓여 마치 dead-lock 과 같은 상황이 되버리는 것이다. 이때, 트랜잭션까지 적용되었기에 트랜잭션이 커밋 또는 롤백되지도 않아 DB 커넥션이 활성화된 채로 남았던 것이다. 이로 인해 DB 커넥션을 얻으려는 다른 API 요청 처리 작업에도 영향을 끼친 것이다. 👀

 

이제 문제에 대한 해결책은 해당 팀에서 정해야되는 부분이지만, 그래도 문제의 원인을 찾는데 도움을 드릴 수 있어 나름대로 보람있었다. ⭐

 

인프런 "스프링 부트 - 핵심 원리와 활용" 강의 듣는 중..!! 🚀

지난 주 인프런 "스프링 DB 2편 - 데이터 접근 활용 기술" 강의를 완강한 이후, 이번 주에는 인프런 "스프링 부트 - 핵심 원리와 활용" 강의를 수강 중에 있다. 스프링 부트가 어떤 편의를 제공해주는지는 기존에도 알고있었지만, 해당 강의를 통해 스프링 부트가 어떠한 원리로 그러한 편의들을 제공해주는지 쉽게 배울 수 있었다. 🎁 분량이 꽤 상당한 강의이기에 과연 목표(연말까지 스프링 강의 로드맵 완강) 달성을 위해 빠른 시간 내에 완강할 수 있을지 의문이지만,(..👀) 나름대로 틈틈이 강의 한 섹터씩 정복(?)해나가고자 한다. 💪

 

WIL 작성은 올해까지만 할 예정..!!

작년 코드스쿼드 마스터즈 코스를 수료한 이후로 한 주도 빠지지 않고 이렇게 WIL 을 작성해왔는데, 이러한 WIL 작성은 올해 2023년 연말까지만 진행할 예정이다. 👀 그동안 WIL 을 작성하면서 한 주에 있었던 일들을 되돌아 보고 복기하는 시간을 가지며 나름대로 유익함을 느꼈었지만, 요근래에는 Tech 분야의 글 작성에 갈증을 느끼고 있기 때문이다. 현재 백엔드 엔지니어로 근무하면서 여러 기술적인 이슈들을 처리하면서 많은 것들을 배우고 있는데, 이를 정리하고 공유하는 차원에서 Tech 분야의 글을 하나씩 작성해나가고 싶어졌다. (WIL 도 병행하면 좋겠지만, 현실적으로 병행하기엔 부담이 될 것 같다. 👀)

 

2022년에는 나름 기술 블로그라는 이름에 맞게 기술 관련된 글을 많이 작성했었으나, 2023년 올해에는 SSAFY, Pullanner 프로젝트 등 여러모로 글 쓸 여유가 없었던 만큼 WIL 과 회고 위주의 글만 작성했었다. 그동안 WIL 에 정말 축약된 내용으로만 배운 내용에 대해 작성해보긴 했는데, 이보다는 좀 더 deep 하게 기술에 대해 다루어 보고 싶다는 마음이 생겼다. ✍ (그래도 2023년 이후에도 백준 1일 1커밋 운동은 계속 이어나가고자 한다. ⚡)

 

(백준 1일 1커밋 운동은 365일을 향해 달려가고 있다..🏃‍♂️)