Categories: Camel프레임워크

[Camel in Action] 실전편 – MQTT와 IoT 기기 연동, 센서 데이터 파이프라인 구축

IoT와 Camel의 조합

IoT 기기는 MQTT라는 경량 메시지 프로토콜로 데이터를 주고받습니다. 수천 개의 센서가 보내는 데이터를 수집, 가공, 저장하는 파이프라인이 필요합니다. Camel의 MQTT 컴포넌트는 이런 IoT 백엔드를 쉽게 구축할 수 있게 해줍니다.

MQTT 기본 개념

MQTT는 발행/구독(Pub/Sub) 모델을 사용합니다. 기기는 특정 토픽에 데이터를 발행하고, 서버는 그 토픽을 구독해 데이터를 받습니다.

  • 토픽: 데이터 채널. 계층 구조로 표현 (예: factory/line1/sensor/temperature)
  • QoS 0: 최대 1회 전송 (유실 가능, 빠름)
  • QoS 1: 최소 1회 전송 (중복 가능, 신뢰성 있음)
  • QoS 2: 정확히 1회 전송 (가장 신뢰성 높지만 느림)

Camel MQTT 컴포넌트로 센서 데이터 수신

// 모든 센서 데이터 수신 (와일드카드 토픽)
from("mqtt:sensorData?host=tcp://mqtt-broker:1883"
  + "&subscribeTopicName=factory/+/sensor/#"
  + "&qualityOfServiceEnum=AtLeastOnce")
  .process(exchange -> {
    String topic = exchange.getIn().getHeader(MqttMessage.MQTT_TOPIC, String.class);
    byte[] payload = exchange.getIn().getBody(byte[].class);
    // 토픽에서 라인과 센서 타입 파싱
    String[] parts = topic.split("/");
    exchange.getIn().setHeader("line", parts[1]);
    exchange.getIn().setHeader("sensorType", parts[3]);
    exchange.getIn().setBody(new String(payload));
  })
  .to("direct:processSensorData");

센서 데이터 처리 파이프라인

from("direct:processSensorData")
  .unmarshal().json(SensorReading.class)
  // 이상값 필터링
  .filter(simple("${body.value} >= 0 && ${body.value}  800"))
      .to("direct:sendAlert")
  .end();

from("direct:saveToTimeSeries")
  .to("influxdb:mydb?retentionPolicy=autogen");

Camel로 MQTT 명령 전송

// 기기에 제어 명령 발송
from("rest:post:api/devices/{deviceId}/command")
  .process(exchange -> {
    String deviceId = exchange.getIn().getHeader("deviceId", String.class);
    exchange.getIn().setHeader(MqttMessage.MQTT_TOPIC,
      "factory/devices/" + deviceId + "/command");
  })
  .to("mqtt:commands?host=tcp://mqtt-broker:1883"
    + "&qualityOfServiceEnum=ExactlyOnce");

대규모 IoT 데이터 배치 집계

// 1분간 센서 데이터를 집계해 평균값 계산
from("mqtt:sensorData?host=tcp://mqtt-broker:1883&subscribeTopicName=sensor/#")
  .aggregate(header("sensorType"), new AverageAggregationStrategy())
    .completionTimeout(60000) // 1분
    .completionPredicate(exchangeProperty(AGGREGATED_SIZE).isGreaterThan(100))
  .process(exchange -> {
    double avg = exchange.getIn().getBody(Double.class);
    exchange.getIn().setHeader("average", avg);
  })
  .to("influxdb:aggregated-metrics");

zerg96

Share
Published by
zerg96

Recent Posts

AI 해킹 시대, 4대 은행이 해외 법인 보안망부터 다시 짜는 이유

국내 금융권에서 AI를 이용한 해킹과 대규모 정보유출이 잇따르자, 은행들이 이제 해외 법인과 지점의 보안까지 다시…

1시간 ago

서울 집값은 11% 올랐는데 거래는 17% 줄었다, 토허제 1년의 역설

서울 전역이 토지거래허가구역으로 묶인 지 1년이 됐습니다. 집을 못 팔게 막으면 값이 내려갈 거라는 기대도…

1시간 ago

코스피 5연속 급락 뒤 2% 반등, 외국인·기관이 받쳤고 코스닥은 제자리

어제 5거래일 연속으로 밀렸던 코스피가 오늘 아침 확 반등했습니다. 오전 9시 12분 기준 코스피는 6,165.02로…

1시간 ago

네이버 vs 카카오, 한국 AI 전쟁의 진짜 승자는 누구인가?

네이버 하이퍼클로바X vs 카카오 AI — 한국 양대 IT 기업의 AI 전쟁, 기술 역량과 플랫폼…

2시간 ago

GPU를 사지 않고 빌린다? 네이버·아마존·구글이 같은 주에 꺼낸 AI 인프라 카드

AI 이야기는 이제 "어떤 모델이 더 똑똑한가"에서 "누가 계산 자원을 더 싸고 안정적으로 쥐고 있나"로…

2시간 ago

코스피 5.46% 급락 다음 날, 오늘 밤 9시 30분 미국 CPI가 진짜 변수인 이유

어제 코스피가 하루에 348.89포인트, 5.46% 빠지면서 6,035.35로 마감했습니다. 장중에는 5,911선까지 밀렸다가 겨우 6,000선 위로 올라왔는데요,…

3시간 ago