MQTT 메시지 재전송 정책과 중복 처리 전략
MQTT 환경에서 안정성과 효율을 높이기 위한 재전송 정책 설계와 중복 메시지 처리 전략에 대한 실무적 설명과 구현 고려사항 중심의 설계
목차
개요
IoT와 경량 메시지 브로커 환경에서 MQTT는 널리 사용된다. 그러나 네트워크 불안정이나 클라이언트 오류로 인해 메시지 유실과 중복이 발생한다. 본문은 MQTT 재전송 정책 설계와 중복 메시지 처리 전략을 초보자도 이해할 수 있도록 단계별로 설명한다. 핵심 목표는 신뢰성 확보, 네트워크 부담 최소화, 운영의 단순화이다.
기본 개념 정리
QoS와 재전송
MQTT의 QoS는 전송 보장 수준을 결정한다. QoS 0은 비보장, QoS 1은 최소 한 번 전달, QoS 2는 정확히 한 번 전달을 목표로 한다. QoS가 높을수록 재전송과 상태 관리가 필요하며 중복 가능성이 늘어난다.
중복 메시지의 원인
중복은 다음과 같은 상황에서 발생한다.
- 네트워크 타임아웃으로 인한 재시도
- 브로커 재시작 후 미확인 메시지 재발송
- 클라이언트 재연결 시 재전송 로직
설계 목표
재전송 정책을 설계할 때 우선순위는 다음과 같다.
- 데이터 무결성 확보
- 중복 처리의 단순화
- 네트워크 및 리소스 효율화
- 운영과 모니터링의 용이성
재전송 전략과 백오프 정책
기본 재시도 전략
재전송 횟수와 간격을 고정으로 두면 네트워크 혼잡을 유발할 수 있다. 따라서 가변적 백오프 전략이 권장된다. 기본 파라미터는 최대 재시도 횟수, 초기 지연, 최대 지연, 그리고 재시도 방식이다.
지수 백오프와 지터
지수(backoff) 방식은 재시도 간격을 기하급수로 늘려 과부하를 완화한다. 여기에 지터(jitter)를 추가하면 동시 재시도 집중을 분산할 수 있다. 구현 예시는 다음과 같다.
const baseDelay = 200; // ms
const maxDelay = 30000; // ms
function backoffAttempt(attempt) {
const exp = Math.min(maxDelay, baseDelay * Math.pow(2, attempt));
const jitter = Math.random() * baseDelay; // uniform jitter
return Math.floor(exp + jitter);
}
정책 설계 체크리스트
- QoS에 따라 다른 재전송 정책 적용
- 최대 재시도 횟수와 장애 감지 임계값 설정
- 네트워크 상태를 반영한 동적 조정 가능성 고려
- 지터 사용으로 스파이크 방지
중복 메시지 처리 전략
아이덴티파이어 기반 중복 제거
메시지에 고유 식별자(message ID 또는 application-level ID)를 부여하면 소비자가 중복을 식별할 수 있다. 소비자는 최근 처리된 ID를 저장하고, 동일 ID 수신 시 무시하거나 확인 응답만 회신하도록 한다.
아이덴포턴시(Idempotency) 설계
처리 로직 자체를 아이덴포턴트하게 만드는 것이 가장 안전한 방법이다. 예를 들어 센서 값 누적 대신 상태 덮어쓰기 방식으로 설계하면 동일 메시지 재처리 시 부작용을 막을 수 있다.
스토리지와 TTL 전략
중복 감지를 위해 최근 ID를 메모리 또는 영속 저장소에 보관한다. 단기 캐시와 TTL(Time To Live)을 적용하면 메모리 사용을 제한할 수 있다.
- 메모리 캐시: 빠르지만 재시작 시 소실
- Redis 같은 외부 캐시: 분산 환경에서 유리
- 영속 DB: 완전한 기록이 필요할 때 사용
실전 적용 예제: 소비자 측 로직
아래는 소비자 측에서 중복 검사와 재처리 방지를 동시에 적용한 간단한 흐름이다.
async function handleMessage(msg) {
const id = msg.headers['x-msg-id'] || msg.payload.id;
if (!id) {
// ID가 없으면 폴백 정책 적용
}
const seen = await cache.get(id);
if (seen) return; // 중복으로 간주
try {
await processPayload(msg.payload);
await cache.set(id, true, { ttl: 60 * 60 }); // 1시간 보관
} catch (err) {
// 처리 실패 시 재시도 또는 DLQ(사망 큐)로 이동
}
}
운영과 모니터링
지표와 경보
효과적인 정책 운용을 위해 다음 지표를 모니터링한다.
- 재전송률: 재시도 이벤트 수 대비 성공률
- 중복율: 중복으로 판단된 메시지 비율
- 지연 시간: 재전송으로 인한 처리 지연 변화
- DLQ 비율: 처리 불가 메시지 비율
테스트 전략
정책 변경 시 네트워크 장애 시나리오, 브로커 재시작, 클라이언트 재연결을 포함한 혼합 테스트를 수행한다. 부하 테스트로 재전송 정책의 네트워크 영향도 평가가 필요하다.
결론
MQTT 재전송 정책 설계는 QoS 특성, 네트워크 환경, 애플리케이션 요구를 균형 있게 고려해야 한다. 지수 백오프와 지터를 활용해 재전송 충돌을 줄이고, 메시지 아이디 기반 중복 제거와 아이덴포턴시 설계로 처리 안정성을 확보하는 것이 핵심이다. 운영 중에는 재전송률, 중복률, DLQ 비율을 모니터링해 정책을 주기적으로 조정하면 예측 가능한 안정성을 달성할 수 있다.