앱 서버 병목을 끊다: MQTT 브로커 분리와 선택 기준 재정의
초기에는 앱 서버가 로봇 메시지를 중간에서 받아 처리해도 문제가 없었다. 하지만 트래픽이 늘면서 앱 서버가 API, 상태 처리, 메시징까지 모두 떠안게 됐고 병목이 구조적으로 커졌다.
이 글은 MQTT 브로커를 왜 분리하려고 했는가보다 한 단계 더 들어가,
무엇을 기준으로 브로커를 선택해야 운영 리스크를 줄일 수 있는가를 정리한 기록이다.
문제 정의
상황은 명확했다.
- 스트림성 트래픽까지 앱 서버가 처리하면서 부하가 누적됨
- 실시간 메시징 특성이 API 서버 운영 모델과 충돌함
- 서버 스케일링이 곧 메시지 품질 보장으로 이어지지 않음
핵심 문제는 “브로커를 도입할지 말지"가 아니었다.
메시징 경계를 어디서 분리하고 무엇을 보장할지가 본질이었다.
처음 기준이 실패한 이유
초기에는 기준을 이렇게 잡았다.
- 안정성
- 확장성
- 최적화
문제는 너무 추상적이라는 점이었다. “안정성"이라는 단어만으로는 선택할 수 없고, 실제 운영에서 검증 가능한 항목으로 쪼개야 했다.
최종 선택 기준
실제로 비교해야 하는 항목은 아래였다.
- QoS 레벨 지원과 메시지 중요도별 정책 적용 가능성
- 세션 유지/복구(재연결 시 동작 포함)
- 영구 세션 및 저장 기간 정책 제어
- 웹/앱/디바이스 클라이언트 SDK 호환성
- 인증/암호화(X.509 포함) 적용 난이도
- 모니터링 및 오토스케일 운영 가능성
메시지 유형별 QoS 매핑
QoS를 단일 값으로 고정하면 비용이 급증한다. 실무에서는 메시지 유형별로 다르게 가져갔다.
- 텔레메트리: QoS0 (유실 허용, 고빈도)
- 상태 이벤트: QoS1 (중복 허용, 유실 최소화)
- 제어 명령: QoS1~2 (중복 제어 필요)
핵심은 “모든 메시지를 안전하게"가 아니라 중요도별 보장 수준을 맞추는 것이다.
중요한 판단: 기능보다 운영 자동화
검토 중간에 가장 크게 바뀐 생각은 이것이다.
우리 트래픽은 고정이 아니라 유동적이므로, 브로커 기능 자체보다 모니터링과 오토스케일 지원이 우선이다.
- 고급 기능이 많아도 운영 자동화가 약하면 병목이 다시 생긴다.
- 반대로 기능이 단순해도 관측과 스케일링이 되면 서비스 신뢰도는 올라간다.
실무적으로 남긴 액션 아이템
- MQTT와 Kafka 계열 비교 항목을 트래픽 패턴 기준으로 재작성
- 클라이언트 전달 보장 정책(지연 허용치, 마지막 메시지 처리)을 명문화
- 브로커 도입 전 관측 지표(큐 길이, 지연, 재전송, 재연결률) 정의
- 인증 체계를 X.509 중심으로 통일 가능한지 사전 검증
참고 및 인용
참고: MQTT 표준은 QoS, 세션, retain/LWT 등 실시간 메시징 보장 모델을 정의한다. MQTT Specification
참고: OASIS MQTT v5 문서는 reason code, session expiry 등 운영에 중요한 제어 기능을 명세한다. MQTT Version 5.0
참고: AWS IoT Core 문서는 MQTT 주제/정책/보안 운영 시 고려사항을 상세히 다룬다. MQTT in AWS IoT
시리즈
- 1편: 운영 가능한 로봇 Agent는 프로비저닝에서 시작된다
- 2편(현재 글): 앱 서버 병목에서 MQTT 브로커 분리까지
- 3편: 기능보다 먼저 테스트 가능한 구조
- 4편: 로봇 WebRTC 스트리밍 장애를 푸는 방법