예약 알림 스케줄링 설계 면접: 30분 전 알림을 서버 여러 대에서 한 번만
시스템 디자인 Vol.1 · 15장 「30분 전에 도착하는 예약 알림」에서
이런 화면입니다
예약 시간 30분 전, 폰에 「곧 방문 시간이에요」 알림이 옵니다. 잊고 있던 손님이 이 알림 하나로 노쇼를 면합니다.
이 기능에는 버튼을 누르는 사람이 없습니다. 미래의 한 시점에 일이 저절로 일어나야 합니다.
면접관이 이렇게 묻습니다
예약 30분 전에 알림을 보내야 합니다. 예약은 하루 수만 건이고, 서버는 여러 대가 떠 있고, 배포나 장애로 재시작도 합니다. 설계해 보세요.
범위부터 좁힙니다
한 줄로 좁힙니다. 예약마다 시작 30분 전에 알림 한 번. 빠뜨려도 안 되고, 두 번 가도 안 된다. 푸시 전송은 외부 서비스에 맡기고, 보낼 시점을 어떻게 아느냐에 집중합니다.
아무도 버튼을 누르지 않습니다. 미래의 시점을 누가 기억하고, 그 시점이 왔을 때 누가 알아챌지가 핵심 질문입니다.
가장 많이 나오는 답
예약을 만들 때 메모리에 타이머를 걸어 둡니다.
// 예약 생성 직후
setTimeout(() => push(reservation), startAt - 30 * 60 * 1000 - Date.now());
로컬에서 예약 하나 만들어 보면 정확히 30분 전에 알림이 옵니다.
그런데 여기서 깨집니다
배포로 서버가 재시작되면 걸어 둔 타이머가 전부 사라집니다. 그날 오후 예약 알림이 통째로 빠집니다.
타이머를 서버 밖으로 옮겨도 다음 벽이 나옵니다. 서버 세 대가 같은 예약을 각자 처리해서 같은 손님에게 알림이 세 번 갑니다.
떨어지는 답은 이런 모양입니다
- setTimeout을 걸면 된다고 답합니다.
- 재시작 질문에서 멈춥니다.
- 서버가 여러 대일 때 같은 알림이 세 번 가는 것을 막지 못합니다.
면접관은 여기서 멈추지 않습니다
보내는 도중에 서버가 죽으면요?
빠뜨리지 않는 것과 두 번 보내지 않는 것을 같이 지키는지 봅니다.
방문 시각이 지나도 아무도 나타나지 않으면 예약 상태는요?
시간이 지나면 저절로 일어나야 하는 일을 알림 말고도 알아보는지 봅니다.
수백만 건에 초 단위 정확도가 필요하면요?
지금 설계의 한계와 다음 계단을 말하는지 봅니다.
이 다음 판단은 책에서 이어집니다
책은 미래의 시점을 어디에 기억할지 정하고, 여러 대의 서버가 같은 예약을 두고 부딪힐 때와 예약이 쌓일 때 무엇을 챙겨야 하는지 풉니다.
15장에서 이어지는 것
- 미래의 시점을 기억하는 위치
- 서버가 여러 대일 때 같은 예약이 겹치는 문제
- 예약이 쌓일수록 챙길 것
- 알림 뒤 예약 상태는 어떻게 바뀌나