MQTT 5 Reason Codes와 오류 처리 전략
MQTT 5의 Reason Codes 구조와 주요 에러 코드 해석, 연결·구독·퍼블리시 단계별 오류 처리 전략과 로깅·모니터링 체크리스트
목차
개요
MQTT 5는 연결과 메시지 흐름에서 세분화된 Reason Codes를 제공한다. 이 코드는 브로커와 클라이언트 간의 상태를 명확히 전달하므로, 적절한 해석과 대응이 중요하다. 본문에서는 Reason Codes의 개념, 자주 발생하는 코드의 의미, 그리고 단계별 오류 처리 전략을 구체적으로 다룬다.
Reason Codes 기본 개념
역할과 장점
Reason Codes는 단순한 성공/실패를 넘어 세부 원인을 전달한다. 이를 통해 클라이언트는 자동 재시도, 사용자 알림, 재구성 같은 적절한 조치를 선택할 수 있다. 또한 운영 관점에서는 문제의 원인을 빠르게 파악하는 데 도움이 된다.
분류
- 성공 코드: 성공 응답을 나타냄
- 논리적 실패: 권한 문제, 토픽 오류 등
- 프로토콜·구현 오류: 잘못된 패킷 형식이나 내부 에러
- 운영·리소스 한계: 서버 바쁨, 쿼터 초과 등
주요 에러 코드와 의미
자주 마주치는 Reason Codes와 그 해석을 정리하면 다음과 같다. 숫자는 MQTT 5 표준 값에 따름.
- 0x00 Success: 요청 성공
- 0x80 Unspecified error: 구체적 이유 미상, 일반적 실패
- 0x81 Malformed packet: 패킷 형식 오류
- 0x82 Protocol error: 프로토콜 규칙 위반
- 0x83 Implementation specific error: 클라이언트·브로커 구현 오류
- 0x87 Not authorized: 인증·권한 부족
- 0x8F Topic Filter invalid / Topic Name invalid: 토픽 필터나 이름의 문법 오류
- 0x90 Packet too large: 허용 최대 패킷 크기 초과
- 0x9A Message rate too high / 0x97 Receive Maximum exceeded: 속도·용량 관련 제한
각 코드는 컨텍스트에 따라 다르게 처리해야 한다. 예를 들어 Not authorized는 인증 재시도나 사용자 권한 확인이 필요하다. 반면 Malformed packet은 전송 데이터 검증 로직을 점검해야 한다.
오류 처리 전략
공통 원칙
- 신속한 분류: 코드별 원인 범주를 먼저 결정한다
- 명확한 재시도 정책: 어떤 경우에 재시도할지 정의한다
- 상태 보전: 클라이언트 세션 상태와 메시지 중복을 고려한다
연결 단계 처리
CONNECT/CONNACK 단계에서는 Reason Code가 연결 허용 여부를 결정한다. 다음 절차를 권장한다.
- Success: 연결 유지
- 인증·권한 관련 코드: 자격 증명 검증 및 사용자 알림
- 서버 관련 코드(서버 바쁨, 이동 등): 백오프를 적용한 재시도
- 프로토콜·패킷 오류: 클라이언트 구현 검토 후 재시작
구독·퍼블리시 처리
SUBSCRIBE/SUBACK, PUBLISH 관련 코드도 세밀한 정책이 필요하다.
- QoS와 재전송 정책을 일치시킨다
- 토픽 관련 오류: 토픽 문법을 검증하고 사용자에게 원인 제공
- 메시지 크기 초과: 메시지 분할 또는 페이로드 축소 방안 적용
재시도와 백오프
재시도는 에러 유형에 따라 달리 적용한다. 권한 문제는 재시도보다 자격 증명 갱신이 우선이고, 서버 과부하는 지수형 백오프가 적절하다. 백오프 정책 예시는 다음과 같다.
retry_delay = base_delay
for attempt in range(max_attempts):
wait(retry_delay)
if connect_success():
break
retry_delay = min(max_delay, retry_delay * 2)
로그와 모니터링
Reason Codes를 운영지표로 활용하면 문제를 빠르게 감지할 수 있다. 다음 요소를 로깅과 모니터링에 포함한다.
- 패킷 종류와 Reason Code
- 클라이언트 식별자와 세션 정보
- 타임스탬프와 재시도 횟수
알림 임계값은 Not authorized나 Packet too large 같은 빈번하게 발생할 수 있는 코드와, Unspecified error 같은 예측 불가능한 코드를 분리해 설정한다.
구현 예시
간단한 클라이언트 측 처리 예시로, CONNECT 실패 시 코드 기반 분기 처리 흐름을 보여준다.
def handle_connack(reason_code):
if reason_code == 0x00:
log('connected')
elif reason_code in (0x87, 0x84):
log('auth error, check credentials')
refresh_credentials()
elif reason_code in (0x86, 0x88):
log('server unavailable, apply backoff')
schedule_reconnect_with_backoff()
else:
log('unexpected reason', reason_code)
alert_operator()
운영 체크리스트
- 주요 Reason Codes별 대응 매뉴얼 정리
- 재시도·백오프 정책 문서화
- 로그에 Reason Code와 컨텍스트 저장
- 알림 임계값과 자동 복구 정책 설정
- 정기적으로 토픽 규칙과 페이로드 크기 제한 검토
마무리
MQTT 5의 Reason Codes는 문제의 원인을 상세히 알려준다. 이를 표준화된 로그 체계와 연계해 처리 정책을 세우면 복구와 운영 효율이 크게 개선된다. 특히 연결, 구독, 퍼블리시 단계별로 우선순위를 둔 대응 방안을 마련하는 것이 중요하다.