가입유저가 많은 서비스에서 홈화면에 접속한 유저에 대한 어떤 데이터를 보여줘야하는 경우에 어떻게 시스템을 설계할수 있을까?
가장 쉬운방법은,
배치프로세스를 만들고, 해당 배치에서 가입유저대상으로 데이터를 일정주기로 수집하여, 미리 데이터를 데이터베이스에 만들어둔다.
그리고, 사용하는 시점에는 데이터베이스의 단순 조회를 통해 서비스되도록 설계하는 방법이다.
하지만,
만약 수집데이터를 수집하기위해 외부API를 호출해야하고, 해당 외부API의 호출량이 정해져있는 (유료,TPS) API라면,
이야기가 좀 달라진다.
(*자체 데이터를 통해 통계데이터를 만드는경우라면, 이야기는 좀틀리다,
빅데이터 플랫폼(스파크,하둡등)을 통해 얼마든지 다른 해결책이 있다)
홈화면에 접속한 유저에게만 보여줘야하는 데이터를 위해,
가입유저 전체대상으로 배치잡을 구동하게 되면,
접속하지 않는 유저에 대해서도 API호출을 하여, 데이터를 수집해야하기때문에 비효율적인 설계가 된다.
(만약 가입유저가 100만명인데, 홈에 들어오는 평균유저가 1만명이면...1만명을 위해서 100만명분의 배치를 돌려야한다)
아마 조금 시간이 지나면, API 호출 리미트제한에 걸려서, 배치가 멈추는 일도 발생할것이다.
다른 해결 방법으로는,
홈화면에 접속하면 그때 API를 호출하여 데이터를 보여주고, 캐시를 통해 호출량을 줄이는 방법이 있다.
좋은 해결 방법중에 하나일수있지만,
리스크가 아예 없는것은 아니다.
문제점은 아래와 같다.
1) 캐시를 적용한다고 해도, 사용자 접속이 폭주하는 경우, API호출을 적절히 제어하거나, API의 장애를 대응하기가 어렵다.
- 물론 위 문제를 해결하기 위한 여러방법이 있긴하다. 서킷브레이커를 적용하거나, 대기열기능을 적용하면 해결을 할수있겠다.
2) 수집 데이터의 수집역할이 모호해진다. (중요!!!)
- 사실 이부분이 문제점이 가장크다.
기능적으로는 문제가 없다고 하도라도, 서비스의 설계측면에서 보면, 안좋은 설계로 서비스가 만들어질수있다.
수집데이터는 수집을 위한 레이어에서 수집 프로세스를 통해 일관되게 동작하도록 설계되어야 유지/보수/설계흐름등의 관점에서 좋다.
하지만, 위 방법을 사용하게 되면, 결국 서비스 레이어에서 직접 수집을 하게 되는 형태가 된다.
서비스 레이어가 멈추거나, 문제가 있으면 수집 또한 영향을 받고, 멈추는것이다.
이런 설계는 좋은 설계가 아니라고 생각이 된다.
그럼, 이런 문제를 해결하기 위한 설계는 어떻게 해야할까?
우선 서비스레이어에서의 수집(API호출)을 제거해야하고, 해당 수집을 배치레이어로 옮기는 방법을 사용해야하는데,
이경우 가장 값싼방법은 이벤트를 이용하는 방법이다.
서비스레이어에서는 이벤트를 배치레이어로 발생을 하고,
해당 이벤트를 받은 배치가 해당 유저의 데이터를 수집(API호출등)을 진행하는 방법을 사용한다.
중요한점은 서비스레이어에서 아무런 안전장치를 만들어두지않는다면, 같은 유저의 이벤트가 짧은 시간에 중복발생되고,
유저의 데이터 수집이 중복으로 동작할수있는 케이스를 해결해야한다는 점이다.
이런 문제를 해결하기 위한 해결책은 몇가지 있다.
1) 배치레이어에서 배치주기를 같는 불름필터를 통해, 배치주기안에 중복된 요청이 들어왔는지를 필터링해서 수집하는 방법이 있다.
- 불름필터 (FALSE : 데이터가 없다 - 이것만 100% 사실) 를 통해, 대상이 아니라고 판단되는 경우만,
수집을 하도록하면, 중복 수집을 막을수있다.
2) 실시간 CEP솔류션 (ESPER등)을 사용하는 방법이 있다.
- CEP를 통해 배치주기에 중복으로 요청이 들어온 이벤트를 DISTINCT하여 유니크한 대상으로, 수집을 하는 방법이다.
그외에도 여러 방법은 존재한다.
여기서 중요한점은, 배치주기안에 같은 이벤트가 들어오는 경우 해당 이벤트들은 한번만 수집이 되도록 하는것이다!
*중요!!!
기능에 대한 방법이나 문제에 대한 해결책을 생각할때, 서비스의 설계 레이어를 생각하지 않는 경우가 많다.
레이어를 생각하지 않으면, 코드에서의 경계가 관리되지않아, 도메인,인프라영역이 서로 침범하게 되듯이,
설계단의 레이어들도 서로가 역할을 나눠하게 되고, 침범하게 되고, 실타래처럼 꼬이게 된다.
서비스 설계 레이어도 항상 생각을 하도록 하자...
'MY개발생각' 카테고리의 다른 글
| [개발생각] 캐시 스탬피드 (0) | 2026.04.13 |
|---|---|
| [개발생각] 내가 생각하는 개발자란? (0) | 2026.04.05 |
| [개발생각] 트랜잭션 시간을 줄이자 (0) | 2026.04.05 |
| [개발생각] 게시판 JPA로 구현할때, 정해야 할것들 (0) | 2026.03.30 |
| [개발생각] 공지글 읽음 처리에 대해서.. (0) | 2026.03.26 |
