MQTT란? 브로커·토픽·QoS 쉽게 이해하기
요약
MQTT(Message Queuing Telemetry Transport)는 브로커를 가운데 두고 장치들이 토픽 단위로 메시지를 발행(Publish)하고 구독(Subscribe)하는 가벼운 메시지 전송 프로토콜입니다.
헤더가 작고 연결을 계속 유지하므로 센서처럼 작은 데이터를 자주 보내는 IoT 장치와 통신이 불안정한 현장에 많이 쓰입니다.
이 글에서는 브로커·토픽 구조, 토픽 설계 예시, QoS 0·1·2의 차이, Retain·Last Will 사용법을 정리합니다.
보안은 TLS 전용 포트 8883(암호화 없는 기본 포트는 1883)과 클라이언트 인증 방법을 중심으로 설명합니다.
냉장창고 수십 곳의 온도를 한 화면에서 보려고 하면 먼저 “센서 값을 어떤 방식으로 서버까지 보낼까?”를 정해야 합니다. 예전에는 서버가 장치를 하나씩 돌아가며 물어보는 폴링 방식을 주로 썼지만, 장치가 많아지고 LTE·Wi-Fi처럼 연결이 끊겼다 붙었다 하는 회선이 섞이면 이 방식으로는 관리하기 어려워집니다.
MQTT는 이런 문제를 풀기 위해 만들어진 프로토콜입니다. 장치는 값이 생길 때마다 브로커에 한 번 보내기만 하면 되고, 그 값이 필요한 화면·DB·알람 서버는 브로커에서 받아 갑니다. 다만 토픽 이름을 아무렇게나 짓거나 QoS를 잘못 고르면 데이터가 빠지거나 중복으로 쌓이는 일이 생기므로, 처음 설계할 때 기본 규칙을 알아 두는 것이 좋습니다.
1. MQTT란?
MQTT는 TCP/IP 위에서 동작하는 발행·구독(Publish/Subscribe) 방식의 메시지 프로토콜입니다. 1999년 송유관 원격 감시용으로 처음 만들어졌고, 지금은 국제 표준화 단체 OASIS가 관리합니다. MQTT 3.1.1은 2014년 OASIS 표준이 되었고 2016년 ISO/IEC 20922로 채택되었으며, 기능을 늘린 MQTT 5.0은 2019년 3월 OASIS 표준으로 발표되었습니다.
MQTT의 특징은 보내는 쪽과 받는 쪽이 서로를 몰라도 된다는 점입니다. 센서는 “어디로 보낼지(토픽)”만 알고, 모니터링 서버는 “어떤 토픽을 받을지”만 압니다. 둘을 이어 주는 일은 모두 브로커가 맡습니다. 고정 헤더는 최소 2바이트로 작아서 저속 회선이나 데이터 요금이 드는 LTE 회선에서도 부담이 적습니다.
| 항목 | 내용 |
|---|---|
| 통신 방식 | 발행·구독(Publish/Subscribe), 브로커 중계 |
| 전송 계층 | TCP/IP (WebSocket 위에서도 사용 가능) |
| 기본 포트 | 1883 (암호화 없음), 8883 (TLS) — IANA 등록 |
| 주요 버전 | 3.1.1 (2014, ISO/IEC 20922:2016), 5.0 (2019) |
| 전달 보장 | QoS 0·1·2 세 단계 |
| 데이터 형식 | 정해져 있지 않음 (JSON, 숫자 문자열, 바이너리 등 자유) |
2. MQTT 브로커·클라이언트는 어떻게 동작할까?
2-1. 브로커(Broker)
MQTT 브로커는 메시지를 받아서 그 토픽을 구독한 클라이언트에게 나눠 주는 중계 서버입니다. 누가 어떤 토픽을 구독하는지, 연결이 끊긴 클라이언트에게 보낼 메시지가 남아 있는지, 마지막 값(Retain)이 무엇인지를 브로커가 기억합니다. 오픈소스 브로커를 서버에 직접 설치하기도 하고, 클라우드 사업자의 관리형 브로커를 쓰기도 합니다.
2-2. 클라이언트(Client)
MQTT 클라이언트는 브로커에 접속하는 모든 프로그램과 장치를 말합니다. 센서·게이트웨이처럼 값을 보내는 쪽(Publisher)도, 모니터링 화면·DB 저장 프로그램처럼 값을 받는 쪽(Subscriber)도 모두 클라이언트이며, 하나의 클라이언트가 두 역할을 함께 할 수도 있습니다. 클라이언트는 접속할 때 고유한 클라이언트 ID를 쓰는데, 같은 ID로 다른 장치가 접속하면 브로커가 기존 연결을 끊습니다.
2-3. 연결 유지(Keep Alive)
MQTT 연결은 한 번 맺으면 계속 유지됩니다. 클라이언트는 접속할 때 Keep Alive 시간(초)을 알려 주고, 보낼 데이터가 없으면 그 시간 안에 PINGREQ 패킷을 보내 살아 있음을 알립니다. 브로커는 Keep Alive 시간의 1.5배 동안 아무 패킷도 받지 못하면 연결을 끊습니다. 예를 들어 Keep Alive가 60초면 90초 동안 소식이 없을 때 끊긴 것으로 처리합니다.
3. MQTT 토픽이란? 토픽은 어떻게 설계할까?
3-1. 토픽 구조와 와일드카드
MQTT 토픽은 메시지가 어디에 속하는지 나타내는 주소이며, 슬래시(/)로 단계를 나눕니다. 구독할 때는 와일드카드 두 가지를 쓸 수 있습니다. +는 한 단계만, #은 그 아래 모든 단계를 뜻하며 #은 반드시 맨 끝에 와야 합니다. 토픽은 대문자와 소문자를 구별하므로 “Temp”와 “temp”는 서로 다른 토픽입니다.
| 구독 필터 | 받는 토픽 예 | 받지 않는 토픽 예 |
|---|---|---|
| plant1/cold/+/temp | plant1/cold/room01/temp, plant1/cold/room02/temp | plant1/cold/room01/humi |
| plant1/cold/# | plant1/cold 아래 모든 토픽 | plant2/cold/room01/temp |
| +/+/+/status | plant1/cold/room01/status | plant1/cold/room01/temp |
| # | 일반 토픽 전부 | $SYS/… 처럼 $로 시작하는 브로커 내부 토픽 |
3-2. 현장용 토픽 설계 예시
토픽은 “넓은 범위 → 좁은 범위” 순서로 짓는 것이 좋습니다. 사업장 → 구역 → 장치 → 측정 항목 순으로 나누면 와일드카드로 구역 전체나 항목 하나만 골라 받기 쉽습니다.
- 측정값 : site01/warehouse/cold-03/temp → 페이로드 {"v":3.8,"u":"C","ts":"2026-10-21T09:00:00+09:00"}
- 장치 상태 : site01/warehouse/cold-03/status → online / offline
- 알람 : site01/warehouse/cold-03/alarm → 상한 초과 등 이벤트
- 설정 명령 : site01/warehouse/cold-03/cmd → 측정주기 변경 등 (구독 권한을 따로 제한)
토픽 설계에서 자주 하는 실수는 장치 이름에 한글·공백을 쓰거나, 측정 시각을 토픽에 넣는 것입니다. 토픽은 바뀌지 않는 주소로 두고 값·시각·단위는 페이로드에 담아야 구독 필터를 단순하게 유지할 수 있습니다. 맨 앞에 /를 붙이면 빈 단계가 하나 생기므로 붙이지 않는 편이 깔끔합니다.
4. MQTT QoS 0·1·2 차이는?
MQTT QoS(Quality of Service)는 메시지 하나를 얼마나 확실하게 전달할지 정하는 단계입니다. 단계가 높을수록 확인 패킷이 늘어나 확실해지지만 그만큼 통신량과 지연이 늘어납니다.
| 구분 | QoS 0 | QoS 1 | QoS 2 |
|---|---|---|---|
| 전달 보장 | 최대 한 번 (At most once) | 최소 한 번 (At least once) | 정확히 한 번 (Exactly once) |
| 패킷 흐름 | PUBLISH | PUBLISH → PUBACK | PUBLISH → PUBREC → PUBREL → PUBCOMP |
| 유실 가능성 | 있음 | 없음 (재전송) | 없음 |
| 중복 가능성 | 없음 | 있음 | 없음 |
| 현장 사용 예 | 짧은 주기로 계속 오는 측정값 | 기록이 남아야 하는 측정값, 알람 | 적산값·명령처럼 중복되면 안 되는 메시지 |
4-1. QoS를 고를 때 판단 기준
QoS 1에서 생기는 중복은 받는 쪽에서 장치 ID와 측정 시각으로 같은 값인지 확인하면 쉽게 걸러낼 수 있습니다. 그래서 온도·습도 기록에는 QoS 1을 쓰고 저장할 때 중복을 거르는 구성이 흔합니다. 또 실제 전달 QoS는 보낸 쪽 QoS와 구독할 때 정한 QoS 중 낮은 쪽으로 정해지므로, 센서를 QoS 1로 보내도 화면이 QoS 0으로 구독하면 화면까지는 QoS 0으로 전달됩니다.
4-2. 패킷 수로 본 계산 예시
센서 100대가 10초마다 값을 보내면 1분에 600건, 하루에 864,000건입니다. 오가는 패킷 수로 따지면 QoS 0은 하루 864,000개, QoS 1은 확인 패킷이 붙어 1,728,000개, QoS 2는 4단계라서 3,456,000개입니다. 측정값 크기가 작을수록 확인 패킷 비중이 커지므로, 데이터 요금이 드는 LTE 회선에서는 QoS 선택이 통신량에 직접 영향을 줍니다. 측정주기와 전송주기를 나눠 운용하는 방법은 IoT 센서 측정주기와 전송주기의 차이점과 운용방법 글에서 자세히 다룹니다.
5. Retain과 Last Will은 언제 쓸까?
5-1. Retain(보관 메시지)
Retain은 브로커가 토픽별로 마지막 메시지 하나를 보관해 두었다가, 새로 구독한 클라이언트에게 바로 보내 주는 기능입니다. 측정주기가 10분인 센서라도 모니터링 화면을 켜자마자 마지막 값을 볼 수 있습니다. 토픽에 길이가 0인 페이로드를 Retain으로 보내면 보관된 메시지가 지워집니다.
5-2. Last Will(유언 메시지)
Last Will and Testament(LWT)는 클라이언트가 접속할 때 미리 맡겨 두는 메시지로, 정상 종료(DISCONNECT) 없이 연결이 끊기면 브로커가 대신 발행합니다. 전원 차단, 회선 단절, 장치 멈춤처럼 장치가 스스로 알릴 수 없는 상황을 알아내는 데 씁니다. MQTT 5.0에서는 Will Delay Interval을 두어, 잠깐 끊겼다가 바로 다시 붙는 경우에는 유언 메시지를 보내지 않도록 할 수 있습니다.
5-3. 장치 상태 표시에 함께 쓰는 방법
- 장치가 접속할 때 status 토픽에 “offline”을 Retain 유언 메시지로 등록합니다.
- 접속 직후 같은 status 토픽에 “online”을 Retain으로 발행합니다.
- 연결이 비정상으로 끊기면 브로커가 “offline”을 발행하고, 이 값이 Retain으로 남습니다.
- 모니터링 화면은 언제 접속해도 status 토픽만 보면 각 장치의 현재 상태를 알 수 있습니다.
6. MQTT 보안은 어떻게 설정할까? (TLS·인증)
MQTT 자체에는 암호화 기능이 없어서 1883 포트로 보내면 측정값·아이디·비밀번호가 그대로 네트워크에 흐릅니다. 외부망을 지나는 구간이라면 TLS로 암호화한 8883 포트를 쓰는 것이 기본입니다. TLS의 동작 원리는 SSL/TLS 데이터 암호화 프로토콜 글을 참고하면 됩니다.
| 보안 항목 | 방법 | 점검 포인트 |
|---|---|---|
| 전송 암호화 | TLS (포트 8883) | 인증서 만료일, 장치의 서버 인증서 검증 여부 |
| 클라이언트 인증 | 사용자 이름·비밀번호, 또는 클라이언트 인증서 | 장치마다 다른 계정 사용, 공장 기본 비밀번호 변경 |
| 접근 제어 | 브로커의 토픽별 권한(ACL) | 센서는 자기 토픽에만 발행, cmd 토픽은 관리 서버만 발행 |
| 익명 접속 | 브로커 설정에서 차단 | 시험용으로 열어 둔 설정이 운영에 남아 있지 않은지 |
비밀번호 인증만 쓰는 경우에도 반드시 TLS와 함께 써야 합니다. 암호화 없이 비밀번호를 보내면 같은 네트워크에서 쉽게 엿볼 수 있기 때문입니다. 장치 계정을 공용으로 쓰면 한 대가 유출됐을 때 전체 계정을 바꿔야 하므로, 장치별 계정과 토픽 권한을 짝지어 관리하는 것이 안전합니다.
7. 현장에서 MQTT를 운영할 때 확인할 점
- Keep Alive 값 : LTE·Wi-Fi 회선은 통신사 장비나 공유기가 오래 쉬는 연결을 끊을 수 있으므로, 일반적으로 30~120초 범위에서 정하고 실제로 끊김이 생기는지 확인합니다.
- 세션 유지 : 연결이 끊긴 동안의 QoS 1·2 메시지를 받으려면 3.1.1에서는 Clean Session을 끄고, 5.0에서는 Session Expiry Interval을 0보다 크게 설정합니다.
- 시각 기록 : 회선이 끊겼다가 쌓인 값을 한꺼번에 보내면 도착 시각과 측정 시각이 달라집니다. 페이로드에 측정 시각을 넣고, 장치 시계는 NTP로 맞춥니다.
- 클라이언트 ID 중복 : 장치를 복제 설정하면서 ID가 같아지면 두 장치가 번갈아 끊기는 현상이 생깁니다. 장치 일련번호를 ID에 넣는 것이 안전합니다.
- 브로커 감시 : 브로커가 멈추면 모든 데이터가 멈추므로 브로커 자체의 접속 수·메시지 수·디스크 사용량도 알람 대상에 넣습니다.
MQTT를 Modbus·OPC UA와 어떤 기준으로 나눠 쓰는지는 산업용 통신 프로토콜 비교 (Modbus, OPC-UA, MQTT) 글에, 센서부터 서버까지 전체 흐름은 산업 IoT 시스템 전체 구조 이해 글에 정리되어 있습니다.
8. 관련 산업용어
■ 발행·구독(Pub/Sub)
보내는 쪽과 받는 쪽이 직접 연결되지 않고, 중계자를 통해 주제별로 메시지를 주고받는 통신 방식입니다.
■ 페이로드(Payload)
메시지에 담긴 실제 데이터 부분입니다. MQTT는 형식을 정하지 않으므로 JSON처럼 사람이 읽을 수 있는 형식을 많이 씁니다.
■ ACL(Access Control List)
어떤 클라이언트가 어떤 토픽에 발행·구독할 수 있는지 정한 권한 목록입니다.
■ Sparkplug
산업 현장에서 MQTT 토픽 이름과 페이로드 형식을 통일하기 위해 Eclipse 재단에서 만든 규격입니다.
9. 자주 묻는 질문
Q. MQTT 기본 포트 번호는?
암호화 없는 연결은 1883, TLS 연결은 8883입니다. 두 포트 모두 IANA에 MQTT용으로 등록되어 있으며, 외부망을 지나면 8883을 쓰는 것이 좋습니다.
Q. MQTT QoS 1과 QoS 2 차이?
QoS 1은 반드시 전달되지만 중복될 수 있고, QoS 2는 정확히 한 번만 전달됩니다. QoS 2는 확인 단계가 4번이라 통신량이 QoS 1의 두 배입니다.
Q. MQTT는 TCP인가 UDP인가?
TCP입니다. 연결을 유지한 상태에서 순서대로 전달하는 TCP 위에서 동작하며, 차이는 TCP vs UDP 차이 (산업 IoT 관점) 글에서 확인할 수 있습니다.
Q. MQTT 브로커가 꺼지면 데이터는 어떻게 되나?
브로커가 꺼진 동안 발행된 메시지는 브로커에 전달되지 않습니다. 장치나 게이트웨이에 값을 임시 저장했다가 다시 연결되면 보내는 기능이 있어야 기록 공백을 막을 수 있습니다.
Q. MQTT 3.1.1과 5.0 중 무엇을 써야 하나?
새로 구축한다면 장치와 브로커가 모두 지원하는 경우 5.0이 유리합니다. 5.0은 오류 원인 코드, Will 지연, 세션 만료 시간 같은 운영 기능이 늘었고, 장치가 지원하지 않으면 3.1.1을 써도 기본 기능은 같습니다.
10. 마무리
MQTT는 브로커를 가운데 두고 토픽으로 메시지를 주고받는 가벼운 IoT 프로토콜입니다. 토픽은 사업장 → 구역 → 장치 → 항목 순으로 바뀌지 않게 짓고, 측정 시각과 단위는 페이로드에 담습니다. 측정 기록에는 보통 QoS 1을 쓰고 받는 쪽에서 중복을 거르며, Retain과 Last Will을 함께 쓰면 장치의 온라인·오프라인 상태를 바로 알 수 있습니다. 외부망을 지난다면 8883 포트의 TLS와 장치별 계정·토픽 권한은 처음부터 설정해야 합니다.
참고 기준 : OASIS MQTT Version 3.1.1 (2014), ISO/IEC 20922:2016, OASIS MQTT Version 5.0 (2019)
태그 : MQTT, MQTT브로커, MQTT토픽, QoS, MQTT QoS, Retain, LastWill, LWT, 발행구독, PubSub, IoT통신, MQTT보안, TLS, 8883포트, KeepAlive, 산업IoT
- 이전글Modbus 함수 코드 01~16 정리, 프레임 예시와 예외 코드 26.10.21
- 다음글식품 냉장·냉동 온도 기준, 식품공전 품목별 보존온도와 기록 방법 26.10.21