Foundry
메시징
기초
핵심

메시지 큐 기초

비동기 처리의 핵심, 왜 메시지 큐가 필요한가?

메시지 큐 기초

왜 메시지 큐가 필요한가?

  • 비동기 처리: 이메일 발송, 알림 등 즉시 응답 불필요한 작업
  • 디커플링: 서비스 간 직접 의존 제거
  • 버퍼링: 트래픽 급증 시 요청을 큐에 저장 후 처리

주요 메시지 브로커

브로커특징적합 사례
Kafka고처리량, 로그 기반이벤트 스트리밍, 로그 수집
RabbitMQ유연한 라우팅, AMQP작업 큐, RPC
SQSAWS 관리형간단한 비동기 처리

실무 포인트

  • At-least-once vs Exactly-once: 대부분 At-least-once → 멱등성 보장 필요
  • 메시지 순서 보장이 필요한가? → Kafka 파티션 키 활용
  • DLQ(Dead Letter Queue)로 실패 메시지 관리
면접에서 이렇게 나옵니다

Q.메시지 큐를 왜 쓰나요?

호출하는 쪽과 처리하는 쪽을 시간적으로 떼어내기 위해서입니다.

얻는 것내용
응답 시간 단축즉시 필요 없는 일을 뒤로 넘긴다. 이메일, 썸네일 생성
부하 완충갑작스러운 유입을 큐가 받아 두고 소비자가 자기 속도로 처리한다
장애 격리소비자가 죽어도 메시지는 남는다
결합도 감소발행자가 소비자를 몰라도 된다
확장소비자를 늘려 처리량을 올린다
재처리실패한 작업을 다시 처리할 수 있다

두 번째가 큐의 고유한 값입니다. 초당 1만 건이 몰려도 소비자가 초당 1천 건만 처리할 수 있다면, 동기 호출로는 실패하지만 큐가 있으면 시간을 늘려 전부 처리합니다.

세 번째도 중요합니다. 동기 호출에서 상대가 죽으면 그 요청은 사라지지만, 큐에 넣었으면 상대가 복구된 뒤 처리됩니다.

흔한 실수: 성능을 위해 쓴다고만 답하는 것. 전체 처리 시간은 오히려 늘어납니다. 짧아지는 것은 사용자가 기다리는 시간입니다. 그리고 그 대가로 즉시 결과를 알 수 없게 됩니다.

Q.메시지 큐를 쓰면 안 되는 경우는 언제인가요?

상황이유
결과를 즉시 알려줘야 한다로그인 검증, 잔액 조회. 비동기로 만들 수 없다
순서가 엄격히 중요하다큐는 파티션 단위로만 순서를 보장한다
호출 한 번으로 끝난다큐를 두면 운영할 것만 늘어난다
강한 트랜잭션이 필요하다DB 와 큐를 원자적으로 묶을 수 없다
지연을 감당할 수 없다큐를 거치면 최소 수십 밀리초가 더 든다

세 번째가 실무에서 가장 흔한 오용입니다. 서비스 두 개 사이의 단순한 조회에 큐를 두면 응답을 되받기 위한 구조를 또 만들어야 하고, 그것은 그냥 동기 호출보다 복잡합니다.

큐를 도입하면 함께 따라오는 것들도 있습니다.

따라오는 비용내용
중복 처리 대비멱등성을 만들어야 한다
실패 처리재시도와 실패 큐를 설계해야 한다
관측트레이스가 끊기고 지연을 따로 재야 한다
운영브로커 자체가 장애 지점이 된다

흔한 실수: 결합도를 낮추려고 모든 통신을 큐로 바꾸는 것. 흐름이 보이지 않아 장애 때 어디까지 진행됐는지 알기 어려워집니다.

Q.메시지 유실을 어떻게 방지하나요?

유실될 수 있는 구간이 세 곳입니다. 각각을 막아야 합니다.

구간유실 상황대응
발행브로커에 도착 전에 실패저장 확인 응답을 기다린다. 재시도한다
브로커저장 전에 노드가 죽는다복제본을 두고 과반 저장을 확인한다
소비처리 전에 완료 표시를 한다처리 성공 후에 표시한다

세 번째가 가장 흔한 원인입니다. 메시지를 받자마자 완료로 표시하고 처리 중에 죽으면 그 메시지는 사라집니다. 처리가 끝난 뒤 표시해야 합니다.

첫 번째에서는 DB 쓰기와 발행을 묶는 문제가 함께 옵니다. 커밋과 발행 사이에 죽으면 데이터는 있고 이벤트는 없으므로, 이벤트도 같은 트랜잭션에 저장해 두고 별도 프로세스가 발행하는 구조를 씁니다.

설정에서 볼 것내용
발행 확인 수준리더만 받았는지, 복제본까지 받았는지
복제 수와 최소 동기 복제 수하나가 죽어도 남는지
소비자 완료 표시 시점자동 표시를 끄고 처리 후 수동으로

흔한 실수: 유실을 0으로 만들려는 것. 대가는 지연과 처리량입니다. 어떤 데이터는 유실을 감수하는 편이 합리적이고, 그 판단이 먼저입니다.

Q.컨슈머 랙이 계속 쌓이면 어떻게 대응하나요?

쌓인다는 것은 처리 속도가 유입 속도보다 느리다는 뜻입니다. 원인을 나눠 봅니다.

확인내용
유입이 늘었는가발행량 지표를 본다
처리가 느려졌는가메시지당 처리 시간을 본다
소비자가 죽었는가인스턴스 수와 재시작 이력
특정 파티션만 쌓이는가키가 한쪽에 몰렸거나 그 소비자만 문제
재시도가 반복되는가처리 못 하는 메시지가 앞을 막고 있다

네 번째와 다섯 번째가 자주 놓치는 원인입니다. 전체 랙만 보면 원인이 안 보입니다.

대응내용
소비자 증설파티션 수까지만 효과가 있다
파티션 증설그 위로 늘리려면 필요하다
처리 최적화건별 DB 접근을 묶음 처리로
막는 메시지 격리실패가 반복되면 실패 큐로 보내고 넘어간다
발행 조절급하지 않은 발행을 줄인다

첫 번째의 한계가 중요합니다. 파티션 수가 소비자 수의 상한이라, 파티션 4개에 소비자 10대를 붙이면 6대는 아무것도 하지 않습니다.

흔한 실수: 랙 숫자만 보고 판단하는 것. 건수보다 따라잡는 데 걸릴 시간이 실제 지표입니다. 100만 건이 쌓였지만 처리 속도가 유입의 두 배면 곧 사라지고, 1만 건이지만 처리가 더 느리면 계속 늘어납니다.

먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.

더 깊이 공부하기

읽었으면 문제로 확인해보세요

메시징 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.