대기열로 나중에 처리하기

오래 걸리는 일을 접수만 받아 두고 뒤에서 하나씩 처리하는 방식이에요. 대량 메일이나 큰 파일 작업에서 화면이 멈추는 걸 막아요.

쉽게 말하면

손님이 계산대에서 선물 포장 100개를 부탁했어요. 사장님이 그 자리에서 포장을 시작하면 뒤에 선 손님 열 명이 전부 멈춰요. 실제 가게는 그렇게 안 해요. 주문표를 받아 뒤쪽 꽂이에 꽂고 번호표를 드려요. 안쪽 담당이 꽂이에서 한 장씩 빼서 포장하고, 끝나면 번호를 불러요. 대기열이 바로 그 꽂이예요. 오래 걸리는 일은 접수만 하고 뒤로 빼서, 계산대는 계속 돌아가게 해요.

화면이 멈추는 이유도 똑같아요. 손님이 버튼을 누르면 그 요청 하나가 끝날 때까지 그 화면은 답을 못 받아요. 안내 메일 500통을 그 자리에서 보내면 손님은 500통이 다 나갈 때까지 흰 화면을 봐요.

게다가 기다림에는 상한이 있어요. 호스팅 업체마다 한 번의 요청이 최대 몇 초까지 돌 수 있는지 정해 두고, 그 시간을 넘기면 도중에 끊어요. 그래서 오래 걸리는 일은 미루는 게 아니라 구조를 바꿔야 해요.

바로 처리
버튼을 누르면 그 자리에서 메일 500통을 전부 보냄

손님 화면이 멈춰요. 중간에 시간이 초과되면 몇 통이 나갔는지도 알 수 없어요.

대기열로
보낼 목록만 저장하고 접수됐다고 바로 답한 뒤, 뒤에서 한 통씩 보냄

화면은 즉시 돌아와요. 진행 상황은 목록에서 보고, 실패한 건만 골라 다시 보내요.

뒤로 뺄 일과 앞에서 할 일

모든 걸 뒤로 뺄 필요는 없어요. 기준은 하나예요. 손님이 결과를 그 자리에서 기다려야 하는 일인가. 기다려야 하면 앞에서 처리하고, 안 기다려도 되면 뒤로 빼요.

가게에서 일어나는 일걸리는 느낌앞에서 할까, 뒤로 뺄까
로그인, 장바구니 담기눈 깜짝할 사이앞에서 처리해요. 결과를 바로 봐야 다음 행동을 하니까요
결제 승인몇 초앞에서 처리해요. 성공인지 실패인지 손님이 그 자리에서 알아야 해요
주문 확인 메일 한 통짧지만 받는 쪽 사정에 달림뒤로 빼요. 메일 회사가 느린 날 결제 화면까지 같이 느려지면 안 돼요. 메일 발송과 도달률
안내 메일 수백 통수 분에서 수십 분반드시 뒤로 빼요. 이건 애초에 한 번의 요청으로 감당할 크기가 아니에요
손님이 올린 사진 줄이기장당 몇 초뒤로 빼요. 대신 화면에는 준비 중 표시를 띄워요
월말 정산 파일 만들기자료가 쌓일수록 길어짐뒤로 빼요. 다 되면 받을 수 있는 자리를 알려줘요

판단이 애매할 때 물어볼 한 문장

이 일이 실패하면 손님에게 지금 알려야 하나요. 지금 알려야 하면 앞에서, 나중에 알려도 되면 뒤로 빼요. 결제 승인이 늘 앞에 남는 이유가 이거예요.

대기열이 도는 순서

말은 어려운데 실제로는 다섯 단계예요. 이 다섯 단계를 알면 개발자에게 어디가 막혔는지 정확히 물어볼 수 있어요.

  1. 1손님이 보내기를 눌러요. 화면이 그 요청을 서버로 보내요. 가게끼리 주고받는 창구
  2. 2서버는 일을 하지 않아요. 할 일 한 장을 적어 저장만 해요. 받는 사람 목록, 내용, 아직 안 함 표시가 적혀요.
  3. 3손님에게 곧바로 답해요. "접수됐어요. 지금 보내는 중이에요"가 이 단계예요. 여기까지가 1초 안에 끝나요.
  4. 4뒤에서 작업자가 돌아요. 저장된 할 일을 오래된 것부터 하나씩 꺼내 실제로 실행해요. 꺼낸 건 진행 중으로 표시해서 다른 작업자가 또 집지 않게 해요.
  5. 5끝나면 완료로 바꾸고 결과를 남겨요. 실패하면 이유와 함께 남기고 정해진 횟수만큼 다시 시도해요. 시간 초과와 재시도

여기서 작업자는 사람이 아니라 계속 켜져 있는 프로그램이에요. 가게로 치면 계산대가 아니라 안쪽 작업대에 붙어 있는 담당이에요. 이 담당이 꺼져 있으면 접수는 계속 쌓이는데 아무것도 안 나가요.

장면 · 외주 개발자가 말했다

메일은 큐에 넣었으니 곧 나갈 겁니다.

"넣었다"와 "나갔다"는 다른 말이에요. 되물을 문장은 하나예요. "지금 대기 중인 건이 몇 건이고, 실패한 건은 어디서 보나요." 이 두 숫자를 볼 화면이 없으면 발송이 멈춰도 손님 문의가 오기 전까지 아무도 몰라요.

정해진 시간에 자동 실행과 뭐가 달라요

둘 다 사람이 안 봐도 도는 일이라 헷갈려요. 다른 건 누가 시작을 결정하느냐예요. 한쪽은 시계가 정하고, 한쪽은 손님이 정해요.

묻는 것[[cron-job|정해진 시간에 자동 실행]]대기열로 나중에 처리
언제 시작하나요시계가 정한 시각에 시작해요. 매일 아침 8시처럼요손님이 버튼을 누른 그 순간 접수돼요
몇 번 도나요하루 한 번처럼 횟수가 정해져 있어요접수된 건수만큼 돌아요. 하루 3건일 수도, 3천 건일 수도 있어요
몰리면 어떻게 되나요다음 시각까지 그냥 기다려요줄이 길어져요. 작업자를 늘리면 줄이 빨리 줄어요
손님이 결과를 기다리나요대개 아니에요. 아침 리포트는 사장님이 봐요대부분 기다려요. 그래서 진행 상황 표시가 꼭 필요해요
실패하면 어떻게 되나요다음 시각에 다시 돌아요. 그사이 빈 구멍이 생겨요그 건만 다시 시도해요. 실패한 건이 목록에 남아요

그래서 둘은 경쟁이 아니라 짝이에요. 정해진 시각에 깨어나 "오늘 보낼 안내 200건"을 대기열에 넣고, 실제 발송은 대기열이 하나씩 해요. 이 조합이 가장 흔해요.

잘못 만들면 나는 사고 세 가지

대기열은 붙이는 것보다 지켜보는 것이 어려워요. 실제로 자주 나는 순서예요.

  1. 1작업자가 조용히 멈춰 있는 것. 접수는 계속 되는데 처리가 0이에요. 화면에는 접수됐다고 떠서 손님도 사장님도 며칠 뒤에 알아요. 대기 건수를 매일 보는 화면이 유일한 예방책이에요.
  2. 2재시도가 중복을 만드는 것. 메일은 이미 나갔는데 보냈다는 기록 저장이 실패하면, 다시 시도할 때 같은 손님에게 두 번 가요. 같은 일이 두 번 실행돼도 결과가 한 번이 되게 표시를 남겨야 해요.
  3. 3한 건이 줄 전체를 막는 것. 잘못된 자료 한 건에서 계속 실패하면 그 뒤가 안 나가요. 정해진 횟수를 넘긴 건은 따로 빼두고 줄은 계속 굴려야 해요.

견적에서 여기를 확인하세요

대기열을 붙이는 값 자체는 크지 않아요. 값이 드는 건 대기 건수와 실패 건을 보는 화면이에요. 견적에 이 화면이 빠져 있으면 반드시 물어보세요. 이게 없는 대기열은 눈 감고 굴리는 것과 같아요.

자주 묻는 것

Q. 손님이 언제 끝나느냐고 물으면 뭐라고 하나요?
끝나는 시각을 약속하지 말고 지금 상태를 보여주세요. 접수됨, 처리 중, 완료, 실패 네 가지면 충분해요. 밀리는 날에는 평소보다 늦어질 수 있다고 화면에 한 줄 적어 두면 문의가 크게 줄어요.
Q. 대기열을 쓰면 무조건 빨라지나요?
아니에요. 전체로 보면 오히려 조금 늘 수도 있어요. 대기열이 줄이는 건 손님이 화면 앞에서 기다리는 시간이에요. 일 자체에 걸리는 시간은 뒤에서 똑같이 흘러요.
Q. 줄이 자꾸 길어지면 어떻게 하나요?
작업자를 늘리는 게 첫 수예요. 창구를 하나 더 여는 것과 같아요. 그래도 안 줄면 일감 자체가 너무 많은지, 보내는 쪽 서비스의 호출 제한에 걸려 느린 건지 갈라 봐야 해요.
Q. 먼저 접수된 것이 먼저 끝나나요?
꺼내는 순서는 대개 먼저 들어온 것부터지만, 작업자가 여럿이면 끝나는 순서는 섞여요. 순서가 중요한 일이면 같은 손님 것끼리 한 줄로 묶어 달라고 미리 말해야 해요.
Q. 결제도 뒤로 빼면 안 되나요?
승인은 앞에서 받아야 해요. 손님이 성공인지 실패인지 바로 알아야 하니까요. 대신 승인 뒤에 붙는 일, 영수증 메일이나 알림 발송은 뒤로 빼는 게 맞아요. 결제사가 결과를 먼저 알려주는 웹훅과 같이 쓰면 잘 맞아요.
Q. 바이브캠퍼스로 만들면 이걸 직접 다뤄야 하나요?
평소에는 아니에요. 사장님이 하실 말은 "이 일은 오래 걸리니 접수만 받고 뒤에서 처리해 주세요" 한 줄이에요. 이 문서가 필요한 순간은 대량 발송을 붙일 때, 그리고 처리가 밀렸다는 문의를 받았을 때예요.

확인해 보세요

손님 800명에게 안내 메일을 보내는 버튼을 만들려고 해요. 어떻게 부탁하는 게 맞을까요?

하나 더

메일이 안 나간다는 문의를 받았어요. 개발자에게 처음 물어볼 말로 가장 좋은 건 무엇일까요?

직접 해보기

오래 걸리는 일을 뒤로 빼 달라고 말해 보세요

스튜디오 대화창에 이렇게 그대로 붙여 넣어 보세요. "안내 메일 보내기는 버튼을 누르면 접수만 하고 바로 접수 화면을 보여 주세요. 실제 발송은 뒤에서 한 통씩 하고, 보낸 건수와 실패한 건수를 볼 수 있는 화면도 같이 만들어 주세요." 지켜볼 화면까지 한 문장에 넣는 것이 핵심이에요.

스튜디오 열기

더 깊이 (안 읽어도 괜찮아요)

비유가 어디까지 맞고 어디부터 다른가 · 주문표 꽂이 비유는 "접수와 처리를 떼어 놓는다"까지 정확해요. 다른 점은 꽂이가 가게 밖에 있을 수도 있다는 거예요. 할 일 목록을 내 데이터베이스 표 한 장에 적어 두는 방식이 있고, 대기열만 전문으로 맡아 주는 외부 서비스에 맡기는 방식이 있어요. 건수가 적을 때는 표 한 장으로 충분하고, 크게 늘면 전문 서비스로 옮겨요.

작업자를 늘리면 왜 순서가 섞이나 · 작업자가 둘이면 첫 번째와 두 번째 일감을 거의 동시에 집어요. 두 번째 일이 더 가벼우면 먼저 끝나요. 그래서 "먼저 접수된 것이 먼저 끝난다"는 보장이 사라져요. 순서가 중요한 일은 같은 손님 것끼리 한 줄로 묶고 그 줄은 한 명만 집게 만들어요. 처리량과 순서는 맞바꾸는 관계예요. 손님이 늘어도 버티기

서버가 잠들면 대기열도 잠든다 · 요즘 호스팅에는 요청이 없을 때 잠들어 요금을 아끼는 방식이 많아요. 이런 곳에서는 계속 켜져 있어야 할 작업자가 같이 잠들어서 줄이 안 줄어요. 대기열을 붙일 때 "작업자는 어디서 계속 도나요"를 확인해야 하는 이유예요. 서버 구성에 따라 답이 달라요.

이것만 기억하세요

  • ·대기열은 오래 걸리는 일을 접수만 받고 뒤에서 하나씩 처리하는 방식이에요
  • ·기준은 하나예요. 손님이 결과를 그 자리에서 기다려야 하면 앞에서, 아니면 뒤로 빼요
  • ·붙이는 값보다 지켜보는 값이 커요. 대기 건수와 실패 건수를 보는 화면을 꼭 같이 만들어요
  • ·재시도는 중복을 만들 수 있어요. 두 번 실행돼도 결과가 한 번이 되게 표시를 남겨요
  • ·정해진 시각에 도는 것과는 짝이에요. 시계가 일감을 넣고 대기열이 하나씩 처리해요
VibeCampusNew build