마지막 수정: 08-18
이 서비스에서는 사용자가 직접 드리미를 선택하는 방식보다, 서버가 적절한 후보를 제안하는 매칭 방식이 더 적합하다고 판단했다.
선택 자체가 사용자에게 인지 부하가 될 수 있기 때문이다. 사용자가 여러 드리미의 거리, 대기 시간, 응답 가능성 등을 직접 비교하게 만들면 서비스 이용 흐름이 길어진다. 반면 서버는 주문 위치, 드리미 위치, 대기 시간, 응답 이력 같은 정보를 더 잘 알고 있으므로, 이를 기반으로 적절한 후보를 먼저 제안하는 방식이 더 자연스럽다고 보았다.
수요와 공급의 불균형에 대응하기 쉽기 때문이다. 특정 주문에 드리미가 몰리거나, 반대로 특정 주문이 계속 선택되지 않는 상황이 생길 수 있다. 서버 매칭 구조를 사용하면 거리뿐 아니라 주문 대기 시간, 드리미 대기 시간, 후보 수 같은 요소를 정책에 반영하여 오퍼를 더 균형 있게 분배할 수 있다.
초기 기획에서 콜을 빠르게 잡는 게임적인 경험을 고려했기 때문이다. 사용자가 실시간으로 오퍼를 받고, 수락하거나 거절하고, 다시 매칭되는 흐름이 서비스의 핵심 경험이 될 수 있다고 판단했다.
매칭 구조가 실시간성을 가장 잘 보여줄 수 있는 구조라고 생각했다. 단순 목록 조회나 수동 선택보다, 주문과 드리미가 실시간으로 들어오고 나가며 오퍼가 생성되고 만료되는 흐름이 SSE, 상태 전이, 배치 매칭 같은 기술적 요소를 잘 드러낼 수 있다고 보았다.
물론 구현 과정에서 이 구조가 쉽지만은 않다는 점도 알게 되었다. 사용자가 직접 선택할 수 있는 일을 서버가 대신 처리하면, 그만큼의 복잡도와 책임은 개발자가 부담하게 된다. 특히 오퍼 상태, 만료, 수락 경쟁, 재매칭, 서버 재시작 복구 같은 문제를 고려해야 했고, 이를 통해 자동 매칭은 단순한 편의 기능이 아니라 상태 정합성을 계속 관리해야 하는 구조라는 점을 배웠다.
우리 서비스는 부르미와 드리미로 역할이 나뉘고, 서로 다른 드리미가 한 명의 부르미 요청을 상호배타적으로 수락해야 한다. 즉 서로 다른 드리미가 같은 요청을 동시에 수락할 수 없도록 하는 것이 매칭의 핵심 요구였다.
이를 위해 두 가지를 결정해야 했다.
이 문서는 두 결정의 고민 과정과 구현, 그리고 참고한 사례(Riot Messaging Service)를 정리한다.