26강
메시지 큐
접수와 처리를 분리하면, 느린 일 때문에 사용자를 기다리게 하지 않아도 된다
먼저 보면 좋은 강의: 웹 요청의 해부, 지연 시간과 처리량
단계별로 보기
스페이스바로 재생/정지, 좌우 화살표로 단계 이동, R로 처음으로 돌아갑니다.
대기 중1 / 4 단계 — 접수증을 끊어주고 돌려보낸다
사용자가 주문을 넣습니다. 접수 서버는 그 주문을 큐에 적어두기만 하고 곧바로 "접수됐습니다"를 돌려줍니다. 여기까지 걸린 시간은 9밀리초입니다. 아직 아무것도 실제로 처리되지 않았다는 점이 중요합니다. 사용자는 접수증만 받고 떠났습니다.
이 강의를 마치면
- 요청을 '접수하는 일'과 '처리하는 일'을 분리하는 것이 무엇을 바꾸는지 설명한다.
- 큐가 요청을 버리지 않고 쌓는다는 점, 그리고 그 대가가 '유실'이 아니라 '지연'임을 구분한다.
- 적체(백로그)가 쌓이는 이유를 처리 속도와 도착 속도의 차이로 설명한다.
- 워커를 늘려 적체를 해소하는 과정을 직접 확인한다.
사용자를 언제까지 기다리게 할 것인가
주문 버튼을 누르면 시스템은 여러 가지 일을 합니다. 주문을 저장하고, 결제를 승인받고, 확인 메일을 보내고, 창고에 출고를 지시하고, 통계를 갱신합니다.
이 일들을 전부 끝낸 다음에 사용자에게 "완료됐습니다"를 보여준다고 해봅시다. 메일 서버가 2초 걸리면 사용자는 2초를 더 기다립니다. 메일 서버가 죽어 있으면 주문 자체가 실패합니다. 메일이 안 갔다고 주문을 취소하는 게 맞는 일일까요?
아닙니다. 사용자에게 정말 필요한 것은 "주문이 접수됐다"는 확답뿐입니다. 나머지는 뒤에서 해도 됩니다.
접수대와 심사실
민원 창구를 떠올려 보세요. 창구 직원은 서류를 받고, 확인하고, 접수증을 끊어줍니다. 여기까지가 30초입니다. 실제 심사는 뒤쪽 사무실에서 사흘에 걸쳐 진행됩니다.
민원인은 사흘을 창구에 서 있지 않습니다. 접수증을 들고 집에 갑니다.
| 하는 일 | 걸리는 시간 | 사용자가 기다리나? | |
|---|---|---|---|
| 접수대 | 요청을 받아 적어둔다 | 30초 | 예 |
| 심사실 | 실제 작업을 한다 | 사흘 | 아니오 |
시스템에서 이 접수대에 해당하는 것이 메시지 큐입니다. 그리고 뒤쪽 심사실에서 일하는 사람이 워커(worker) 입니다.
큐는 무엇이 다른가
앞선 강의에서 서버는 처리 능력을 넘으면 요청을 버렸습니다. 대기열이 꽉 차면 새 손님을 돌려보냈습니다. 사용자에게는 오류 화면이었습니다.
큐는 그렇게 하지 않습니다. 큐는 쌓습니다. 그게 큐의 존재 이유입니다.
일반 서버: 감당 못 하면 → 버린다 → 사용자가 오류를 본다
큐: 감당 못 하면 → 쌓는다 → 사용자는 모른다, 대신 처리가 늦어진다이 차이가 결정적입니다. 트래픽이 몰려도 사용자 화면은 멀쩡합니다. 주문은 전부 정상 접수됩니다. 다만 확인 메일이 30분 뒤에 도착합니다.
공짜가 아니다
여기서 많은 사람이 착각합니다. 큐를 붙였으니 문제가 해결됐다고요.
아닙니다. 일의 총량은 그대로입니다. 큐는 일을 없애주지 않습니다. 단지 사용자가 기다리는 자리에서 안 보이는 자리로 옮겼을 뿐입니다.
워커가 초당 30건을 처리하는데 초당 60건이 들어오면, 매초 30건씩 쌓입니다. 한 시간이면 10만 건이 밀립니다. 사용자 화면은 여전히 멀쩡합니다. 그런데 오늘 주문한 사람의 확인 메일이 내일 도착합니다.
큐가 바꾼 것은 실패의 모양입니다. 유실(오류 화면)이 지연(늦은 처리)으로 바뀐 것입니다. 대개는 이 교환이 남는 장사지만, 공짜는 아닙니다.
그리고 큐에도 한계는 있습니다. 쌓을 자리마저 다 차면 그때는 큐도 버립니다. 그때는 이미 훨씬 큰 문제입니다.
쌓인 것을 어떻게 빼는가
적체가 쌓이는 이유는 단순합니다. 들어오는 속도 > 처리하는 속도. 그러니 해법도 단순합니다. 처리하는 쪽을 빠르게 하거나, 처리하는 사람을 늘리는 것입니다.
심사관을 한 명에서 두 명으로 늘리면 심사 속도가 두 배가 됩니다. 들어오는 속도를 넘어서는 순간부터 쌓여 있던 서류가 줄어들기 시작합니다.
이것이 큐 구조의 진짜 장점입니다. 접수대는 그대로 두고 뒤쪽 인력만 늘리면 됩니다. 사용자는 아무것도 눈치채지 못합니다. 창구는 처음부터 30초였으니까요.
직접 해보세요
아래 과제에는 워커가 한 명뿐이라 큐에 일이 계속 쌓입니다. 먼저 실행해서 사용자는 멀쩡한데(오류 0건) 큐만 부풀어 오르는 것을 확인하세요. 이 조합이 큐 구조에서 가장 위험한 신호입니다. 그다음 워커를 늘려 적체를 빼보세요.
이 강의가 단순화한 것
교육용 모형은 언제나 무언가를 생략합니다. 무엇을 생략했는지 아는 것도 학습의 일부입니다.
전제한 것
- 큐에 넣는 순간 사용자에게는 '접수 완료'로 응답한다. 실제 작업 결과를 기다리지 않는다.
- 이 시뮬레이터에서 워커 하나가 큐에서 꺼내가는 속도에는 상한이 있다. 그래서 적체를 빼려면 워커 수를 늘려야 하며, 이는 실제 시스템에서 컨슈머를 늘리는 것과 같은 처방이다.
- 큐가 메시지를 잃지 않고 보관한다고 가정한다. 실제 큐의 디스크 저장·복제 여부는 제품마다 다르다.
- 작업 하나의 처리 시간은 일정하다고 본다. 실제로는 작업마다 크게 다르다.
다루지 않은 것
- 메시지 순서 보장(ordering)과 파티셔닝
- 재배달과 가시성 타임아웃(visibility timeout)
- 데드레터 큐(처리에 반복 실패한 메시지의 격리)
- 정확히 한 번(exactly-once) 배달의 어려움
이제 직접 만들어 보세요
읽어서 아는 것과 만들어서 아는 것은 다릅니다. 컴포넌트를 배치하고 트래픽을 흘려서 실제로 동작하는지 확인해 보세요.
이 강의에 물어보기
하루 5번이 강의 본문만 근거로 답합니다. 강의에 없는 내용은 지어내지 않습니다.