운영중인 앱에서 출석체크 이벤트를 도입하게 되었다. 출석체크 이벤트는 사용자들에게 매일 자정에 접속하여 출석체크를 하면 보상을 제공하는 간단한 메커니즘이다. 하지만... 예상했던 것 이상으로 수만 명의 사용자들로부터 동시에 들어오는 출석체크 요청의 폭풍에 직면했다. 동시성 문제 수만 명의 사용자들로부터 동시에 들어오는 요청을 처리하는 것은 결코 간단한 일이 아니었다. 서버의 자원은 한정되어 있고, 동시에 너무 많은 요청이 처리될 경우 데이터베이스 충돌, 성능 저하, 심지어는 서비스 다운에 이르기도 한다. 이는 단순히 기술적인 도전을 넘어, 우리 서비스의 안정성과 사용자의 신뢰성에 대한 문제였다. CloudWatch를 확인해보면 출석체크가 시작되는 밤 12시 (UTC 15:00)에 API 요청이 수만 건으..
회사에 백엔드파트 리더로 전 야놀자 리더분께서 오셨다. 오셔서 코드품질과 성능개선에 대해서 설명해주시는데, 그동안 내가 쓰레기같은 코드들만 빨리 짜고 있었구나 싶었다..🥲 그래서 요새는 기존 코드들을 하나씩 리팩토링에 들어가고있다. TypeOrm을 좀 효율적으로 잘 쓰자고 강조하셨다. 그래서 오늘은 TypeOrm의 loadRelationCountAndMap() 메서드에 대해서 포스팅을 해보려한다. 우선 기존 코드를 먼저 확인해보자. 기존 Code 사진속 코드에 대해서 설명을 하자면 투표 댓글 작성 API 인데, 존재하지 않는 투표거나, 종료된 투표가 내가 참여한 투표가 아니면 댓글을 못달게 에러를 return하는 로직이였다. vote Repository / voting Repository로 두번 DB C..
이전에 Nest.JS로 개발하다가 중복된 값이 있으면 Update 해주고 아닐경우 Insert를 해야되는 케이스가 있었는데 Upsert나 save를 사용하지 않고 로직으로 find해서 If-Else문으로 Update, Insert를 날려서 처리한적이 있었다. Upsert나 Save로 처리했으면 코드가 좀 더 간결해지고 DB커넥션도 줄여서 성능향상도 됬을텐데,,,하고 아쉬워하던 찰나에 비슷한 케이스로 개발을 할 일이 생겼다! 뉴스의 기사에 좋아요, 싫어요 리액션 기능을 추가하는 케이스이였다. 이번엔 무조건 로직으로 처리하지 않고 Upsert나 Save로 처리해야겠다고 생각했다. 그럼 우선 Upsert랑 Save에 주요 차이점 대해 알아보면 Upsert는 데이터베이스에서 레코드를 업데이트하거나 삽입하는 데 ..
그동안 TypeOrm에서 IN조건으로 배열 통채로 검색이 안되는줄알고 service부에서 for문을 돌려서 uuid를 일일히 검색을 했었다. 그랬더니 이처럼 너무나 비효율적으로 SELECT쿼리 커넥션이 여러번 이뤄지는걸 볼 수 있다. 이러면 당연히 성능에도 영향을 끼친다. 그래서 서칭을 하다가 TypeOrm으로 한번에 배열로 검색을 할수있다는걸 알게 되었다. 이런...! - repository부 여러개 검색하려는 uuid를 배열로 where조건에 In을 써서 이처럼 한번에 할 수 있다. 윽 이렇게 쉽게 되는걸 굳이 for문을 돌려가며 했다니,,,, 열심히 하자. 아직 갈길이 멀었다.
TypeOrm으로 개발을 하다보면 꼭 정해줘야하는 "timezone"에 대해서 알아보자. 우선 UTC시간과 KST에 대해 알고있어야한다. UTC시간은 협정세계시 , UTC +- 00:00 KST시간은 한국시간 , UTC +09:00 개발을 할때 같은 시간인데 DB에 UTC, KST 시간이 섞여서 나올때도 있다. ex) DB에 값은 2023-01-28 00:00:00 이지만 TypeOrm으로 가져왔을땐 2023-01-27 15:00:00로 변경이 되있다. ex) 서버에서 DB의 시간값을 읽는 과정에서 offset이 0인값을 읽어온 후 KST시간 +09:00인 값으로 변환을 해버리는 현상 왜 이런현상이 발생하는걸까? -> TypeOrm이 시스템의 타임존을 따라가기 떄문이다. TypeOrm은 디비와 연결하면서..
오늘은 TypeOrm method인 save(), insert(), update() 에 대해서 알아보려고 한다. 얼핏보기에는 비슷해서 아무거나 써도 될 것 같은데 이게 별거 아닌 것 같아도 성능에도 영향을 끼친다. 우선 typeorm 공식 홈페이지에 나와있는 사진을 보면서 한개씩 알아보자. SAVE() save() 메서드는 값이 없으면 insert 기능을 하여 데이터를 저장하고 값이 존재하면 덮어쓴다. 그러고 저장된값을 select해서 리턴한다. 수정할때 save()는 기존의 데이터를 위에 덮어쓰는 방식이라서 기존데이터가 사라진다. 쉽게말해 document단위로 데이터를 변경한다. ex) 필드가 5개 존재하고 save로 2개의 필드를 수정하려면 5개의 필드는 전부 사라지고 2개의 필드만 저장된다. INS..