아키텍처 개요
Caffeine은 .NET 10 기반의 AI-Native IIoT 엣지 플랫폼으로, 제조 현장의 OT 데이터를 수집, 처리, 분석하는 Full-Stack 솔루션이다. Reactive Programming(System.Reactive)과 Zero-Allocation Architecture를 핵심으로, 드라이버 플러그인부터 Blazor/MAUI UI까지 포괄한다.
4-Tier 시스템 아키텍처
Caffeine은 명확한 4계층 구조로 설계되어 있으며, 각 계층은 독립적으로 배포 및 확장이 가능하다.
계층별 역할
| 계층 | 프로젝트 | 역할 |
|---|---|---|
| Presentation | Admin, Mobile, WPF, CLI, Client SDK | 사용자 인터페이스 및 외부 연동 |
| Engine | Caffeine.Engine | 중앙 오케스트레이터. gRPC, SignalR, GraphQL, REST, MQTT, Kafka 통합 |
| Edge | Caffeine.Bridge.Host | 엣지 게이트웨이. 드라이버를 동적 로드하여 장비와 직접 통신 |
| Driver | Caffeine.Drivers.* | IDriverModule 인터페이스 구현. 산업 프로토콜 플러그인 |
프로젝트 의존성 그래프
아래 다이어그램은 각 .csproj 파일의 ProjectReference를 기반으로 작성한 정확한 의존성 관계이다.
핵심 의존성 규칙
- Caffeine.Core -- 최하위 기반 모듈. 엔티티, 인터페이스, 값 객체 정의. 외부 NuGet 최소화 (
System.Reactive등) - Caffeine.IPC -- gRPC/Protobuf 계약 정의. 프로젝트 참조 없이 독립적
- Caffeine.Licensing -- 라이선스 검증 모듈. Release 빌드 시 Obfuscar 난독화 자동 적용
- Caffeine.Infrastructure -- Core + Licensing에만 의존. 외부 서비스 어댑터 구현 (Redis, InfluxDB, TypeDB, Kafka, ML.NET)
- Caffeine.Engine -- Core + IPC + Infrastructure를 조합하는 중앙 오케스트레이터
- Caffeine.Admin -- Composition Root. Engine, Identity, AI, Simulation, UI를 모두 조합
- Caffeine.Client -- 외부 연동용 SDK. 내부 ProjectReference 없이 Protobuf 복사본으로 독립 빌드
- Caffeine.Drivers.* -- Core에만 의존. Bridge.Host에서 동적 DLL 로드 (Plugin Architecture)
데이터 흐름
OT 데이터 수집 파이프라인
장비에서 수집된 OT 데이터가 저장소까지 전달되는 흐름이다.
실시간 모니터링 데이터 Push
Engine에서 Admin 대시보드로 실시간 데이터를 전달하는 흐름이다.
핵심 컴포넌트
Caffeine.Core
역할: 프레임워크의 핵심 도메인 모듈
IDriverModule-- 드라이버 플러그인 인터페이스 정의TagManager-- 태그 생명주기 관리 (ConcurrentDictionary 기반 Lock-free)- Abstractions 네임스페이스 -- IoT, Engine, Services, Persistence, Messaging 인터페이스
System.Reactive기반 Reactive 데이터 파이프라인
Caffeine.Engine
역할: 중앙 오케스트레이터 (Worker Service)
통신 프로토콜:
- gRPC (Port 5050) -- Bridge와의 고성능 양방향 통신
- REST API (Port 5001) -- Swagger UI 지원, API Versioning (v1)
- SignalR --
/hubs/alarms,/hubs/monitoring실시간 Push - GraphQL --
/graphql(HotChocolate, Query/Mutation/Subscription) - MQTT -- MqttListenerService를 통한 장비 메시지 수신
- Kafka -- 이벤트 스트리밍 (Producer/Consumer)
백그라운드 워커:
| 워커 | 역할 |
|---|---|
IngestionWorker | 데이터 수집 파이프라인 구동 |
HistorianService | 시계열 데이터 InfluxDB 저장 |
ReasoningService | AI 추론 및 이상 감지 |
AlarmManagerService | 알람 관리 V2 |
AlarmService | Reactive Extensions 기반 온도 알람 |
HealthCheckAlertService | Health Check 기반 알림 |
RedisBulkService | Redis 대량 쓰기 |
MqttListenerService | MQTT 메시지 리스너 |
SecsGemService | SECS/GEM 시뮬레이션 연동 |
ModelLoaderService | 시작 시 태그 모델 로드 |
TagStreamingService | 실시간 태그 값 브로드캐스트 |
MetricReporterService | Prometheus 메트릭 수집 |
BackgroundLicenseMonitorService | 라이선스 상태 모니터링 |
Caffeine.Infrastructure
역할: 외부 서비스 어댑터 (DI 등록: AddCaffeineInfrastructure())
| 분류 | 서비스 | 용도 |
|---|---|---|
| Data Store | RedisService / RedisBackedRepository | 실시간 데이터 캐시, Shadow Repository |
| Data Store | InfluxDbTraceWriter | 시계열 데이터 저장 (Graceful Degradation 지원) |
| Data Store | TypeDbRealClient | 지식 그래프 (Lazy Connection) |
| Data Store | SqliteAlarmRepository | 알람 이력 저장 |
| Messaging | NullMessageProducer | Kafka 미연결 시 No-op 폴백 (Null Object Pattern) |
| Messaging | RxEventBus | In-Memory Reactive 이벤트 버스 |
| ML | FeatureExtractor, FailurePredictionService | 예측 정비 (ML.NET) |
| ML | AnomalyDetectionService | 이상 감지 |
| ML | RulPredictionService | 잔여 수명 예측 |
| Alerting | EmailNotificationChannel | 이메일 알림 (MailKit) |
| Alerting | TeamsNotificationChannel | Microsoft Teams 알림 |
| Alerting | PrometheusAlertConverter | Alertmanager 통합 |
| Observability | OpenTelemetry + Prometheus | 메트릭 수집 및 노출 |
Caffeine.Drivers.*
역할: 산업 프로토콜 드라이버 컬렉션 (Plugin Architecture)
| 드라이버 | 프로토콜 | 용도 | 비고 |
|---|---|---|---|
Caffeine.Drivers.SecsGem | SECS/GEM | 반도체 장비 통신 | 빌드 후 Bridge/drivers에 자동 복사 |
Caffeine.Drivers.Simulation | Simulated | 개발/테스트용 가상 장비 | 빌드 후 Bridge/drivers에 자동 복사 |
Caffeine.Drivers.Lse | LSE | LSE 프로토콜 장비 | |
Caffeine.Drivers.Mitsubishi | MELSEC | Mitsubishi PLC | Source Generator 사용 |
Caffeine.Drivers.Omron | FINS | Omron PLC |
드라이버는 IDriverModule 인터페이스를 구현하며, Bridge.Host가 런타임에 drivers/ 디렉토리에서 DLL을 동적 로드한다.
Caffeine.Client SDK
역할: 외부 애플리케이션 연동용 독립 SDK (NuGet 패키지)
- gRPC --
public_api.proto기반 타입 안전 호출 - SignalR -- 실시간 태그 구독
- 내부 프로젝트 참조 없이 독립적으로 빌드 (Protobuf 복사본 포함)
Caffeine.Generators
역할: Roslyn Source Generator (netstandard2.0)
- 컴파일 타임 직렬화 코드 생성
- Mitsubishi 드라이버에서 Analyzer로 참조
기술 스택 요약
| 분류 | 기술 |
|---|---|
| 런타임 | .NET 10 (net10.0), Source Generator는 netstandard2.0 |
| 통신 | gRPC, SignalR, GraphQL (HotChocolate), REST/Swagger, MQTT (MQTTnet), Kafka |
| 시계열 DB | InfluxDB 2.7 |
| 지식 그래프 | TypeDB (Vaticle) |
| 캐시 | Redis (StackExchange.Redis) |
| 관계형 DB | SQLite (EF Core) -- 알람, 감사 로그, Identity |
| AI/ML | ONNX Runtime, ML.NET (TimeSeries, Anomaly Detection) |
| Observability | Serilog, OpenTelemetry, Prometheus, Grafana, HealthChecks UI |
| UI | Blazor Server + MudBlazor 7.0, Plotly.Blazor |
| 보안 | ASP.NET Core Identity, JWT Bearer, ExceptionHandlingMiddleware, PKV License |
| CLI | System.CommandLine, Spectre.Console |
| 빌드 | Roslyn Source Generator, Obfuscar (Release 난독화) |
| 배포 | Docker Compose, Kubernetes |
보안 아키텍처
Caffeine은 다계층 보안 모델을 적용하여 인증, 인가, 네트워크 보안, 라이선스 검증을 포괄한다.
인증 및 인가
구현 상세:
| 보안 레이어 | 구현 | 설명 |
|---|---|---|
| 사용자 인증 | ASP.NET Core Identity + JWT | HMAC-SHA256 서명, 3시간 토큰 유효기간 |
| 역할 기반 인가 | RBAC (Administrator, Operator, Viewer) | Identity 시드에서 역할 초기화 |
| Bridge 인증 | ConfigBasedAuthenticator | Master API Key 기반 (환경변수 우선) |
| 전역 예외 처리 | ExceptionHandlingMiddleware | 내부 에러 상세 노출 차단, 일관된 ApiErrorResponse 반환 |
| 전송 암호화 | TLS / HTTPS | 프로덕션 환경 HTTPS 리다이렉션, HSTS (365일) |
| 데이터 암호화 | EncryptionService | AES-256 기반 민감 데이터 암호화 |
| 라이선스 검증 | Caffeine.Licensing (PKV) | 머신 바인딩 + JWT 토큰 검증, Release 빌드 Obfuscar 난독화 |
| 감사 로그 | AuditLogMiddleware + SQLite | 모든 요청에 대한 감사 추적 |
라이선스 검증 흐름
BackgroundLicenseMonitorService가 주기적으로 라이선스 상태를 확인MachineInfoProvider가 하드웨어 정보를 수집하여 머신 바인딩 검증- Release 빌드에서
NO_LICENSE상수 사용을 MSBuild Target으로 차단
배포 아키텍처
Docker Compose (개발/테스트)
서비스 구성
| 서비스 | 이미지 | 포트 | 역할 |
|---|---|---|---|
caffeine-engine | Custom Build | 5001 (HTTP), 5050 (gRPC), 5002 (SECS/GEM) | 중앙 오케스트레이터 |
caffeine-bridge-01 | Custom Build | - | 엣지 게이트웨이 |
caffeine-admin | Custom Build | 8080 | Blazor 관제 대시보드 |
caffeine-redis | redis:alpine | 6379 | 실시간 데이터 캐시 |
caffeine-influxdb | influxdb:2.7 | 8086 | 시계열 데이터 저장 |
caffeine-typedb | vaticle/typedb:latest | 1729 | 지식 그래프 |
caffeine-kafka | confluentinc/cp-kafka:7.4.0 | 9092 | 이벤트 스트리밍 |
caffeine-mqtt | eclipse-mosquitto:2.0 | 1883, 9001 | MQTT 메시지 브로커 |
caffeine-grafana | grafana/grafana:latest | 3000 | 시각화 대시보드 |
caffeine-simulator-01 | Custom Build | - | 장비 시뮬레이터 |
Observability
Health Check 엔드포인트
| 엔드포인트 | 용도 |
|---|---|
/health | 전체 상태 (Liveness + Readiness) |
/health/live | Liveness Probe (자체 상태) |
/health/ready | Readiness Probe (외부 의존성 포함) |
/healthchecks-ui | Engine Health Checks UI |
/health-ui | Admin Health Checks UI |
/metrics | Prometheus 메트릭 |
로깅
- Serilog -- 구조화된 로깅 (Console + SQLite Sink)
- OpenTelemetry -- 분산 추적, ASP.NET Core / HTTP / Runtime 계측
- Prometheus Exporter --
/metrics엔드포인트
성능 최적화
Lock-Free 아키텍처
ConcurrentDictionary기반 태그 관리 (Lock 경합 제거)- 처리량: 50,000 tags/sec, 지연시간: 5ms 이하
Channel 기반 비동기 파이프라인
// Producer (IngestionService)
await _channel.Writer.WriteAsync(tagData);
// Consumer (IngestionWorker)
await foreach (var data in _channel.Reader.ReadAllAsync())
{
await ProcessAsync(data);
}
System.Threading.Channels로 Producer-Consumer 패턴 구현- 백프레셔(Backpressure) 자동 처리
- Zero-Allocation 최적화
Reactive Extensions (System.Reactive)
- 데이터 스트림 변환, 필터링, 집계를 선언적으로 처리
AlarmService에서 실시간 온도 모니터링에 적용
확장성
수평 확장
- Engine: Stateless 설계, Redis로 상태 공유하여 다중 인스턴스 운영 가능
- Bridge: 장비 그룹별 독립 배포, Engine과 gRPC로 연결
- Kafka: 이벤트 파티셔닝을 통한 처리량 분산
수직 확장 기준
| 태그 수 | CPU | RAM | Redis | InfluxDB |
|---|---|---|---|---|
| ~1,000 | 2 Core | 4 GB | 2 GB | 10 GB |
| ~10,000 | 4 Core | 8 GB | 4 GB | 50 GB |
| ~100,000 | 8 Core | 16 GB | 8 GB | 200 GB |
다음 단계
이전: 프레임워크 소개 ← | 다음: 설치 가이드 →