MQTT 메시지 검증과 Avro/JSON Schema 적용
MQTT 메시지에 스키마 기반 검증을 적용하는 원리와 JSON Schema 및 Avro 선택과 설계, 검증 흐름을 초보자도 이해하기 쉬운 기술적 개념
목차
서론: 왜 MQTT 메시지 검증이 필요한가
IoT 기기와 마이크로서비스는 주로 MQTT로 경량 메시지를 주고받는다. 하지만 포맷 불일치나 누락된 필드는 다운스트림 오류를 유발한다. 메시지 유효성 검증을 도입하면 데이터 품질을 보장하고, 장애 원인 분석과 핸들링이 쉬워진다.
스키마 기반 검증의 장점
명확한 계약
스키마는 생산자와 소비자 간의 계약 역할을 한다. 필드 타입과 필수 여부를 명시하면 버전 관리와 호환성 판단이 쉬워진다.
에러 방지와 가시성
유효성 검사를 통해 잘못된 메시지를 조기에 차단하고 로그를 남겨 문제의 원인을 파악하기 쉽다.
JSON Schema vs Avro: 선택 기준
- JSON Schema: 사람 가독성이 높고 REST/웹 환경에 친화적이다. 텍스트 기반 MQTT 페이로드(예: JSON)와 자연스럽게 매칭된다.
- Avro: 바이너리 직렬화로 전송량이 적고 스키마 레지스트리와의 통합에 유리하다. 대량 데이터와 저대역 환경에 적합하다.
- 운영 고려사항: 네트워크 대역, 레지스트리 유무, 언어·라이브러리 지원 여부를 기준으로 선택한다.
스키마 설계 원칙
- 필수(required)는 최소화하고 기본값(default)으로 안전하게 처리한다.
- 추가 필드 허용 여부(additionalProperties)는 제한하여 불필요한 데이터 유입을 방지한다.
- 버전 필드를 포함해 스키마 진화와 호환성 전략을 명확히 한다.
구현 패턴: 브로커 전/후 검증
검증 위치는 크게 두 가지다. 생산자 측(퍼블리셔) 검증은 잘못된 메시지의 전송을 막는다. 소비자 측(서브스크라이버) 검증은 외부 입력을 방어한다. 중앙화된 파이프라인(예: MQTT 브로커 플러그인 또는 사이드카)에서 통합 검증을 수행하면 로그와 모니터링이 용이하다.
JSON Schema 예시 및 검증 흐름
간단한 센서 데이터 JSON Schema 예시:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "TemperaturePayload",
"type": "object",
"properties": {
"deviceId": {"type": "string"},
"ts": {"type": "integer"},
"temp": {"type": "number"}
},
"required": ["deviceId", "ts", "temp"],
"additionalProperties": false
}
Node.js 환경에서 AJV로 검증하는 기본 흐름:
const Ajv = require('ajv');
const ajv = new Ajv();
const schema = /* 위 스키마 JSON */;
const validate = ajv.compile(schema);
function handleMessage(payload) {
const obj = JSON.parse(payload);
const ok = validate(obj);
if (!ok) {
console.error('validation error', validate.errors);
// 오류 처리 로직
} else {
// 정상 처리 로직
}
}
Avro 예시 및 사용 흐름
Avro 스키마는 바이너리 직렬화에 적합하다. 예시 스키마:
{
"type": "record",
"name": "Temperature",
"fields": [
{"name": "deviceId", "type": "string"},
{"name": "ts", "type": "long"},
{"name": "temp", "type": "double"}
]
}
전송 흐름은 일반적으로 스키마 레지스트리에 ID를 저장하고, 페이로드는 스키마 ID + 바이너리로 전송한다. 소비자는 ID로 레지스트리에서 스키마를 조회해 역직렬화한다.
// avro-js 사용 예시
const avro = require('avro-js');
const type = avro.parse(/* 위 Avro 스키마 */);
function encode(obj) {
return type.toBuffer(obj); // Buffer를 MQTT로 전송
}
function decode(buffer) {
return type.fromBuffer(buffer);
}
운영 팁과 체크리스트
- 스키마 버전 관리: 변경 시 하위 호환성 전략을 문서화한다.
- 로깅: 검증 실패 시 원본 페이로드와 에러를 충분히 남긴다(개인정보 제외).
- 모니터링: 검증 실패율을 모니터링하고 임계치를 설정한다.
- 성능: 고빈도 토픽은 바이너리(Avro) 고려, 검증 오버헤드 측정.
결론
mqtt message schema 적용은 데이터 품질과 시스템 안정성에 직접적인 영향을 준다. JSON Schema는 가독성과 빠른 도입에 유리하고, Avro는 성능과 레지스트리 기반 운영에 강점이 있다. 환경과 요구사항을 고려해 적절한 스키마를 선택하고 일관된 검증 흐름을 설계하면 운영 부담을 줄일 수 있다.