앤디 블로그
  • 모두
  • 개발 문화
  • 기술
  • 자바
  • 스프링
  • 인프라
  • 카프카
  • 데이터베이스
  • 컨퍼런스
책
짧은 글
이력서
  • 모두
  • 개발 문화
  • 기술
  • 자바
  • 스프링
  • 인프라
  • 카프카
  • 데이터베이스
  • 컨퍼런스
책
짧은 글
이력서
  • MQTT 프로토콜과 AWS IoT 적용

    • MQTT 프로토콜
      • MQTT 프로토콜이란?
      • 기본 구조 및 작동 원리: 느슨한 연결
      • 보안
      • 프로토콜 비교 (MQTT, HTTP, CoAP)
        • 1. HTTP
        • 2. MQTT
        • 3. CoAP
    • MQTT가 IoT 에서 효율적인 통신인 이유
      • 기술적 측면(가벼움)
        • MQTT 패킷
      • 비즈니스 측면(비용과 확장)
    • AWS IoT
      • 아키텍처
      • 구현 예시(온도 센서)
    • Ref.

MQTT 프로토콜과 AWS IoT 적용

2025년 8월 13일
  • MQTT 프로토콜
    • MQTT 프로토콜이란?
    • 기본 구조 및 작동 원리: 느슨한 연결
    • 보안
    • 프로토콜 비교 (MQTT, HTTP, CoAP)
      • 1. HTTP
      • 2. MQTT
      • 3. CoAP
  • MQTT가 IoT 에서 효율적인 통신인 이유
    • 기술적 측면(가벼움)
      • MQTT 패킷
    • 비즈니스 측면(비용과 확장)
  • AWS IoT
    • 아키텍처
    • 구현 예시(온도 센서)
  • Ref.

IoT 는 통신을 위해 MQTT 프로토콜을 사용한다. 회사에서 프로젝트를 하며 aws IoT 를 사용하면서, MQTT 에 대해 잘 알아햐한다고 생각해서 개론적인 내용을 정리했다.

MQTT 프로토콜

MQTT는 단순히 '메시지를 주고받는 기술' 이상의 의미를 가진다. MQTT 는 제한된 자원과 불안정한 네트워크라는 IoT 환경의 본질적인 제약을 극복하기 위해 탄생되었따.

MQTT 프로토콜이란?

MQTT(Message Queuing Telemetry Transport)는 머신 대 머신 통신에 사용되는 경량 메시징 프로토콜이다. IoT 환경에서 다양한 디바이스가 정보를 주고받을 수 있도록 해주는 역할을 한다. MQTT는 주로 스마트 센서, 웨어러블 기기, 그리고 다양한 IoT 디바이스에 사용되는데, 이것들이 어떻게 서로 연결되는지 이해해야 한다.

기본 구조 및 작동 원리: 느슨한 연결

MQTT의 핵심은 발행-구독(Publish-Subscribe) 모델이다. 이는 메시지를 보내는 주체(Publisher)와 받는 주체(Subscriber)가 서로를 전혀 알지 못해도 통신할 수 있게 만드는 구조다. 둘 사이에는 '브로커(Broker)'라는 중개자가 존재한다.

Publisher는 특정 '토픽(Topic)'에 메시지를 발행한다. 예를 들어, 'home/living_room/temperature'라는 토픽에 '25.5'라는 메시지를 던지는 식이다. 브로커는 이 메시지를 받고, 해당 토픽을 구독하고 있는 모든 Subscriber에게 메시지를 전달한다. 이로써 Publisher와 Subscriber는 시공간적으로 완전히 분리(Decoupling)된다. Publisher는 누가 메시지를 받는지 신경 쓸 필요가 없고, Subscriber는 누가 메시지를 보냈는지 알 필요가 없다. 오직 '토픽'이라는 관심사로만 연결될 뿐이다.

image0

이러한 구조는 시스템의 유연성과 확장성을 극대화한다. 새로운 센서(Publisher)나 모니터링 앱(Subscriber)이 추가되어도 기존 시스템을 전혀 수정할 필요가 없다. 그저 브로커에 접속해 정해진 토픽으로 발행하거나 구독하면 그만이다.

신뢰성은 서비스 품질(Quality of Service, QoS) 수준으로 보장된다. MQTT는 세 가지 QoS 레벨을 정의했다.

  • QoS 0 (At most once): 메시지를 최대 한 번 보낸다. 전송 보장은 없지만 가장 빠르다. 화재 경보기처럼 손실되어도 괜찮은 주기적인 센서 데이터에 적합하다.
  • QoS 1 (At least once): 메시지가 최소 한 번은 전달되는 것을 보장한다. 메시지를 받은 쪽에서 확인 응답(PUBACK)을 보내야 한다. 응답이 없으면 Publisher는 메시지를 재전송한다. 이 때문에 중복 수신 가능성이 있다.
  • QoS 2 (Exactly once): 메시지가 정확히 한 번만 전달되는 것을 보장한다. 4단계 핸드셰이킹을 통해 메시지 전달을 확인하므로 가장 신뢰성이 높지만, 그만큼 오버헤드가 크다. 금융 거래나 원격 제어처럼 데이터 손실과 중복이 치명적인 경우에 사용된다. HiveMQ의 설명에 따르면, 이 레벨들은 신뢰성과 네트워크 효율성 사이의 트레이드오프를 개발자가 직접 선택하게 해준다.

보안

MQTT 프로토콜 자체는 암호화를 정의하지 않지만, 통신 전반을 보호하기 위한 강력한 메커니즘을 함께 사용한다. 가장 기본은 TLS/SSL(Transport Layer Security/Secure Sockets Layer)을 적용하여 클라이언트와 브로커 간의 모든 통신 채널을 암호화하는 것이다. 이를 통해 중간자 공격(Man-in-the-Middle Attack)으로 인한 데이터 탈취나 변조를 막을 수 있다.

인증(Authentication)은 접속하는 클라이언트가 '누구인지' 확인하는 과정이다. 주로 두 가지 방식이 사용된다.

  • 사용자 이름/비밀번호: 가장 간단한 방식으로, 클라이언트가 연결(CONNECT) 패킷에 자격 증명을 담아 보내면 브로커가 이를 검증한다.
  • X.509 클라이언트 인증서: 훨씬 강력한 보안 방식으로, 각 클라이언트는 고유한 디지털 인증서를 가진다. 브로커는 신뢰할 수 있는 인증 기관(CA)이 서명한 인증서인지 확인하여 클라이언트를 인증한다.

인가(Authorization)는 인증된 클라이언트가 '무엇을 할 수 있는지' 제어하는 과정이다. 보통 접근 제어 목록(ACL, Access Control List)을 통해 구현된다. 예를 들어, 'Sensor_A' 클라이언트는 'data/sensor_A' 토픽에만 발행(Publish)할 수 있고, 'control/all' 토픽은 구독(Subscribe)만 할 수 있도록 권한을 세밀하게 제어할 수 있다.

프로토콜 비교 (MQTT, HTTP, CoAP)

MQTT의 특징은 다른 프로토콜과 비교해보자

항목HTTPMQTTCoAP
통신 모델요청-응답(Request-Response)발행-구독(Publish-Subscribe)요청-응답(Request-Response)
실시간성낮음 — 클라이언트가 주기적으로 요청(Polling)해야 함높음 — 브로커가 변경 시 즉시 Push중간 — 요청 시점에만 응답
기본 전송 프로토콜TCPTCP (기본), WebSocket 지원UDP
상태 유지 여부무상태(Stateless) — 매 요청 독립 처리상태 유지(Stateful) — 연결 지속무상태(Stateless)
인증/오버헤드매 요청마다 인증 필요초기 연결 시 인증, 이후 재사용매 요청마다 인증 필요(옵션)
통신 방식 최적화일대일(One-to-One)다대다(Many-to-Many)일대일(One-to-One)
추가 특징웹 표준, 브라우저 친화적IoT, 실시간 메시징 최적화리소스 탐색(Resource Discovery) 기능 내장
적합한 활용 사례웹 API, 일반 웹 서비스IoT 디바이스 간 실시간 데이터 전송센서·기기 상태 직접 조회
  • HTTP: 범용성 높지만, IoT 실시간성에 불리
  • MQTT: 실시간 메시징·다대다 통신에 최적
  • CoAP: 일대일 상태 조회·리소스 탐색에 유리

1. HTTP

HTTP는 웹의 표준 프로토콜로, 요청-응답(Request-Response) 모델을 따른다. 클라이언트가 요청을 보내야만 서버가 응답하기 때문에, 실시간 데이터가 필요한 IoT 환경에서는 모든 디바이스가 주기적으로 상태를 조회(Polling)해야 한다. 이 방식은 네트워크 부하와 리소스 낭비를 유발한다. 또한 HTTP는 무상태(Stateless) 프로토콜이라, 매 요청마다 인증 과정을 거쳐야 한다.

2. MQTT

MQTT는 IoT 환경을 위해 설계된 경량 발행-구독(Publish-Subscribe) 프로토콜이다. 브로커가 구독자에게 변경 사항을 즉시 Push하기 때문에 실시간성이 뛰어나며, 연결을 유지하는 상태 유지(Stateful) 방식으로 매번 인증 오버헤드를 줄인다. 특히 다대다(Many-to-Many) 통신이 가능해 여러 디바이스 간 메시지 중개가 유연하다.

3. CoAP

CoAP(Constrained Application Protocol)는 저사양 기기를 위해 설계된 경량 프로토콜로, UDP 기반에서 동작한다. HTTP와 유사한 요청-응답 모델을 사용하며, 리소스 탐색(Resource Discovery) 기능이 내장되어 있다. 주로 일대일(One-to-One) 통신에 최적화되어 있어, 특정 기기의 상태를 직접 조회하는 데 적합하다. 다만 UDP 기반 특성상 신뢰성은 TCP 기반의 MQTT보다 낮을 수 있다.

MQTT가 IoT 에서 효율적인 통신인 이유

MQTT는 많은 IoT 디바이스들이 네트워크를 부담 없이 사용할 수 있게 하는 효율적인 프로토콜이다.

기술적 측면(가벼움)

MQTT의 메시지 헤더는 최소 2바이트로 매우 작다. 이는 데이터를 전송할 때마다 붙는 '꼬리표'가 작다는 의미이며, 제한된 네트워크 대역폭을 매우 효율적으로 사용하게 해준다. HTTP 헤더가 수백 바이트에 달하는 것과 비교하면 그 차이는 명확하다. 페이로드(실제 데이터) 역시 바이너리 형식을 포함한 어떤 데이터든 담을 수 있어 유연하다.

이러한 경량성은 배터리 효율로 직결된다. 네트워크 통신은 기기에서 가장 많은 전력을 소모하는 작업 중 하나다. 전송 데이터가 작고 통신 횟수가 적을수록 기기는 더 오래 깨어있지 않아도 되며, 이는 배터리 수명을 늘려준다.

MQTT 패킷

MQTT 패킷은 고정 헤더, 가변 헤더, 페이로드로 최대 세 부분으로 구성된다.

img

  1. 고정 헤더(Fixed Header) 항상 존재하며 패킷의 첫 부분으로 Control Packet Type과 Flags 필드와 Remaining Length 총 세 필드로 구성된다.
  2. 가변 헤더(Variable Header) 패킷 명령의 타입에 따라 존재하며 관련된 추가적인 데이터를 제공한다.
  3. 페이로드(Payload) 수신받을 클라이언트로 최종적으로 전송될 메세지의 실제 내용을 포함한다.

위의 패킷 구조를 참고하면 알 수 있듯이 MQTT 프로토콜의 가장 작은 패킷의 사이즈는 2byte 로 경량화 메시징 프로토콜로 저전력/낮은 리소스로 다양한 서비스 구현이 가능하다.

비즈니스 측면(비용과 확장)

기술적 효율성은 곧바로 비즈니스 비용 절감으로 이어진다. 특히 셀룰러 네트워크를 사용하는 IoT 기기의 경우, 데이터 사용량은 통신 요금과 직결된다. MQTT를 통해 데이터 전송량을 80~95%까지 줄일 수 있다. 이는 수백만 개의 기기를 운영하는 기업에게는 막대한 비용 절감 효과를 가져다준다.

확장성 또한 중요한 비즈니스 가치다. 발행-구독 모델 덕분에 시스템은 수십 개의 기기에서 수백만 개의 기기로 확장될 때 구조적인 변경이 거의 필요 없다. 브로커 클러스터링, 그리고 MQTT 5.0에 도입된 공유 구독(Shared Subscription)과 같은 기능은 특정 토픽에 몰리는 부하를 여러 구독자에게 분산시켜 대규모 시스템의 안정성을 높여준다.

공유구독이란?

MQTT 5.0에서 공유 구독(Shared Subscription)은 여러 구독자가 하나의 구독 그룹을 공유하면서, 해당 토픽의 메시지를 로드밸런싱 형태로 나눠 받는 기능이다.

공유 구독은 특수 토픽 형식을 사용한다.

$share/<group-name>/<topic>
  • $share : 공유 구독을 의미하는 예약어
  • <group-name> : 구독자 그룹명 (동일 그룹명에 속하면 로드밸런싱 대상)
  • <topic> : 실제 구독할 토픽

AWS IoT

AWS는 MQTT를 IoT 서비스의 통신 프로토콜로 채택했다. AWS IoT Core는 수백만 개의 디바이스를 안정적으로 연결하고 관리할 수 있는 완전 관리형 MQTT 브로커 역할을 수행한다.

아키텍처

AWS IoT에서 MQTT 통신은 여러 구성 요소가 있다.

  • AWS IoT Core: 전체 시스템의 심장부다. 디바이스 게이트웨이(MQTT 브로커), 인증 및 인가 서비스, 규칙 엔진(Rules Engine)으로 구성된다. 디바이스의 연결을 수락하고, 보안 정책에 따라 접근을 제어하며, 들어오는 메시지를 다른 AWS 서비스로 라우팅한다.

  • Thing Registry: 모든 물리적 디바이스는 AWS IoT에서 '사물(Thing)'이라는 논리적 개체로 표현된다. Thing Registry는 이 사물들의 목록과 속성(예: 시리얼 번호, 펌웨어 버전)을 관리하는 데이터베이스다.

  • Device Shadow: 디바이스의 마지막 상태(reported state)와 원하는 상태(desired state)를 JSON 문서 형태로 저장하는 서비스다. 디바이스가 오프라인일 때도 앱은 Device Shadow를 통해 최신 상태를 확인하거나, 원하는 상태를 설정해두고 디바이스가 온라인이 되었을 때 동기화하도록 할 수 있다.

  • Rules Engine: AWS IoT Core의 가장 강력한 기능 중 하나다. 특정 MQTT 토픽으로 들어온 메시지를 SQL과 유사한 쿼리로 필터링하고 변환한 후, AWS Lambda, Amazon S3, DynamoDB 등 십여 개의 다른 AWS 서비스로 손쉽게 전달할 수 있다. 예를 들어, '센서 데이터가 30도를 넘으면 Lambda 함수를 실행하라'와 같은 규칙을 정의할 수 있다.

구현 예시(온도 센서)

image2

AWS IoT Device SDK for Python을 사용하면 파이썬으로 간단하게 Thing과 AWS IoT Core 간의 MQTT 통신을 구현할 수 있다. 먼저 AWS IoT 콘솔에서 Thing을 생성하고, 인증에 필요한 인증서(인증서, 개인 키, 루트 CA)를 다운로드해야 한다.

아래는 온도 센서 데이터를 특정 토픽으로 발행하는 간단한 파이썬 코드 예시다. 이 코드는 AWS IoT Core에 연결하여 5초마다 JSON 형식의 온도 데이터를 발행한다.

from awscrt import io, mqtt
from awsiot import mqtt_connection_builder
import time
import json
import random

# --- 사용자 설정 값 ---
ENDPOINT = "your-iot-endpoint.iot.region.amazonaws.com"
CLIENT_ID = "my-raspberry-pi"
PATH_TO_CERT = "certificates/certificate.pem.crt"
PATH_TO_KEY = "certificates/private.pem.key"
PATH_TO_ROOT_CA = "certificates/AmazonRootCA1.pem"
TOPIC = "device/pi/temperature"

# 연결 설정
event_loop_group = io.EventLoopGroup(1)
host_resolver = io.DefaultHostResolver(event_loop_group)
client_bootstrap = io.ClientBootstrap(event_loop_group, host_resolver)

mqtt_connection = mqtt_connection_builder.mtls_from_path(
    endpoint=ENDPOINT,
    cert_filepath=PATH_TO_CERT,
    pri_key_filepath=PATH_TO_KEY,
    client_bootstrap=client_bootstrap,
    ca_filepath=PATH_TO_ROOT_CA,
    client_id=CLIENT_ID,
    clean_session=False,
    keep_alive_secs=30
)

print(f"Connecting to {ENDPOINT} with client ID '{CLIENT_ID}'...")
connect_future = mqtt_connection.connect()
connect_future.result()
print("Connected!")

# 5초마다 메시지 발행
loop_count = 0
while True:
    temperature = round(random.uniform(20.0, 28.0), 2)
    message = {
        "deviceId": CLIENT_ID,
        "temperature": temperature,
        "timestamp": int(time.time())
    }
    print(f"Publishing message to topic '{TOPIC}': {json.dumps(message)}")
    
    mqtt_connection.publish(
        topic=TOPIC,
        payload=json.dumps(message),
        qos=mqtt.QoS.AT_LEAST_ONCE
    )
    
    loop_count += 1
    time.sleep(5)

Ref.

  • MQTT란 무엇인가요? - MQTT 프로토콜 설명
  • MQTT - AWS IoT Core
  • IoT 데이터 통신 프로토콜 : MQTT
  • [통신 이론] MQTT, MQTT Protocol (MQTT 프로토콜) 이란?