Skip to content

About

산업 현장의 센서 데이터를 실시간으로 수집·처리하고, 위험 판단·제어·알림까지 연결한 모니터링 시스템

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 

Repository files navigation

🏭 Monitory

석유화학 공장의 환경·설비·작업자 데이터를 실시간으로 연결하는
스마트팩토리 통합 모니터링 시스템

LG CNS AM Inspire Camp 1기 · Team FactoReal


Monitory Banner


📌 Project Highlights

약 50만 건 190건 57건 100ms 이내
장시간 센서 데이터 검증 단위 테스트 기능 테스트 응답시간
100개 센서 · 5초 주기 · 7시간 커버리지 약 70% 실제 기능 시나리오 검증 CPU 약 30%

💡 “실시간 시스템에서 수신과 처리 완료는 다르다고 생각했습니다.”

센서 데이터가 들어오는 순간이 아니라 저장·제어·알림이 의도한 순서로 끝났을 때 한 건의 처리가 완료된다고 보고 처리 흐름과 실패 조건을 확인했습니다.

👩‍💻 프로젝트 한눈에 보기

항목 내용
프로젝트 LG CNS AM Inspire Camp 1기 기업 현장형 프로젝트
개발 기간 2025.04.15 ~ 2025.06.23
팀 FactoReal · 8인
개인 역할 Service Team Backend · 웹 서비스 기획·개발·운영
핵심 경험 실시간 데이터 처리 · 처리 순서 재설계 · Kafka 재처리 · 테스트/검증
Organization Fac2Real
Backend Repository monitory-be

ℹ️ 이 저장소는 채용 포트폴리오용 개인 Showcase입니다.
프로젝트 전체 기술·성과와 개인이 직접 수행한 영역을 구분하여 작성했습니다.


📜 목차

  1. 프로젝트 소개
  2. 서비스 시연
  3. 담당 역할 및 기여
  4. 팀원 구성
  5. 시스템 아키텍처
  6. 기술 구성
  7. 트러블 슈팅
  8. 성능·신뢰성 검증
  9. 프로젝트 사용 도구
  10. 개발 및 배포 방식
  11. What I Learned

1. 프로젝트 소개 🌳🔍

공장 환경·안전·설비를 하나의 흐름으로 관리하다

Monitory는 석유화학 공장에서 발생할 수 있는 환경 이상, 작업자 안전 문제, 설비 고장 위험을 실시간 데이터로 확인하고 대응하기 위해 개발한 통합 모니터링 시스템입니다.

IoT 센서와 웨어러블에서 발생한 데이터를 수집해 실시간으로 처리하고, 위험 상태를 판단해 이상 이력 저장, 자동 제어, 운영자 알림까지 연결했습니다.

설비 데이터는 별도의 예지보전 파이프라인과 연동해 잔존 수명을 예측하고 점검 시점을 안내합니다.

핵심 기능

  1. 공장 환경 실시간 모니터링
    온도·습도·VOC·미세먼지·압력·진동·전력 등 센서 데이터를 수집하고 공간별 위험 상태를 확인합니다.

  2. 위험 감지 및 자동 제어
    센서 상태가 기준을 벗어나면 이상 이력을 기록하고 설정된 조건에 따라 후속 제어를 수행합니다.

  3. 실시간 알림
    WebSocket과 FCM 등을 활용해 운영자와 작업자에게 위험 상황을 전달합니다.

  4. 작업자 안전 관리
    웨어러블과 모바일 애플리케이션을 연동해 작업자 상태를 확인하고 위험 상황에 대응합니다.

  5. 설비 예지보전
    설비 센서 데이터를 바탕으로 잔존 수명을 예측하고 점검이 필요한 시점을 안내합니다.

  6. 운영 이력 추적
    이상·제어·알림 이력을 관리해 어떤 위험에 어떤 조치가 수행됐는지 확인할 수 있습니다.


2. 서비스 시연 🎬

🌡️ 공장 환경 안전 모니터링

공간·설비 센서에서 발생하는 데이터를 실시간으로 확인하고, 위험 상태가 감지되면 이상 이력과 제어 결과까지 함께 관리합니다.

환경 안전 모니터링

  • 온도·습도·VOC·미세먼지 등 센서 상태 실시간 확인
  • 공간별 환경 리포트와 센서 그래프 조회
  • 센서별 자동 제어 조건 설정
  • 이상 발생 이력과 후속 제어 결과 추적

🦺 작업자 안전 모니터링

웨어러블에서 수집한 작업자 상태를 실시간으로 확인하고, 이상이 감지되면 관리자와 현장 작업자에게 위험 상황을 전달합니다.

작업자 안전 모니터링

  • 웨어러블 기반 작업자 상태 수집
  • 작업자별 위험 상태 확인
  • 위험 발생 시 관리자 화면 알림
  • FCM 기반 작업자 모바일 긴급 알림

🔧 설비 예지보전

설비 데이터를 기반으로 현재 상태와 예상 점검 시점을 확인하고, 점검 진행 상태와 이력을 관리합니다.

설비 예지보전

  • 설비별 상태 및 센서 정보 조회
  • 잔존 수명 기반 예상 점검일 확인
  • 점검 대상과 진행 상태 관리
  • 점검 완료 후 이력 갱신

📑 월간 리포트

한 달간 발생한 환경·작업자·설비 관련 데이터를 집계해 공간별 위험 현황과 주요 지표를 확인할 수 있습니다.

월간 리포트

  • 월별 위험 발생 현황 집계
  • 공간별 위험 이벤트 비교
  • 환경·작업자·설비 데이터를 통합한 리포트 제공
  • 결과 CSV 및 이메일 전달

3. 담당 역할 및 기여 👩‍💻

Service Team Backend Developer

8인 팀에서 백엔드 개발과 웹 서비스 기획·개발·운영을 담당했습니다.

직접 수행한 핵심 경험

  • Spring 기반 실시간 데이터 처리 백엔드 개발
  • 이상 이력과 제어 이력 사이의 처리 순서 오류 분석
  • 저장·제어·알림의 실행 순서를 다시 정의하고 처리 흐름 재설계
  • Kafka 메시지를 DB 저장과 제어 완료 이후에만 처리 완료로 확정하도록 수동 ACK 적용
  • 처리 중 예외 발생 시 동일 메시지를 다시 처리할 수 있도록 실패 경계와 재처리 가능성 설계
  • 단위·기능·통합·E2E 테스트 및 장시간 부하 조건에서 수정 구조 검증 참여
  • Jira·Confluence, 데일리 스크럼과 코드 리뷰를 활용한 이슈 공유 및 문서화 협업

제가 이 프로젝트에서 가장 중요하게 본 기준

메시지가 도착했다고 해서 한 건의 업무가 끝난 것은 아닙니다.
어떤 단계까지 완료되어야 정상 처리인지, 중간에 실패하면 어디서 다시 시작할지를 함께 설계해야 했습니다.


4. 팀원 구성 👥

이름 담당 영역 주요 역할
정주영 Infra DevOps, Jenkins CI
조수빈 Infra DevOps, Data Stream
이상훈 Infra Kubernetes, ArgoCD, Terraform
김우영 IoT Sensor Simulator, Wearable, Backend
정민석 IoT Sensor Simulator, Backend
유승희 ML Machine Learning, MLOps, Backend
김예인 Service Web Design, Frontend
윤다인 Service Backend / 웹 서비스 기획·개발·운영

5. 시스템 아키텍처 🏗️

전체 시스템 구성

Monitory System Architecture

Monitory는 공장 내부의 센서와 작업자 웨어러블에서 발생하는 데이터를 AWS 기반 데이터 스트림으로 수집하고, 실시간 처리·모니터링·제어·예지보전 기능으로 연결했습니다.

데이터 처리 흐름

IoT Sensor / Wearable
        │
        ▼
AWS IoT Core
        │
        ▼
Amazon Kinesis
        │
        ▼
Apache Flink
        │
        ▼
Apache Kafka
        │
        ├──────── Backend
        │            │
        │            ├─ 상태 판단
        │            ├─ 이상 이력 저장
        │            ├─ 자동 제어
        │            └─ 실시간 알림
        │
        ├──────── InfluxDB / Grafana
        │
        └──────── S3 / ML Pipeline

주요 Repository

Fac2Real
├── monitory-be              # Spring Boot Backend
├── monitory-fe              # React Frontend
├── monitory-model-server    # FastAPI Model Server
├── monitory-data-source     # Sensor / Data Source
├── monitory-test            # Test / Verification
└── monitory-iac             # Infrastructure as Code
Repository 설명
monitory-be Spring Boot Backend
monitory-fe React Frontend
monitory-model-server FastAPI Model Server
monitory-data-source Sensor / Data Source
monitory-test Test / Verification
monitory-iac Infrastructure as Code

ER Diagram

ER Diagram 펼쳐보기

ER Diagram


6. 기술 구성 🚀

아래는 프로젝트 전체 기술 구성입니다.
개인이 직접 수행한 영역은 앞의 담당 역할 및 기여와 트러블 슈팅에서 별도로 구분했습니다.

Backend 🖥️

  • Java / Spring Boot
    실시간 이벤트 처리와 이상 이력·제어·알림 관련 도메인 로직 및 운영 API 구성

  • Kafka
    환경·설비·작업자 데이터를 비동기 메시지로 전달하는 실시간 처리 파이프라인 구성

  • Manual ACK
    메시지를 받은 시점이 아니라 실제 처리 완료 이후에 오프셋을 커밋해 실패 시 재처리 가능성을 확보

  • WebSocket / STOMP
    위험도와 알림 상태를 운영 화면에 실시간 전달

  • Flyway
    ddl-auto: none 환경에서 SQL Migration을 기준으로 DB 변경 이력 관리

Real-time Processing ⚡

실시간 처리 구조 펼쳐보기
  • ConcurrentHashMap과 AtomicIntegerArray 기반 In-Memory 상태 관리
  • 공간·센서·작업자 위험 상태 변화 시 DB 기록
  • Kafka Consumer와 WebSocket 전송을 별도 스레드로 분리
  • 위험 레벨별 알림 채널을 전략 패턴으로 구성

Data Pipeline ☁️

데이터 파이프라인 펼쳐보기
  • AWS IoT Core / MQTT: IoT 센서 데이터 수집
  • Kinesis: 실시간 데이터 스트림 수집
  • Apache Flink: 스트림 처리 및 데이터 변환
  • Kafka: 목적별 실시간 메시지 전달
  • InfluxDB / Grafana: 시계열 데이터 저장 및 모니터링

ML Pipeline 🤖

ML Pipeline 펼쳐보기
  • S3에 저장된 설비 데이터를 기반으로 예측 파이프라인 수행
  • SQS 이벤트를 활용해 데이터 준비 시점과 예측 실행을 연결
  • FastAPI 기반 Model Server
  • LightGBM 기반 잔존 수명(RUL) 예측

DevOps 🚀

CI/CD · Infrastructure 펼쳐보기
  • Jenkins: Test, JaCoCo, Build, Docker Image Build, ECR Push
  • ArgoCD / Helm: GitOps 기반 배포 상태 관리
  • Kubernetes: 서비스 실행 환경 구성
  • Terraform: AWS Infrastructure as Code
  • Docker / ECR: 컨테이너 이미지 관리

7. 트러블 슈팅 🛠️

⭐ 01. 저장이 끝나기 전에 제어가 실행되던 문제

개인 핵심 트러블슈팅 경험

🔴 Problem

위험 신호가 발생하면 먼저 AbnormalLog를 저장하고, 해당 이상에 대응한 ControlLog를 남겨야 했습니다.

하지만 이상 이력의 ID가 확정되기 전에 제어 로직이 실행되면서 어떤 이상에 어떤 제어가 수행됐는지 기록의 연결이 깨지는 문제가 발생했습니다.

ControlLog는 @MapsId를 사용해 AbnormalLog의 PK를 공유하고 있었기 때문에 부모 이력이 먼저 저장되어야 다음 처리가 가능했습니다.

🟡 Attempt 1 · 하나의 트랜잭션으로 묶기

SensorEventProcessor.process() 전체를 하나의 @Transactional 범위로 묶었습니다.

결과

Consumer 스레드의 영속성 컨텍스트와 충돌하면서 동일한 저장 오류가 이어졌습니다.

🟡 Attempt 2 · 트랜잭션 분리

REQUIRES_NEW를 적용해 이상 이력 저장을 별도 트랜잭션으로 분리했습니다.

결과

기존 트랜잭션에서 조회한 엔티티가 새 트랜잭션에서는 분리된 상태가 되면서 영속성 관련 예외가 다시 발생했습니다.

🔍 Root Cause

두 방법이 모두 실패한 뒤 트랜잭션 설정 대신 데이터가 언제 확정되고 다음 처리가 언제 시작되는지를 다시 확인했습니다.

ID 생성 시점과 제어 호출 순서를 따라가면서 실행 흐름 자체에 문제가 있다는 것을 확인했습니다.

기존 처리

이상 감지
   │
   ├─ 후속 처리 시작
   ├─ 제어 실행
   └─ 이상 이력 확정


개선 처리

이상 이력 저장
   │
   ▼
자동 제어
   │
   ▼
운영자 알림

🟢 Solution

DB 관련 처리가 완료된 뒤에 알림이 실행되도록 처리 순서를 다시 구성했습니다.

autoControlService.evaluate(dto, abnLog, dangerLevel);   // 저장·제어
alarmEventService.startAlarm(dto, abnLog, dangerLevel);  // 알림

Kafka에는 수동 ACK를 적용했습니다.

DB 저장과 제어가 모두 정상적으로 끝난 뒤에만 메시지를 처리한 것으로 확정하고, 중간에 예외가 발생하면 ACK를 남기지 않아 동일 메시지를 다시 처리할 수 있도록 했습니다.

✅ Result

  • AbnormalLog · ControlLog · 알림의 실행 순서를 명확히 정의
  • 처리 도중 실패해도 메시지를 다시 처리할 수 있는 구조 확보
  • 수정된 흐름을 단위·기능·통합·E2E 및 장시간 부하 조건에서 검증

이 경험을 통해 실시간 시스템에서는 메시지 수신 시점보다 업무 처리 완료의 기준을 먼저 정의해야 한다는 것을 배웠습니다.


02. WebSocket 전송과 Consumer 처리 분리

상세 내용 펼쳐보기

Kafka Consumer가 이벤트 처리와 WebSocket I/O를 같은 흐름에서 수행하면 전송 지연이 다음 메시지 처리에 영향을 줄 수 있었습니다.

ThreadPoolTaskExecutor 기반의 별도 실행 환경을 두고 WebSocket 전송을 비동기로 분리했습니다.

Kafka Consumer

이벤트 처리
상태 판단
     │
     └─ WebSocket 전송 요청
                 │
                 ▼
        websocketExecutor
                 │
                 ▼
          운영 화면 전송

비동기 처리 중 발생하는 예외를 확인할 수 있도록 별도 예외 처리도 구성했습니다.

프로젝트 코드·Git 이력에서 확인되는 팀 단위 적용 사례입니다.


03. Polling 기반 설비 예측을 이벤트 기반으로 전환

상세 내용 펼쳐보기

기존 방식에서는 스케줄러가 일정 시간마다 설비 데이터를 확인했습니다.

S3에 새로운 데이터가 저장되는 시점과 예측 실행 시점을 연결하기 위해 S3 이벤트와 SQS Listener 기반 구조를 적용했습니다.

Before

Scheduler
   │
   └─ 주기적으로 데이터 확인


After

S3 Upload
   │
   ▼
SQS Event
   │
   ▼
Listener
   │
   ▼
Prediction

새로운 데이터가 준비되는 시점에 필요한 작업을 실행하는 이벤트 기반 구조로 전환했습니다.

프로젝트 코드·Git 이력에서 확인되는 팀 단위 적용 사례입니다.


04. 날짜 경계 차이로 발생한 조회 결과 불일치

상세 내용 펼쳐보기

날짜 범위를 조회하는 두 API에서 서로 다른 시간 기준을 사용하면서 그래프와 상세 로그의 결과가 다르게 나타나는 문제가 있었습니다.

날짜 단위 조회의 시작과 종료 시점을 명확하게 지정했습니다.

LocalDateTime start =
    LocalDate.now().minusDays(N).atStartOfDay();

LocalDateTime end =
    LocalDate.now().minusDays(1).atTime(LocalTime.MAX);

두 API가 동일한 날짜 경계를 기준으로 조회하도록 맞추면서 데이터 불일치를 해소했습니다.

프로젝트 코드·Git 이력에서 확인되는 팀 단위 적용 사례입니다.


8. 성능·신뢰성 검증 🧪

Test & Verification

Test Result

검증 항목 결과
단위 테스트 190건
테스트 커버리지 약 70%
기능 테스트 57건
E2E 시나리오 2건

E2E 시나리오

  • 중합설비 과열
  • 탈휘 가스 누출

추가 검증

  • Data Sink 데이터 유실 여부 확인
  • IoT Core / Kafka 메시지 형식 검증
  • Topic 전달 정확성 확인
  • 내부 처리 로직 통합 검증

테스트 수치는 프로젝트 전체의 검증 결과입니다.


📈 Load Test

Load Test

테스트 조건

Sensor          100개
Interval        5초
Duration        7시간

100 × 12회/분 × 420분
≈ 504,000건

검증 결과

항목 결과
처리 규모 약 50만 건
CPU 사용률 약 30%
응답시간 100ms 이내

장시간 데이터가 지속해서 유입되는 조건에서 지연·누락·최종 저장 결과와 자원 사용량을 함께 확인했습니다.

성능 수치는 프로젝트 전체 아키텍처와 데이터 스트림을 대상으로 한 팀 단위 검증 결과입니다.


프로젝트에 적용된 추가 개선

In-Memory 상태 관리

고빈도 이벤트가 발생하는 상황에서 공간·센서·작업자의 현재 위험 상태를 메모리에서 관리하고, 상태가 변경되는 시점에 필요한 데이터를 기록하도록 구성했습니다.

ConcurrentHashMap과 AtomicIntegerArray 기반 구조가 사용됐습니다.

위험 레벨별 알림 구조

INFO / WARNING / CRITICAL 등 위험 단계에 따라 다른 알림 정책을 적용할 수 있도록 전략 패턴 기반 구조를 적용했습니다.

새로운 알림 채널을 추가할 때 기존 로직에 미치는 영향을 줄일 수 있도록 역할을 분리했습니다.

Flyway 기반 DB 변경 이력 관리

ddl-auto: none 환경에서 Flyway Migration을 DB 변경 이력의 기준으로 사용했습니다.

프로젝트에는 V1~V16 범위에서 총 20개의 Migration SQL이 관리됐으며, PK/FK 변경과 데이터 선처리 등 요구사항 변화에 따른 스키마 변경을 Git 이력으로 남겼습니다.


9. 프로젝트 사용 도구 🛠️

영역 도구
형상 관리 Git, GitHub
이슈 / 일정 관리 Jira
문서화 / 협업 Confluence
협업 방식 Agile, Daily Scrum, Retrospective, Code Review
Monitoring Grafana, Prometheus
CI Jenkins, JaCoCo
CD / GitOps ArgoCD, Helm
Container / Infra Docker, Kubernetes, Terraform
Load Test Locust

외부 서비스 🌐

영역 서비스
IoT / Stream AWS IoT Core, Amazon Kinesis
Messaging Apache Kafka, Amazon SQS
Storage AWS S3
Container Registry AWS ECR
Database AWS RDS, InfluxDB
Mobile Push Firebase Cloud Messaging
Notification AWS SNS
Model Serving FastAPI

10. 개발 및 배포 방식 📚

Agile Sprint 📈

Sprint 기간 주요 목표
Sprint 0 04.15 ~ 04.25 프로젝트 설계, PoC
Sprint 1 04.27 ~ 05.12 작업 환경 관리 기능
Sprint 2 05.13 ~ 05.26 작업자 안전관리 기능
Sprint 3 05.27 ~ 06.09 설비 예측·정비 기능
Sprint 4 06.10 ~ 06.23 테스트 및 산출물 정리
  • 데일리 스크럼을 통해 진행 상황과 이슈를 공유했습니다.
  • Jira와 Confluence로 요구사항, 담당 작업과 변경 내용을 관리했습니다.
  • 코드 리뷰와 회고를 통해 구현 결과와 개선 사항을 함께 확인했습니다.

DB Migration Convention 🗃️

  • JPA ddl-auto 대신 Flyway SQL 파일을 변경 이력의 기준으로 사용
  • 적용된 Migration 파일은 유지하고 새로운 버전 파일로 변경 사항 관리
  • PK/FK 변경 시 제약 조건과 기존 데이터 영향을 함께 확인
  • 잘못된 스키마 변경이 다음 환경으로 넘어가지 않도록 변경 이력 관리

CI/CD · GitOps 🚀

Application Repository
        │
        ▼
     Jenkins
        │
        ├─ Test + JaCoCo
        ├─ Build
        ├─ Docker Image Build
        └─ AWS ECR Push
                │
                ▼
Infrastructure Repository
                │
                └─ Helm values
                   Image Tag = Git Commit Hash
                            │
                            ▼
                         ArgoCD
                            │
                            ├─ Sync
                            └─ Health Check

CI/CD Architecture

  • 애플리케이션 저장소와 인프라 저장소를 분리했습니다.
  • Docker 이미지 태그에 Git 커밋 해시를 사용해 배포 버전을 추적했습니다.
  • Jenkins가 빌드·테스트 이후 인프라 저장소의 Helm 설정을 갱신했습니다.
  • ArgoCD가 Git 변경 사항을 감지해 배포하고 Health Check로 상태를 확인했습니다.

CI/CD 및 인프라 구성은 프로젝트 전체 아키텍처입니다.


11. What I Learned 💭

이 프로젝트에서 가장 크게 배운 것은 실시간 시스템에서 메시지를 받는 것과 처리를 끝내는 것은 다르다는 점입니다.

한 건의 데이터가 들어온 뒤 저장, 제어, 알림이 서로 연결되어 있다면 각 단계의 실행 순서와 실패 시 동작까지 함께 정의해야 했습니다.

두 번의 수정이 실패한 뒤에는 설정을 계속 바꾸는 대신 실제 ID 생성 시점과 실행 순서를 다시 확인했습니다. 그 과정에서 문제의 원인을 처리 흐름에서 찾았고, 저장과 제어가 끝난 뒤에만 메시지를 완료 처리하도록 기준을 다시 세웠습니다.

수정 이후에는 단위·기능·통합·E2E 테스트와 장시간 부하 조건에서 결과를 확인했습니다.

이 프로젝트 이후 개발할 때 확인하는 기준

  • 한 건의 처리는 어디까지 끝나야 완료인가
  • 중간 단계에서 실패하면 어디에서 다시 처리할 것인가
  • 한 구성요소의 변경이 다음 처리에 어떤 영향을 주는가
  • 수정한 구조가 실제 운영과 유사한 조건에서도 같은 결과를 만드는가

기능 구현 이후의 실패 조건·재처리·변경 영향·검증 결과까지 설명할 수 있는 개발자

Monitory를 통해 세운 개발 기준입니다.


LG CNS AM Inspire Camp 1기 · Team FactoReal
Service Team · Backend Developer
윤다인

About

산업 현장의 센서 데이터를 실시간으로 수집·처리하고, 위험 판단·제어·알림까지 연결한 모니터링 시스템

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors