프로젝트가 마무리에 접어들었고,
이제는 성능 테스트를 통해, 서비스가 잘 제공될수있도록 해야하는 시점이 왔다.
먼저 성능테스트를 위한 플랜을 작성해야하는데, 아래와 같이 진행을 하려고 한다.
1) 서비스하는 화면에서 평균적으로 호출하는 API의 갯수를 파악함 (평균 5개정도)
2) 회원별로 API를 호출하도록 함.
3) 내부적으로 캐시하는 데이터가 활용되지않도록, 파라미터등을 바꿀수있으면 랜덤으로 바꾸면서 캐시히트가 되지않는 방식으로 호출함.
4) 대기열을 통한 완충되는 성능 측정
위 4개 사항을 감안해서 테스트를 진행할 예정이고,
특히 내부적으로 캐시하는 데이터들도 존재하기에 캐시 히트가 최대한 되지않게 하여,
잘못된 성능지표가 나오지 않도록 주의하려고 한다.
또한 대기열 기능을 넣었는데, 해당 대기열이 서비스 부하시 어느정도로 완충작용을 해주는지 또한 지표로 뽑으려고 한다.
서비스를 오픈할때는 사실 경험상 예상트래픽, 예상케이스 플랜으로 된적이 없었다.
빅테크에서 전문가라고 하는 사람들이 예측한 예상 트래픽, 그리고 그에 따른 시스템 확장을 했지만,
한번도 맞은 적이 없었고,
항상 장애가 났고, 이리저리 수숩하는 장면만이 생각난다.
그만큼, 오픈당시 트래픽을 예상하고 그에 따른 인프라를 확장하는 부분은 법도.장사가 없는 영역이라고 생각한다.
하지만 잊지 말아야할것은,
성능테스트를 최대한 실전에 맞추면, 그나마 어렴풋하게라도 기준이 되는 지표들을 손에 넣을수있다는 것이다.
이 지표가 상당히 중요하고, 향후 트래픽에 따른 장애시 미리 대처하는데 많은 도움을 줄수있다.
서비스 오픈이 다가오면,
경험에 의한 트라우마인지는 몰라도, 트래픽이 몰리고, 서비스가 죽는 상황이 무섭다.
이 상황을 대처할수 있는 방법을 미리 생각해 두지않으면,
그 상황이 왔을때, 사실 할수있는게 많이 없다. (서버 늘려주세요..정도?!)
현재 프로젝트에서 성능 확장을 위해 어떤 방법을 사용했는지 정리를 해본다면..
1) 데이터 베이스는 온라인용, 통계용으로 구분해서 구축했고, 각각의 데이터베이스도 레플리카를 두어, WRITE 쿼리는 온라인, 통계용의 마스터 데이터베이스로 호출을 하고, READ 쿼리는 각각의 레플리카 데이터베이스로 호출을 할수있게 CQRS 경계를 지키도록 했다.
2) 레디스 캐시 서비스를 적극 활용했다.
무겁고 자주 호출해야하지만, 자주 바뀌지않거나 실시간성이 필요하지 않은 데이터들은 캐시를 활용함으로써
데이터베이스의 부담을 줄이도록 했다.
3) 레디스 캐시 조차 불필요한 경우는 로컬캐시를 활용하여, 레디스 수신의 네트워크 비용 마저 줄이도록 했다.
로컬 메모리가 늘어나는것을 방지하기위해, Access기준 Evict와 Time기준 Evict를 적용하였다.
(캐시를 일정시간안에 사용하면, 캐시가 유지되고, 아니면 캐시가 삭제됨, 그리고 절대적인 만료시간으로 캐시가 삭제되도록 함)
4) 트래픽이 몰릴수있는 공지/이벤트성 푸시/알림등은 일정 청크로 나눠서, 시간차를 두고 전송하도록 하여, 유저의 시스템 이용 몰림이 최소화 되도록 했다.
5) 푸시 전송 서비스에서는, 서버의 트래픽/IO/Memory/DB상태등을 포괄적으로 실시간으로 확인하면서 푸시의 속도를 능동형으로 조정하며 보낼수있는 기능을 만들었다.
6) 대기열 기능을 구현했다.
한번에 서비스에 사용작 몰리지 않도록, 주기적으로 서버의 상태를 감지/모니터링하여, 부하가 높아지는 시점에는 자동적으로 대기열이 앱화면으로 활성화되도록 기능을 만들었다.
대기열이 열리면, 일정 사용자가 일정시간간격으로만 대기하면서 들어가도록 하여, 서비스의 부담을 완충할수있게 해주도록 했다.
7) 배치는 샤드되어 동작할수있도록 구성하였다(모두는 아니지만, 중요하거나, 향후 트래픽이 많아질것으로 예상하는 배치잡 대상) 따라서 향후 트래픽이 몰리는경우, 샤드 기능으로 여러 인스턴스에서 잡을 나눠서 동작할수있게 구성했다.
8) 외부 API호출과 데이터베이스 트랜잭션이 열리는 시점을 분리했다.
트랜잭션 섹션안에서 API호출등 외부 연동이나 로직이 길어지게 되면, 트랜잭션을 잡고있는 시간이 늘어나게 되고 그에 따른 성능이슈가 발생하기에, 외부 API나 무거운 프로세스는 최대한 트랜잭션 밖에서 미리 처리를 하고, 처리한 값을 트랜잭션 섹션안에 가지고 와서, 처리하도록 했다.
(커뮤니티 이미지 첨부하여 글쓰기 기능, 실거주인증 외부 연동 API 연결)
9) 블룸필터를 통한 데이터베이스 저장하는 상황을 줄였다.
특히 커뮤니티기능에서 좋아요/댓글수등을 데이터베이스를 사용하지 않고, 레디스 캐시의 자료구조를 사용함으로써,
빠르게 처리가 되도록 하였다.
위 9가지 정도를 신경쓰며, 프로젝트를 진행했다...
이래도 죽으면, 그냥 기쁘게 서비스가 대박이 났구나!! 라고 생각하는게 맞을듯!
'MY개발생각' 카테고리의 다른 글
| [개발생각] LMAX Disruptor에 대해서 (0) | 2026.09.10 |
|---|---|
| [개발생각] AI사용에 대한 전략 (0) | 2026.09.06 |
| [개발생각] Kotlin JDSL사용을 해야 했어.... (0) | 2026.08.23 |
| [개발생각] 미션 보상 기능을 코틀린 DSL 사용하면.. (0) | 2026.08.22 |
| [개발생각] FSM을 사용하자. (0) | 2026.08.15 |
