1022 lines
53 KiB
Markdown
1022 lines
53 KiB
Markdown
# A2A-gRPC 이중 계층 엣지 AIoT 멀티 에이전트 통신 프레임워크
|
||
## 시스템 설계 명세 (System Design Specification)
|
||
|
||
**버전**: 1.0.0
|
||
**작성일**: 2026-06-07
|
||
**대상 독자**: 분산 시스템 설계자, 엣지 AIoT 아키텍트, AI 에이전트 개발자
|
||
|
||
---
|
||
|
||
## 목차
|
||
|
||
1. [설계 원칙](#1-설계-원칙-design-principles)
|
||
2. [시스템 아키텍처 개요](#2-시스템-아키텍처-개요)
|
||
3. [계층별 설계 명세](#3-계층별-설계-명세)
|
||
4. [T2 엣지 게이트웨이 상세 설계](#4-t2-엣지-게이트웨이-상세-설계)
|
||
5. [에이전트 상호작용 프로토콜](#5-에이전트-상호작용-프로토콜)
|
||
6. [데이터 흐름 설계](#6-데이터-흐름-설계)
|
||
7. [장애 내성 설계](#7-장애-내성-설계)
|
||
8. [멀티테넌시 설계](#8-멀티테넌시-설계)
|
||
9. [관측성 설계](#9-관측성-설계)
|
||
10. [사례별 설계 적용](#10-사례별-설계-적용)
|
||
|
||
---
|
||
|
||
## 1. 설계 원칙 (Design Principles)
|
||
|
||
본 시스템의 모든 아키텍처 결정은 다음 7가지 guiding principle에 근거한다. 각 원칙은 엣지 AIoT의 물리적 이질성과 다중 에이전트 협업의 복잡성에서 도출되었다.
|
||
|
||
### P1. Tier-Appropriate Protocol (계층 적합 프로토콜)
|
||
각 tier는 자신의 자원·연결성·전력 제약에 최적화된 프로토콜을 사용한다. T1 클라우드에는 gRPC/HTTP-2, T2 엣지에는 gRPC over QUIC, T3 현장 디바이스에는 MQTT/CoAP/BLE를 적용한다. **단일 프로토콜로 3-tier 전체를 포괄하려는 설계는 거부한다.** 이는 임베디드 디바이스에 gRPC 풀스택을 강제할 때 발생하는 RAM·Flash 초과 문제와, 클라우드 서버에 MQTT를 사용할 때 발생하는 스키마 안전성 부재 문제를 동시에 해결하는 근거다.
|
||
|
||
### P2. Semantic-Transport Separation (시맨틱-전송 분리)
|
||
에이전트 간 "무엇을 할 것인가(Task 위임·역량 광고)"와 "어떻게 전달할 것인가(Byte 전송)"를 명확히 분리한다. A2A/MCP는 시맨틱 계층에서 동작하고, gRPC/MQTT/CoAP는 전송 계층에서 동작한다. 이 분리는 전송 프로토콜을 교체해도 에이전트 협업 로직이 영향받지 않도록 보장한다.
|
||
|
||
### P3. Hardware-Rooted Identity (하드웨어 기반 신원)
|
||
네트워크 주소(IP, MAC)나 소프트웨어 토큰만으로는 물리적 디바이스의 신원을 보장할 수 없다. 모든 신원 클레임은 TPM/Secure Element의 하드웨어 attestation 또는 Kubernetes Service Account 바인딩에 뿌리를 두어야 한다. SPIFFE/SPIRE가 이 하드웨어 신원을 동적 SVID로 추상화하여 상위 계층에 전달한다.
|
||
|
||
### P4. Fail-Locally, Resume-Globally (국소 실패, 전역 재개)
|
||
T3 디바이스와 T2 게이트웨이 사이의 단절은 예외가 아닌 정상 운영 조건이다. 단절 발생 시 T3 디바이스는 로컬 큐에 데이터를 보존하고, 재접속 시 Resume Token으로 마지막 위치부터 이어받는다. 이 원칙은 단절을 "복구해야 할 장애"가 아닌 "흡수해야 할 물리적 현실"로 취급한다.
|
||
|
||
### P5. Defense in Depth (다층 보안)
|
||
보안 통제는 인프라 계층(Envoy Service Mesh, mTLS)과 애플리케이션 계층(gRPC Interceptor, RBAC)에 중복 배치한다. 어느 한 계층이 우회되더라도 다른 계층이 보호를 지속한다. T3 디바이스의 물리적 접근 가능성을 고려하여, 디바이스 변조 시 즉시 SVID를 폐기할 수 있는 동적 인증서 회전 메커니즘을 포함한다.
|
||
|
||
### P6. Observable by Default (기본 관측성)
|
||
관측성(Tracing, Metrics, Logging)은 사후에 추가하는 기능이 아니라 프레임워크의 기본 구성 요소다. W3C traceparent는 T1→T2→T3 전 경로에 걸쳐 gRPC Metadata로 전파되며, T2 게이트웨이는 trace context의 fan-out 지점으로 작동한다. 관측성 없는 배포는 설계상 불가능하다.
|
||
|
||
### P7. Schema-First Interoperability (스키마 우선 상호운용)
|
||
다수의 디바이스 클래스, 언어, 런타임이 공존하는 환경에서 상호운용성은 Protocol Buffers `.proto` 파일을 단일 진실 원천(Single Source of Truth)으로 삼는 Contract-First 접근으로만 보장된다. Buf Schema Registry(BSR)와 `buf breaking` CI 검증이 OTA 업데이트 중에도 하위 호환성을 자동으로 강제한다.
|
||
|
||
---
|
||
|
||
## 2. 시스템 아키텍처 개요
|
||
|
||
### 2.1 3-Tier 전체 조감도
|
||
|
||
```
|
||
╔══════════════════════════════════════════════════════════════════════════════╗
|
||
║ T1: CLOUD TIER (k8s / GPU 서버 / 데이터센터) ║
|
||
║ ║
|
||
║ ┌─────────────┐ ┌─────────────┐ ┌──────────────┐ ┌──────────────────┐ ║
|
||
║ │ LLM Agent │ │ PM / Planner│ │ Analytics │ │ A2A Orchestrator │ ║
|
||
║ │ (GPT/Claude│ │ Agent │ │ Agent │ │ (Task Registry) │ ║
|
||
║ │ /Gemini) │ │ │ │ │ │ │ ║
|
||
║ └──────┬──────┘ └──────┬──────┘ └──────┬───────┘ └────────┬─────────┘ ║
|
||
║ └────────────────┴─────────────────┴──────────────────┘ ║
|
||
║ │ A2A Protocol (Agent Cards / Tasks) ║
|
||
║ ┌──────────────────────────────────────────────────────────────────────┐ ║
|
||
║ │ Istio Service Mesh + Envoy Proxy + OTel Collector + SPIRE Server │ ║
|
||
║ │ OAuth2 + JWKS mTLS (k8s SA SPIFFE ID) Prometheus + Jaeger │ ║
|
||
║ └──────────────────────────────────────────────────────────────────────┘ ║
|
||
╚══════════════════════════════════════════╦═══════════════════════════════════╝
|
||
║
|
||
gRPC over QUIC (HTTP/3) / gRPC over HTTP/2
|
||
W3C traceparent in gRPC Metadata
|
||
mTLS + SPIFFE SVID
|
||
║
|
||
╔══════════════════════════════════════════╩═══════════════════════════════════╗
|
||
║ T2: EDGE TIER (Jetson / RK3588 / 산업용 PC / 5G MEC) ║
|
||
║ ║
|
||
║ ┌──────────────────────────────────────────────────────────────────────┐ ║
|
||
║ │ T2 EDGE GATEWAY (핵심 컴포넌트) │ ║
|
||
║ │ │ ║
|
||
║ │ ┌────────────┐ ┌─────────────┐ ┌──────────┐ ┌────────────────┐ │ ║
|
||
║ │ │ Protocol │ │ Message │ │ Buffer / │ │ Resume Token │ │ ║
|
||
║ │ │ Translator │ │ Normalizer │ │ Batcher │ │ Manager │ │ ║
|
||
║ │ │ MQTT↔gRPC │ │ JSON↔Protob │ │ Fan-in │ │ (disconnect) │ │ ║
|
||
║ │ └────────────┘ └─────────────┘ └──────────┘ └────────────────┘ │ ║
|
||
║ │ ┌────────────┐ ┌─────────────┐ │ ║
|
||
║ │ │ Device │ │ Metrics │ A2A Endpoint (SSE / Webhook) │ ║
|
||
║ │ │ Auth Relay │ │ Collector │ gRPC Interceptor (Trace Inject) │ ║
|
||
║ │ │ SVID Verify│ │ Prom→OTel │ │ ║
|
||
║ │ └────────────┘ └─────────────┘ │ ║
|
||
║ └──────────────────────────────────────────────────────────────────────┘ ║
|
||
║ ║
|
||
║ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────────────────┐ ║
|
||
║ │ Edge Infer. │ │ Local LLM │ │ Envoy Edge Proxy (xDS Light) │ ║
|
||
║ │ Agent │ │ Agent │ │ SPIRE Agent + mTLS │ ║
|
||
║ └──────────────┘ └──────────────┘ └──────────────────────────────────┘ ║
|
||
╚══════════════════════════════════════════╦═══════════════════════════════════╝
|
||
║
|
||
MQTT 5.0 / CoAP (Confirmable) ║ gRPC-Lite / nanopb
|
||
BLE / Wi-Fi / LoRa / 5G NR ║ (고성능 임베디드)
|
||
TPM/SE X.509 SVID ║
|
||
║
|
||
╔══════════════════════════════════════════╩═══════════════════════════════════╗
|
||
║ T3: FIELD TIER (MCU / 임베디드 Linux / 로봇 / 센서 / AGV) ║
|
||
║ ║
|
||
║ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────────┐ ║
|
||
║ │ Cortex-M │ │ AGV / │ │ CCTV / │ │ Smart │ │ Wearable / │ ║
|
||
║ │ Sensor │ │ Robot │ │ Vision │ │ Meter │ │ Vital Mon. │ ║
|
||
║ │ MQTT Pub │ │ gRPC-Lite│ │ gRPC │ │ MQTT │ │ BLE/MQTT │ ║
|
||
║ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └─────────────┘ ║
|
||
║ ║
|
||
║ [TPM/SE attestation] [X.509 SVID] [Offline Queue] [nanopb Protobuf] ║
|
||
╚══════════════════════════════════════════════════════════════════════════════╝
|
||
```
|
||
|
||
### 2.2 3계층 프로토콜 스택
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ Layer 3: Semantic Layer (시맨틱 계층) │
|
||
│ - A2A Protocol: Agent Card 광고, Task 위임·탐색 │
|
||
│ - MCP (Model Context Protocol): 도구/데이터 바인딩 │
|
||
│ - SSE / Webhook: 비동기 Task 상태 업데이트 │
|
||
├─────────────────────────────────────────────────────────────┤
|
||
│ Layer 2: Transport Layer (전송 계층) │
|
||
│ - T1↔T2: gRPC over QUIC (HTTP/3) + Bidi Streaming │
|
||
│ - T2↔T2: gRPC Bidi Streaming (엣지 합의) │
|
||
│ - T2↔T3: MQTT 5.0 / CoAP Confirmable / gRPC-Lite │
|
||
│ - Retry Policy: Exponential Backoff + Jitter │
|
||
├─────────────────────────────────────────────────────────────┤
|
||
│ Layer 1: Security / Identity Layer (보안/신원 계층) │
|
||
│ - T1: OAuth2 + mTLS (k8s SA 기반 SPIFFE ID) │
|
||
│ - T2: SPIFFE SVID + 하드웨어 시리얼 기반 identity │
|
||
│ - T3: TPM/SE attestation + X.509 SVID │
|
||
│ - 2계층 거버넌스: Envoy Service Mesh + gRPC Interceptor │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 2.3 Tier 간 연결 특성 요약
|
||
|
||
| 구간 | 전송 프로토콜 | 보안 | 지연 목표 | 단절 내성 |
|
||
|------|------------|------|----------|----------|
|
||
| T1 ↔ T2 | gRPC over HTTP/2 or QUIC | mTLS + SPIFFE SVID | < 100ms | Resume Token + QUIC conn-migration |
|
||
| T2 ↔ T2 | gRPC Bidi Streaming | mTLS + SPIFFE SVID | < 10ms | 로컬 재연결 + Bidi 재확립 |
|
||
| T2 ↔ T3 (임베디드) | MQTT 5.0 / CoAP | X.509 SVID + TLS-PSK | < 1s | MQTT Last Will + QoS 1/2 |
|
||
| T2 ↔ T3 (고성능) | gRPC-Lite / nanopb | mTLS Lite | < 50ms | Resume Token |
|
||
| T3 ↔ T3 | MQTT / C-V2X / BLE Mesh | 디바이스 pairwise key | < 10ms | 로컬 큐 |
|
||
|
||
---
|
||
|
||
## 3. 계층별 설계 명세
|
||
|
||
### 3.1 시맨틱 계층 (A2A / MCP)
|
||
|
||
#### 3.1.1 A2A Protocol 통합
|
||
|
||
A2A(Agent-to-Agent) Protocol은 에이전트가 서로의 역량을 발견하고 Task를 위임하는 표준 시맨틱 계층이다. 본 프레임워크에서 A2A는 다음과 같이 통합된다.
|
||
|
||
**Agent Card 구조 (JSON)**
|
||
|
||
```json
|
||
{
|
||
"agent_id": "edge-inference-agent-t2-site-a",
|
||
"tier": "T2",
|
||
"capabilities": [
|
||
{"name": "visual_inspection", "modality": "vision", "latency_ms": 50},
|
||
{"name": "anomaly_detection", "modality": "timeseries", "latency_ms": 200}
|
||
],
|
||
"endpoint": {
|
||
"grpc": "grpcs://edge-site-a.internal:50051",
|
||
"a2a_sse": "https://edge-site-a.internal:8443/a2a/events",
|
||
"a2a_webhook": "https://edge-site-a.internal:8443/a2a/webhook"
|
||
},
|
||
"device_class": "edge-gateway",
|
||
"spiffe_id": "spiffe://edge/org/site-a/gateway/uuid-1234",
|
||
"schema_version": "v1.2.0"
|
||
}
|
||
```
|
||
|
||
**Task 위임 흐름**
|
||
- T1 Orchestrator가 Agent Card Registry를 조회하여 대상 T2 에이전트 선택
|
||
- `POST /a2a/tasks` 로 Task 객체 전송 (submitted 상태)
|
||
- T2 에이전트가 Task 수신 후 processing 상태로 전환
|
||
- SSE 또는 Webhook으로 상태 변화(submitted → working → completed/failed) 비동기 전달
|
||
- T2는 하위 T3 디바이스에 대해 동일한 A2A 엔드포인트를 노출하여, T3 디바이스도 A2A Task로 모델링 가능
|
||
|
||
**Rationale**: A2A가 직접 gRPC 메소드가 아닌 HTTP(S)/SSE 기반으로 설계된 이유는, 방화벽 통과 용이성과 브라우저 호환성을 확보하기 위함이다. 반면 실제 데이터 전송(모델 업데이트, 센서 스트리밍)은 gRPC를 통해 이루어져 성능을 보장한다.
|
||
|
||
#### 3.1.2 MCP (Model Context Protocol) 통합
|
||
|
||
MCP는 LLM 에이전트가 외부 도구(Tool)와 데이터 소스에 바인딩되는 표준 인터페이스를 제공한다.
|
||
|
||
```
|
||
T1 LLM Agent
|
||
│
|
||
├── MCP Tool: "query_sensor_data"
|
||
│ └── gRPC call → T2 Gateway → T3 Sensor
|
||
│
|
||
├── MCP Tool: "send_ota_command"
|
||
│ └── gRPC Unary → T2 Gateway → T3 Device
|
||
│
|
||
└── MCP Resource: "device_telemetry_stream"
|
||
└── gRPC Server Streaming → T2 Gateway fan-out
|
||
```
|
||
|
||
MCP 도구 호출은 T2 게이트웨이의 gRPC 인터셉터를 통해 traceparent가 자동 주입되어, LLM 추론 요청부터 T3 센서 응답까지의 전체 경로가 단일 trace로 연결된다.
|
||
|
||
### 3.2 전송 계층 (gRPC / QUIC / MQTT)
|
||
|
||
#### 3.2.1 gRPC 4대 RPC 모드 매핑
|
||
|
||
| RPC 모드 | 사용 시나리오 | Proto 예시 |
|
||
|---------|------------|----------|
|
||
| **Unary** | OTA 명령, 상태 조회, 설정 변경, A2A Task 결과 조회 | `rpc SendOTA(OTARequest) returns (OTAResponse)` |
|
||
| **Server Streaming** | T1→T2 모델 업데이트, T1→T2 LLM 토큰 스트리밍, T2→T3 펌웨어 청크 | `rpc StreamModel(ModelRequest) returns (stream ModelChunk)` |
|
||
| **Client Streaming** | T3→T2 센서 배치 업로드, OTA 청크 전송, 비디오 프레임 업로드 | `rpc UploadTelemetry(stream SensorData) returns (UploadResult)` |
|
||
| **Bidi Streaming** | T2↔T2 엣지 합의, AGV 충돌 회피, V2V 안전 메시지 | `rpc Negotiate(stream ConsensusMsg) returns (stream ConsensusMsg)` |
|
||
|
||
**Rationale**: Bidi Streaming을 T2↔T2 엣지 합의에 사용하는 이유는, 다수 엣지 노드가 단일 소켓을 통해 ms 단위의 상호 메시지 교환을 진행할 수 있어 소켓 수를 O(n²)에서 O(n)으로 줄이기 때문이다.
|
||
|
||
#### 3.2.2 gRPC over QUIC (T1↔T2)
|
||
|
||
T1↔T2 광역 무선 구간에서는 gRPC를 QUIC(HTTP/3) 위에 실어 다음 이점을 얻는다.
|
||
|
||
- **Connection Migration**: 모바일 IP 변경 시(5G→Wi-Fi) TCP 연결 단절 없이 마이그레이션
|
||
- **0-RTT Handshake**: 재연결 시 0-RTT로 즉시 재개 (Resume Token과 시너지)
|
||
- **HOLB-Free Multiplexing**: 여러 gRPC 스트림이 패킷 손실 시 상호 blocking 없이 독립적으로 재전송
|
||
|
||
```
|
||
gRPC Frame
|
||
└── HTTP/3 Frame
|
||
└── QUIC Packet
|
||
└── UDP Datagram
|
||
└── 5G NR / LTE / Wi-Fi Physical
|
||
```
|
||
|
||
#### 3.2.3 T2↔T3 프로토콜 선택 기준
|
||
|
||
```
|
||
T3 디바이스 특성 분류:
|
||
RAM > 2MB?
|
||
/ \
|
||
YES NO (MCU/LoRa)
|
||
│ │
|
||
gRPC-Lite? MQTT 5.0 or CoAP
|
||
(nanopb) │
|
||
/ \ QoS 요구도 높음?
|
||
YES NO / \
|
||
│ │ YES NO
|
||
gRPC-Lite MQTT 5.0 CoAP MQTT QoS 0
|
||
(고성능 임베디드) (일반 IoT) (Confirmable) (저전력 센서)
|
||
```
|
||
|
||
### 3.3 보안/신원 계층 (SPIFFE/SPIRE)
|
||
|
||
#### 3.3.1 SPIFFE ID 체계
|
||
|
||
각 tier의 SPIFFE ID는 계층적 네임스페이스로 설계하여, 정책 적용 시 와일드카드 매칭이 가능하도록 한다.
|
||
|
||
```
|
||
T1 클라우드 에이전트:
|
||
spiffe://cluster.local/ns/<namespace>/sa/<service-account>/agent/<agent-id>
|
||
예: spiffe://cluster.local/ns/ai-agents/sa/pm-agent/agent/pm-001
|
||
|
||
T2 엣지 게이트웨이:
|
||
spiffe://edge/<org>/<site>/gateway/<hardware-uuid>
|
||
예: spiffe://edge/acme/factory-line-a/gateway/550e8400-e29b
|
||
|
||
T3 현장 디바이스:
|
||
spiffe://iot/<org>/<site>/device/<serial-number>
|
||
예: spiffe://iot/acme/factory-line-a/device/agv-motor-ctrl-0042
|
||
```
|
||
|
||
#### 3.3.2 Attestation 메커니즘
|
||
|
||
```
|
||
T1: Kubernetes Service Account Token 검증
|
||
→ SPIRE Server가 k8s API 통해 SA 존재 확인
|
||
→ SVID 발급 (단기 X.509, TTL: 1시간)
|
||
|
||
T2: 하드웨어 시리얼 + TPM PCR 측정값 attestation
|
||
→ SPIRE Agent가 TPM Quote 생성 후 SPIRE Server에 전송
|
||
→ Server가 제조사 TPM EK Certificate Chain 검증
|
||
→ SVID 발급 (TTL: 4시간, 자동 갱신)
|
||
|
||
T3: TPM 2.0 / Secure Element attestation
|
||
→ Device가 SE에서 서명된 Device Certificate 생성
|
||
→ T2 SPIRE Agent가 중계하여 SPIRE Server에 전송
|
||
→ SVID 발급 (TTL: 24시간, 오프라인 시 Local CA 위임 가능)
|
||
```
|
||
|
||
#### 3.3.3 2계층 통신 거버넌스
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────┐
|
||
│ Layer 1: Infrastructure (Envoy / Service Mesh) │
|
||
│ - mTLS 종단(SPIFFE SVID 기반 인증서 자동 교체) │
|
||
│ - 카나리 라우팅, 글로벌 Rate Limiting │
|
||
│ - xDS Light로 T2 게이트웨이에 정책 push │
|
||
│ - Circuit Breaker, Health Check │
|
||
├──────────────────────────────────────────────────────┤
|
||
│ Layer 2: Application (gRPC Interceptor) │
|
||
│ - 디바이스 클래스별 페이로드 크기·빈도 검증 │
|
||
│ - 디바이스 컨텍스트 전파 (battery_level, link_rssi) │
|
||
│ - 단절 시 Resume Token 발급·검증 │
|
||
│ - W3C traceparent 주입·추출 │
|
||
│ - Deadline 강제 주입 (디바이스 클래스별 정책) │
|
||
└──────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**Rationale**: 2계층 분리의 핵심 이점은 관심사 분리다. Service Mesh는 인프라 팀이 제어하여 앱 변경 없이 네트워크 정책을 배포할 수 있고, gRPC Interceptor는 개발팀이 비즈니스 로직 수준에서 디바이스 컨텍스트를 활용할 수 있게 한다. T2 엣지 노드는 전체 Istio 대신 Envoy Mobile(xDS Light)로 경량화하여 제한된 자원 안에서 메쉬 기능을 구현한다.
|
||
|
||
---
|
||
|
||
## 4. T2 엣지 게이트웨이 상세 설계
|
||
|
||
T2 엣지 게이트웨이는 본 아키텍처의 핵심 허브다. 이 컴포넌트 하나가 3-tier 전체의 프로토콜 이질성, 보안 경계, 단절 복구, 관측성 집약을 담당한다.
|
||
|
||
### 4.1 컴포넌트 다이어그램
|
||
|
||
```
|
||
T1 방향 (gRPC over QUIC / HTTP-2)
|
||
│
|
||
┌───────────────▼───────────────────────────────┐
|
||
│ gRPC Server (T1 facing) │
|
||
│ Unary / Server-Streaming / Client-Streaming │
|
||
└───────────────┬───────────────────────────────┘
|
||
│
|
||
┌───────────────▼───────────────────────────────┐
|
||
│ Interceptor Chain (공통) │
|
||
│ [Auth] → [Trace Inject] → [Deadline] → │
|
||
│ [Rate Limit] → [Resume Token] → [Metrics] │
|
||
└───────────────┬───────────────────────────────┘
|
||
│
|
||
┌──────────┬───────────┼───────────┬──────────────┐
|
||
▼ ▼ ▼ ▼ ▼
|
||
┌────────┐ ┌────────┐ ┌─────────┐ ┌─────────┐ ┌──────────┐
|
||
│Protocol│ │Message │ │ Buffer │ │ Resume │ │ Device │
|
||
│Transltr│ │Normalzr│ │Batcher │ │ Token │ │ Auth │
|
||
│ │ │ │ │ │ │ Manager │ │ Relay │
|
||
│MQTT │ │JSON │ │T3 fan-in│ │Offset │ │SVID │
|
||
│topic → │ │↕ │ │N msgs → │ │store │ │verify │
|
||
│gRPC │ │Protobuf│ │1 Stream │ │(Redis) │ │→ T1 mTLS │
|
||
│method │ │ │ │ │ │ │ │ │
|
||
└────┬───┘ └────────┘ └────┬────┘ └─────────┘ └──────────┘
|
||
│ │
|
||
└──────────┬───────────┘
|
||
▼
|
||
┌───────────────────────┐ ┌───────────────────────┐
|
||
│ MQTT Broker (Mosq.) │ │ CoAP Server │
|
||
│ T3 Pub/Sub 처리 │ │ Confirmable/Observe │
|
||
└───────────┬───────────┘ └───────────┬───────────┘
|
||
│ │
|
||
└──────────┬─────────────────┘
|
||
▼
|
||
T3 방향 (MQTT / CoAP / BLE)
|
||
|
||
┌──────────────────────────────────────────────────┐
|
||
│ A2A Endpoint Server (HTTP/S) │
|
||
│ GET /a2a/agents → Agent Card 응답 │
|
||
│ POST /a2a/tasks → Task 위임 수신 │
|
||
│ GET /a2a/events (SSE) → Task 상태 스트리밍 │
|
||
│ POST /a2a/webhook → Task 상태 콜백 수신 │
|
||
└──────────────────────────────────────────────────┘
|
||
|
||
┌──────────────────────────────────────────────────┐
|
||
│ Metrics Collector │
|
||
│ Prometheus Exporter → OTel Collector → Jaeger │
|
||
│ Custom Metrics: resume_token_count, │
|
||
│ protocol_translation_latency_ms, │
|
||
│ t3_connection_drops_total │
|
||
└──────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 4.2 6대 모듈별 책임 명세
|
||
|
||
#### Module 1: Protocol Translator (프로토콜 변환기)
|
||
|
||
**책임**: T3 디바이스의 MQTT publish 메시지를 T1 방향 gRPC 메소드 호출로 변환, 반대 방향도 지원.
|
||
|
||
**변환 규칙 예시**:
|
||
```
|
||
MQTT topic: iot/{org}/{site}/{device_serial}/telemetry
|
||
↓ 매핑 테이블 조회
|
||
gRPC method: SensorService.UploadTelemetry (Client Streaming)
|
||
|
||
MQTT topic: iot/{org}/{site}/{device_serial}/command/ota
|
||
↓
|
||
gRPC method: DeviceService.SendOTA (Unary)
|
||
```
|
||
|
||
**구현**: Buf transcoding filter (`google.api.http` annotation 기반)를 사용하여 MQTT JSON 페이로드를 gRPC Protobuf로 자동 변환. 매핑 규칙은 YAML 설정 파일로 외부화하여 재배포 없이 업데이트 가능.
|
||
|
||
#### Module 2: Message Normalizer (메시지 정규화기)
|
||
|
||
**책임**: T3 디바이스의 JSON 페이로드와 T1/T2의 Protobuf 메시지 간 양방향 변환. 스키마 버전 불일치 처리.
|
||
|
||
**스키마 진화 처리**:
|
||
```
|
||
디바이스 펌웨어 v1.0 (구버전 JSON 스키마)
|
||
↓
|
||
Message Normalizer
|
||
- BSR에서 현재 .proto 스키마 로드
|
||
- JSON 필드를 proto 필드에 매핑
|
||
- 신규 필드: proto default 값 채움
|
||
- 구버전 필드: Protobuf Any + schema descriptor로 보존
|
||
↓
|
||
T1 에이전트 (최신 Protobuf)
|
||
```
|
||
|
||
#### Module 3: Buffer / Batcher (버퍼·배치 처리기)
|
||
|
||
**책임**: T3 다수 노드의 fan-in 메시지를 집계하여 T1으로의 gRPC Streaming 효율을 최대화.
|
||
|
||
**배치 정책**:
|
||
- `max_batch_size`: 기본 100개 메시지 (디바이스 클래스별 재정의 가능)
|
||
- `max_wait_ms`: 기본 50ms (지연 민감도 기준)
|
||
- 배치 조건: `max_batch_size` 도달 OR `max_wait_ms` 경과 중 먼저 발생하는 조건
|
||
|
||
```
|
||
T3 센서 x 10,000개 (각 1Hz)
|
||
→ Buffer: 50ms 수집
|
||
→ 배치 = 최대 500개 메시지
|
||
→ 단일 gRPC Client Streaming으로 T1 전달
|
||
(소켓 수: 10,000개 → 1개)
|
||
```
|
||
|
||
#### Module 4: Resume Token Manager (재개 토큰 관리자)
|
||
|
||
**책임**: T3↔T2 또는 T2↔T1 단절 발생 시 스트리밍 위치를 저장하고, 재접속 시 이어받기를 지원.
|
||
|
||
**Resume Token 구조**:
|
||
```json
|
||
{
|
||
"stream_id": "telemetry-stream-agv-0042-20260607T120000Z",
|
||
"last_offset": 8192,
|
||
"last_sequence": 1024,
|
||
"traceparent": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
|
||
"device_id": "spiffe://iot/acme/line-a/device/agv-0042",
|
||
"issued_at": "2026-06-07T12:00:00Z",
|
||
"ttl_seconds": 300
|
||
}
|
||
```
|
||
|
||
Resume Token은 Redis(T2 로컬)에 저장되어 게이트웨이 재시작 후에도 유효하다. TTL 초과 시 클라이언트는 전체 재동기화(full resync)를 수행한다.
|
||
|
||
#### Module 5: Device Auth Relay (디바이스 인증 중계기)
|
||
|
||
**책임**: T3 디바이스의 X.509 SVID를 T2에서 검증하고, T1에는 T2 자체 SVID로 mTLS 재인증을 수행.
|
||
|
||
```
|
||
T3 Device (X.509 SVID) → TLS 핸드셰이크
|
||
│
|
||
T2 Auth Relay
|
||
1. T3 SVID 인증서 Chain 검증 (SPIRE CA 루트)
|
||
2. SPIFFE ID SAN 추출 및 권한 확인
|
||
3. 디바이스 클래스 / 테넌트 매핑
|
||
4. gRPC Metadata에 X-Device-SPIFFE-ID 주입
|
||
│
|
||
T1 방향 gRPC (T2 SVID로 mTLS)
|
||
```
|
||
|
||
**Rationale**: T3 디바이스가 T1까지 직접 mTLS 연결을 맺을 경우, 클라우드 SPIRE Server가 수만 개 T3 디바이스의 SVID를 직접 관리해야 한다. T2가 인증 중계를 담당함으로써 T1은 T2 수준의 소수 연결만 관리하고, T3의 신원 폭발적 증가를 T2에서 흡수한다.
|
||
|
||
#### Module 6: Metrics Collector (메트릭 수집기)
|
||
|
||
**책임**: T2 게이트웨이의 운영 메트릭을 수집하여 T1 OTel Collector로 전송.
|
||
|
||
**수집 메트릭 목록**:
|
||
```
|
||
# Gateway 운영 메트릭
|
||
grpc_requests_total{method, status, device_class}
|
||
grpc_request_duration_seconds{method, p50, p95, p99}
|
||
protocol_translation_latency_ms{from_protocol, to_protocol}
|
||
buffer_queue_depth{device_class}
|
||
resume_token_issued_total
|
||
resume_token_consumed_total
|
||
t3_connection_active{protocol}
|
||
t3_connection_drops_total{reason}
|
||
|
||
# 디바이스 상태 메트릭 (T3 telemetry 집계)
|
||
device_battery_level{device_id, class}
|
||
device_link_rssi{device_id, interface}
|
||
device_message_rate_hz{device_id}
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 에이전트 상호작용 프로토콜
|
||
|
||
### 5.1 A2A Task 생명주기
|
||
|
||
```
|
||
상태 전이:
|
||
submitted → working → completed
|
||
→ failed
|
||
→ cancelled (T1 요청 또는 타임아웃)
|
||
```
|
||
|
||
### 5.2 T1 Orchestrator → T2 Edge Agent Task 위임 시퀀스
|
||
|
||
```
|
||
T1 Orchestrator T2 Edge Gateway T3 AGV Agent
|
||
│ │ │
|
||
│ 1. GET /a2a/agents │ │
|
||
│ ───────────────────> │ │
|
||
│ <─ Agent Card (JSON) ──│ │
|
||
│ │ │
|
||
│ 2. POST /a2a/tasks │ │
|
||
│ {task: "visual_inspection", │
|
||
│ input: {zone: "line-a"}, │
|
||
│ deadline: "2026-06-07T12:00:30Z"} │
|
||
│ ───────────────────> │ │
|
||
│ <─ {task_id, status: "submitted"} ── │
|
||
│ │ │
|
||
│ 3. GET /a2a/events │ │
|
||
│ (SSE connection) │ │
|
||
│ ───────────────────> │ │
|
||
│ │ 4. gRPC Unary │
|
||
│ │ SendCommand │
|
||
│ │ (start_inspection) │
|
||
│ │ ──────────────────────> │
|
||
│ │ <── (ack) ─────────────-│
|
||
│ │ │
|
||
│ 5. SSE event: │ │
|
||
│ {status: "working"} │ │
|
||
│ <─────────────────── event stream ── │
|
||
│ │ │
|
||
│ │ │ (검사 수행)
|
||
│ │ │
|
||
│ │ 6. gRPC Client Stream │
|
||
│ │ UploadInspectionData │
|
||
│ │ <────────────────────── │
|
||
│ │ (프레임 x N chunks) │
|
||
│ │ │
|
||
│ 7. SSE event: │ │
|
||
│ {status:"completed",│ │
|
||
│ result: {defects: │ │
|
||
│ [{zone: "A2", ...}]│ │
|
||
│ <─────────────────── event stream ── │
|
||
│ │ │
|
||
│ 8. POST /a2a/tasks │ │
|
||
│ /{task_id}/ack │ │
|
||
│ ───────────────────> │ │
|
||
```
|
||
|
||
### 5.3 T2↔T2 엣지 합의 시퀀스 (AGV 충돌 회피)
|
||
|
||
```
|
||
T2 Gateway A T2 Gateway B
|
||
(AGV 라인 A 담당) (AGV 라인 B 담당)
|
||
│ │
|
||
│ gRPC Bidi Streaming: Negotiate() │
|
||
│ ─────────────────────────────────────> │
|
||
│ <──────────────── (stream established) ─ │
|
||
│ │
|
||
│ ConsensusMsg { │
|
||
│ type: POSITION_CLAIM, │
|
||
│ zone: "intersection-01", │
|
||
│ agv_id: "agv-0042", │
|
||
│ priority: EMERGENCY │
|
||
│ } │
|
||
│ ─────────────────────────────────────> │
|
||
│ │
|
||
│ ConsensusMsg { │
|
||
│ type: ACK_DEFER, │
|
||
│ zone: "intersection-01", │
|
||
│ deferred_agv: "agv-0099",│
|
||
│ wait_ms: 200 │
|
||
│ } │
|
||
│ <───────────────────────────────────── │
|
||
│ │
|
||
│ [T2-A: AGV-0042에 통과 명령 전송] │
|
||
│ [T2-B: AGV-0099에 대기 명령 전송] │
|
||
```
|
||
|
||
**지연 보장**: T2↔T2 Bidi Streaming은 엣지 LAN 내에서 동작하며, p99 latency < 10ms 목표를 달성하기 위해 gRPC Keepalive 간격을 5초, deadline을 10ms로 설정한다.
|
||
|
||
---
|
||
|
||
## 6. 데이터 흐름 설계
|
||
|
||
### 6.1 T3 센서 → T1 LLM 에이전트 전체 경로
|
||
|
||
```
|
||
T3: 진동 센서 (Cortex-M, MQTT)
|
||
│
|
||
│ [1] MQTT Publish
|
||
│ Topic: iot/acme/line-a/vib-sensor-0017/telemetry
|
||
│ Payload: {"ts":1749298800, "axis_x": 2.31, "axis_y": 1.05}
|
||
│ QoS: 1, Retained: false
|
||
│
|
||
▼
|
||
T2: Edge Gateway (MQTT Broker 수신)
|
||
│
|
||
│ [2] Protocol Translator 처리
|
||
│ MQTT topic → gRPC method 매핑
|
||
│ device_serial: vib-sensor-0017 추출
|
||
│
|
||
│ [3] Message Normalizer 처리
|
||
│ JSON → SensorTelemetry Protobuf 변환
|
||
│ message SensorTelemetry {
|
||
│ string device_id = 1; // spiffe://iot/...
|
||
│ int64 timestamp_ms = 2;
|
||
│ repeated float values = 3;
|
||
│ DeviceContext context = 4; // battery, rssi
|
||
│ }
|
||
│
|
||
│ [4] Device Auth Relay
|
||
│ T3 SVID 검증 완료
|
||
│ gRPC Metadata 추가:
|
||
│ x-device-spiffe-id: spiffe://iot/acme/line-a/device/vib-sensor-0017
|
||
│ x-device-class: sensor-vibration
|
||
│ x-site-id: line-a
|
||
│ traceparent: 00-<trace-id>-<parent-span-id>-01
|
||
│
|
||
│ [5] Buffer / Batcher
|
||
│ 수집: vib-sensor-0001 ~ vib-sensor-5000 (50ms 대기)
|
||
│ 배치 크기: 3,200개 메시지 → 1개 gRPC Client Stream
|
||
│
|
||
│ [6] Interceptor Chain
|
||
│ Deadline: 5,000ms 주입
|
||
│ Rate Limit: site-a 쿼터 확인 (500k msg/s 이하)
|
||
│ Resume Token: 이전 스트림 위치 확인
|
||
│
|
||
▼
|
||
gRPC Client Streaming → T1 (HTTP/3 over QUIC)
|
||
│ Service: TelemetryIngestionService.BatchUpload
|
||
│ gRPC Metadata: traceparent, x-tenant-id, x-site-id
|
||
│
|
||
▼
|
||
T1: Telemetry Ingestion Service (k8s Pod)
|
||
│
|
||
│ [7] Stream Receiver
|
||
│ Protobuf Deserialize
|
||
│ DB Write: TimescaleDB / ClickHouse
|
||
│ Publish: Kafka topic "telemetry.line-a.vibration"
|
||
│
|
||
▼
|
||
T1: Anomaly Detection Agent (subscribes Kafka)
|
||
│
|
||
│ [8] Feature Extraction
|
||
│ FFT 분석, 통계 특징 추출
|
||
│
|
||
│ [9] LLM 에이전트 호출 (MCP Tool)
|
||
│ Tool: "analyze_vibration_anomaly"
|
||
│ Input: {features: [...], device_id: "vib-sensor-0017"}
|
||
│
|
||
│ [10] LLM 추론
|
||
│ "vib-sensor-0017 베어링 마모 징후 감지 (p=0.92)"
|
||
│
|
||
│ [11] A2A Task 발행
|
||
│ POST /a2a/tasks → T2 Maintenance Agent
|
||
│ {task: "schedule_maintenance", device: "vib-sensor-0017"}
|
||
│
|
||
▼
|
||
T2: Maintenance Agent → T3: Maintenance Robot 파견
|
||
```
|
||
|
||
### 6.2 긴급 이벤트 역방향 경로 (T3 → T1, < 1s)
|
||
|
||
긴급 이벤트(낙상 감지, 이상 전압, 충돌 위험)는 배치 경로를 우회하여 직접 전달된다.
|
||
|
||
```
|
||
T3 Emergency Event
|
||
→ MQTT QoS 2 (exactly-once) Publish
|
||
→ T2 Buffer/Batcher: EMERGENCY flag 감지 → 즉시 flush (배치 대기 없음)
|
||
→ T2 Interceptor: Priority Header 주입 (grpc-priority: critical)
|
||
→ gRPC Unary: EmergencyService.Alert (Deadline: 500ms)
|
||
→ T1 Alert Service → PagerDuty / SMS / LLM 에이전트 즉시 호출
|
||
```
|
||
|
||
---
|
||
|
||
## 7. 장애 내성 설계
|
||
|
||
### 7.1 Resume Token 상세 설계
|
||
|
||
Resume Token은 단순 offset이 아닌, 재접속 시 trace 연속성까지 보장하는 복합 구조체다.
|
||
|
||
```protobuf
|
||
message ResumeToken {
|
||
string stream_id = 1;
|
||
string device_spiffe_id = 2;
|
||
int64 last_offset = 3;
|
||
int64 last_sequence_number = 4;
|
||
string traceparent = 5; // W3C traceparent (trace 연속성)
|
||
int64 issued_at_ms = 6;
|
||
int32 ttl_seconds = 7;
|
||
bytes hmac_signature = 8; // T2 비밀키로 서명 (위조 방지)
|
||
}
|
||
```
|
||
|
||
**재접속 시퀀스**:
|
||
```
|
||
T3 Device (재접속)
|
||
│
|
||
│ gRPC Metadata: resume-token: <base64-encoded-token>
|
||
│ ─────────────────────────────────────────────────>
|
||
│
|
||
T2 Resume Token Manager
|
||
1. HMAC 서명 검증 (위조 방지)
|
||
2. TTL 만료 확인
|
||
3. SPIFFE ID 일치 확인
|
||
4. last_offset 이후부터 스트림 재개
|
||
5. 기존 traceparent 유지 (단절 구간도 같은 trace로 연결)
|
||
│
|
||
│ <── {status: "resumed", from_offset: 8193} ─────
|
||
```
|
||
|
||
### 7.2 Deadline 정책
|
||
|
||
디바이스 클래스별 기본 Deadline은 gRPC Interceptor에서 자동 주입된다. 애플리케이션 코드에서 Deadline을 설정하지 않아도 인터셉터가 강제 적용한다.
|
||
|
||
| 디바이스 클래스 | RPC 유형 | 기본 Deadline | 근거 |
|
||
|--------------|---------|-------------|------|
|
||
| AGV / Robot | Bidi Streaming (합의) | 10ms | 충돌 회피 SLA |
|
||
| AGV / Robot | Unary (명령) | 50ms | 제어 루프 주기 |
|
||
| IoT 센서 | Client Streaming (배치) | 5,000ms | 배치 처리 허용 |
|
||
| IoT 센서 | Unary (상태 조회) | 1,000ms | 단순 조회 |
|
||
| 차량 (V2X) | Unary (안전 메시지) | 10ms | ETSI ITS 요구 |
|
||
| 웨어러블 | Unary (긴급 알림) | 500ms | 헬스케어 SLA |
|
||
| 웨어러블 | Client Streaming (일반) | 10,000ms | 배터리 절약 배치 |
|
||
|
||
### 7.3 Retry Policy
|
||
|
||
```yaml
|
||
# gRPC Service Config (T1 클라이언트에 적용)
|
||
methodConfig:
|
||
- name: [{service: "TelemetryIngestion"}]
|
||
retryPolicy:
|
||
maxAttempts: 4
|
||
initialBackoff: "0.1s"
|
||
maxBackoff: "2s"
|
||
backoffMultiplier: 2.0
|
||
retryableStatusCodes: [UNAVAILABLE, RESOURCE_EXHAUSTED]
|
||
timeout: "10s"
|
||
|
||
- name: [{service: "EmergencyAlert"}]
|
||
retryPolicy:
|
||
maxAttempts: 3
|
||
initialBackoff: "0.01s"
|
||
maxBackoff: "0.1s"
|
||
backoffMultiplier: 2.0
|
||
retryableStatusCodes: [UNAVAILABLE]
|
||
timeout: "0.5s" # 긴급 알림은 짧은 timeout
|
||
```
|
||
|
||
**Hedging Policy** (지연 민감 경로용):
|
||
|
||
안전 메시지나 긴급 알림처럼 첫 번째 응답이 중요한 경우, hedgedDelay 내 응답이 없으면 두 번째 요청을 병렬 전송한다.
|
||
|
||
```yaml
|
||
hedgingPolicy:
|
||
maxAttempts: 2
|
||
hedgingDelay: "5ms"
|
||
nonFatalStatusCodes: [UNAVAILABLE]
|
||
```
|
||
|
||
### 7.4 Circuit Breaker (장애 전파 차단)
|
||
|
||
T3 디바이스 군집 중 일부가 비정상 상태일 때, 장애가 T2→T1으로 전파되는 것을 차단한다.
|
||
|
||
```
|
||
Envoy Circuit Breaker 설정:
|
||
- max_connections: 1024 (T2↔T1)
|
||
- max_pending_requests: 512
|
||
- max_requests: 2048
|
||
- max_retries: 50
|
||
- consecutive_5xx: 5 → OPEN (10s 후 HALF-OPEN)
|
||
```
|
||
|
||
T2 게이트웨이 자체 Circuit Breaker는 T3 디바이스 클래스별로 독립 인스턴스를 운용하여, 특정 디바이스 클래스의 대량 실패가 다른 클래스에 영향주지 않도록 격리한다.
|
||
|
||
---
|
||
|
||
## 8. 멀티테넌시 설계
|
||
|
||
### 8.1 테넌트 식별 구조
|
||
|
||
```
|
||
gRPC Metadata 필수 헤더 (모든 RPC):
|
||
x-tenant-id: <organization-id>
|
||
x-site-id: <site-id>
|
||
x-device-class: [sensor|robot|agv|vehicle|wearable|gateway]
|
||
x-device-spiffe-id: <spiffe-uri>
|
||
```
|
||
|
||
SPIFFE ID의 계층 구조가 테넌트 분리와 직결된다. `spiffe://iot/<org>/...` 패턴에서 `<org>`가 테넌트 경계를 정의하고, Envoy의 RBAC 정책이 이를 기반으로 크로스-테넌트 접근을 차단한다.
|
||
|
||
### 8.2 디바이스 클래스별 쿼터
|
||
|
||
```
|
||
T3 IoT 센서:
|
||
- 메시지 빈도: 분당 120건/디바이스 (2Hz)
|
||
- 페이로드 크기: 최대 4KB/메시지
|
||
- OTA 업데이트: 시간당 1회
|
||
- 초과 시: gRPC RESOURCE_EXHAUSTED (코드 8) 반환
|
||
|
||
T3 AGV / 산업 로봇:
|
||
- 안전 메시지: 초당 100건 (우선 처리, 쿼터 예외)
|
||
- 일반 텔레메트리: 분당 600건
|
||
- 동시 Bidi 스트림: 최대 4개
|
||
- 초과 시: 일반 메시지만 throttle, 안전 메시지 보장
|
||
|
||
T3 차량 (V2X):
|
||
- V2I 안전 메시지: 쿼터 없음 (항상 우선)
|
||
- HD맵 업데이트 다운로드: 100MB/시간
|
||
- 진단 데이터 업로드: 10MB/시간
|
||
|
||
T3 웨어러블:
|
||
- 연속 모니터링: 분당 60건 (1Hz)
|
||
- 긴급 이벤트: 쿼터 없음
|
||
- 배터리 절약 배치: 6시간마다 일괄 업로드 허용
|
||
|
||
T2 엣지 게이트웨이:
|
||
- 동시 추론 세션: 최대 8개 (NPU 점유)
|
||
- T3 동시 접속 디바이스: 최대 10,000개
|
||
- T1 방향 gRPC 연결: 최대 16개 (멀티플렉싱으로 충분)
|
||
```
|
||
|
||
### 8.3 RBAC 설계
|
||
|
||
```
|
||
역할 계층:
|
||
system:admin → 전체 테넌트 관리
|
||
tenant:admin → 단일 테넌트 전체
|
||
site:operator → 특정 사이트 운영
|
||
device:reader → 읽기 전용 (모니터링)
|
||
device:controller → 명령 전송 가능
|
||
agent:orchestrator → A2A Task 위임 가능
|
||
agent:executor → A2A Task 실행 가능 (수신 전용)
|
||
|
||
gRPC Method → Role 매핑 예시:
|
||
DeviceService.SendOTA → device:controller 이상
|
||
TelemetryService.StreamRead → device:reader 이상
|
||
AgentService.DelegateTask → agent:orchestrator 이상
|
||
EmergencyService.Alert → device:controller 이상 또는 T3 device 본인
|
||
```
|
||
|
||
RBAC 정책은 Envoy의 External Authorization (ext_authz) 필터를 통해 OPA(Open Policy Agent)로 위임하여 동적 업데이트를 가능하게 한다.
|
||
|
||
---
|
||
|
||
## 9. 관측성 설계
|
||
|
||
### 9.1 분산 추적 (Distributed Tracing)
|
||
|
||
**traceparent 전파 경로**:
|
||
|
||
```
|
||
T1 LLM Agent
|
||
[trace-id: aabbccdd, span-id: 0001]
|
||
│
|
||
│ gRPC Metadata: traceparent: 00-aabbccdd-0001-01
|
||
▼
|
||
T2 Edge Gateway (Interceptor: extract → span 생성)
|
||
[trace-id: aabbccdd, span-id: 0002, parent: 0001]
|
||
│
|
||
├── A2A Task 위임 → T2 Agent
|
||
│ [trace-id: aabbccdd, span-id: 0003, parent: 0002]
|
||
│
|
||
└── MQTT Publish → T3 Device
|
||
(traceparent을 MQTT User Property로 전달)
|
||
[trace-id: aabbccdd, span-id: 0004, parent: 0002]
|
||
│
|
||
│ T3 응답 수신 시 span 종료
|
||
└── Resume Token에 traceparent 임베드
|
||
(단절 후 재접속 시 동일 trace로 연속)
|
||
```
|
||
|
||
T2 게이트웨이는 **trace fan-out 지점**으로, T3 디바이스가 OTel SDK를 탑재하지 않아도 T2가 T3 span을 대신 생성하여 전체 호출 그래프에 포함시킨다.
|
||
|
||
### 9.2 메트릭 체계
|
||
|
||
**수집 계층**:
|
||
```
|
||
T3 디바이스: 자체 메트릭 없음 (T2가 대행)
|
||
↓
|
||
T2 게이트웨이: Prometheus Exporter (포트 9090)
|
||
↓ (scrape 또는 OTLP push)
|
||
T2 OTel Collector: 집계 + 샘플링 + 재전송
|
||
↓ (OTLP gRPC)
|
||
T1 OTel Collector: 중앙 집계
|
||
↓
|
||
Prometheus (장기 저장) ← Grafana Dashboard
|
||
Jaeger (트레이스 저장) ← Grafana Tempo
|
||
```
|
||
|
||
**SLO 알람 기준**:
|
||
|
||
| 메트릭 | 경고 임계 | 심각 임계 |
|
||
|--------|---------|---------|
|
||
| T2 Gateway p99 translation latency | > 50ms | > 100ms |
|
||
| T3 connection drop rate | > 5% / min | > 20% / min |
|
||
| Resume token TTL 만료율 | > 1% | > 5% |
|
||
| gRPC UNAVAILABLE error rate | > 1% | > 5% |
|
||
| A2A Task failure rate | > 2% | > 10% |
|
||
|
||
### 9.3 구조화 로그
|
||
|
||
모든 로그는 JSON 구조화 형식으로 출력하며, traceparent와 SPIFFE ID를 필수 필드로 포함한다.
|
||
|
||
```json
|
||
{
|
||
"timestamp": "2026-06-07T12:00:00.123Z",
|
||
"level": "INFO",
|
||
"service": "t2-edge-gateway",
|
||
"site_id": "factory-line-a",
|
||
"trace_id": "aabbccdd1122334455667788",
|
||
"span_id": "0002aabb",
|
||
"device_spiffe_id": "spiffe://iot/acme/line-a/device/agv-0042",
|
||
"event": "protocol_translation_completed",
|
||
"from_protocol": "mqtt",
|
||
"to_protocol": "grpc",
|
||
"latency_ms": 1.2,
|
||
"batch_size": 1024
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 10. 사례별 설계 적용
|
||
|
||
### 10.1 스마트 팩토리 (Industry 4.0)
|
||
|
||
**핵심 통신 요구**: AGV 충돌 회피 p99 < 10ms, 다수 센서 fan-in (10k 노드 × 1Hz), OTA 결함 내성
|
||
|
||
| 구성 요소 | 설계 선택 | 근거 |
|
||
|---------|---------|------|
|
||
| AGV↔T2 | gRPC Bidi Streaming | ms 단위 충돌 회피 합의, 단일 소켓 재활용 |
|
||
| 센서→T2 | MQTT QoS 1 + T2 Batcher | 10k 동시 접속, 배치로 gRPC fan-out 최소화 |
|
||
| T2↔T1 | gRPC Client Streaming | 배치 업로드, 백프레셔로 T1 과부하 방지 |
|
||
| OTA | gRPC Server Streaming + Resume Token | 네트워크 단절 시 청크 이어받기 |
|
||
| 디바이스 신원 | TPM + SPIRE | 로봇 물리 변조 대응, 동적 SVID 폐기 |
|
||
| 합의 Deadline | 10ms | AGV 충돌 회피 SLA 준수 |
|
||
|
||
**A2A 역할 분담**:
|
||
- T1 PM Agent: 생산 계획 → T2 Line Agent에 작업 Task 위임 (A2A)
|
||
- T2 Line Agent: 라인별 AGV 집단 제어, 품질 이상 감지 시 T1에 알림
|
||
- T3 AGV Agent (경량): gRPC-Lite로 T2와 통신, 로컬 충돌 회피 실행
|
||
|
||
### 10.2 스마트 빌딩 / 에너지
|
||
|
||
**핵심 통신 요구**: 저전력 무선(LoRa/Zigbee) 지원, 피크 수요 절감을 위한 HVAC 협업, 5~15분 주기 배치
|
||
|
||
| 구성 요소 | 설계 선택 | 근거 |
|
||
|---------|---------|------|
|
||
| 스마트 미터→T2 | MQTT QoS 0 + LoRa 브릿지 | 저전력, 1회/5분 허용 |
|
||
| HVAC 협업 | gRPC Unary (빠른 명령) + T2 내부 합의 | 피크 절감 응답 < 100ms |
|
||
| PV 인버터→T2 | Modbus/MQTT 브릿지 → T2 변환 | 레거시 프로토콜 통합 |
|
||
| T2↔T1 | gRPC Server Streaming | 에너지 최적화 모델 실시간 수신 |
|
||
| 긴급 차단 | gRPC Unary Deadline 50ms | 과전압 즉시 차단 |
|
||
|
||
**A2A 역할 분담**:
|
||
- T1 Energy Optimizer Agent: DR(수요 반응) 신호 수신 → T2 Building Agent에 절감 목표 Task 위임
|
||
- T2 Building Agent: HVAC/조명/EV 충전기 협업, 피크 절감 최적화
|
||
|
||
### 10.3 커넥티드 차량 / V2X
|
||
|
||
**핵심 통신 요구**: 핸드오버 무중단(QUIC), V2V 안전 메시지 < 10ms, HD맵 OTA
|
||
|
||
| 구성 요소 | 설계 선택 | 근거 |
|
||
|---------|---------|------|
|
||
| T3 차량↔T2 RSU | C-V2X / ITS-G5 + gRPC at RSU | ETSI ITS 표준 준수 |
|
||
| T2 RSU↔T1 | gRPC over QUIC | 5G 핸드오버 시 connection migration |
|
||
| V2V (차량간) | QUIC datagram 멀티캐스트 | 브로드캐스트 안전 메시지, HOLB 없음 |
|
||
| HD맵 업데이트 | gRPC Server Streaming + Resume Token | 대용량 맵 데이터, 단절 이어받기 |
|
||
| 디바이스 신원 | V2X PKI + SPIRE 통합 | ITS 인증서 표준과 SPIFFE ID 브릿지 |
|
||
|
||
**A2A 역할 분담**:
|
||
- T1 Traffic Management Agent: 교통 흐름 최적화 → T2 RSU Agent에 속도 제한 Task 위임
|
||
- T2 RSU Agent: 실시간 V2I 메시지 배포, 사고 감지 시 T1 긴급 알림
|
||
|
||
### 10.4 헬스케어 / 원격 모니터링
|
||
|
||
**핵심 통신 요구**: 배터리 수명 최대화, 24h 연속 모니터링, 이상 이벤트 < 1s T1 전달
|
||
|
||
| 구성 요소 | 설계 선택 | 근거 |
|
||
|---------|---------|------|
|
||
| 웨어러블→T2 | BLE/Wi-Fi + MQTT QoS 1 | 저전력, Last Will로 연결 단절 감지 |
|
||
| 연속 데이터 | Client Streaming + 6시간 배치 | 배터리 절약 duty cycle |
|
||
| 긴급 이벤트 | MQTT QoS 2 → 즉시 flush → gRPC Unary | exactly-once + < 1s T1 도달 보장 |
|
||
| 환자 데이터 보호 | HIPAA-ready: AES-256 in-transit + at-rest | 의료 데이터 컴플라이언스 |
|
||
| 디바이스 신원 | TPM/SE + SPIRE | 환자 안전 디바이스 변조 방지 |
|
||
|
||
**A2A 역할 분담**:
|
||
- T1 Clinical AI Agent: EHR 데이터 + T2 집계 데이터로 임상 추론
|
||
- T2 Hospital Edge Agent: 낙상/부정맥 로컬 감지(< 100ms), T1에 A2A Task로 알림
|
||
- T3 Wearable: 센서 수집 + 로컬 오프로드 큐 (BLE 단절 대비)
|
||
|
||
### 10.5 사례별 프로토콜 매트릭스 종합
|
||
|
||
| 설계 항목 | 스마트 팩토리 | 스마트 빌딩 | V2X | 헬스케어 |
|
||
|---------|------------|-----------|-----|--------|
|
||
| T1↔T2 백본 | gRPC + HTTP/2 | gRPC + 유선/4G | gRPC + QUIC (5G) | gRPC + 유선 |
|
||
| T2↔T3 현장 | MQTT 5.0 / gRPC-Lite | MQTT + LoRa 브릿지 | C-V2X / ITS-G5 | BLE + MQTT |
|
||
| 저지연 합의 | gRPC Bidi (AGV) | gRPC Unary (HVAC) | QUIC datagram | gRPC Unary (이벤트) |
|
||
| 핸드오버 | Resume Token | Resume Token | QUIC conn-migration | Resume Token |
|
||
| 디바이스 신원 | TPM + SPIRE | SE + SPIRE | V2X PKI + SPIRE | TPM/SE + SPIRE |
|
||
| 저전력 대응 | N/A | MQTT QoS 0 + sleep | N/A | BLE duty cycle |
|
||
| 긴급 이벤트 | gRPC Stream 알림 | gRPC Unary 알림 | C-V2X CAM/DENM | gRPC Unary < 1s |
|
||
| A2A 위임 방향 | T1→T2→T3 계층 | T1→T2 목표 기반 | T1 교통→T2 RSU | T2 감지→T1 임상 |
|
||
|
||
---
|
||
|
||
## 부록: Proto 설계 가이드라인
|
||
|
||
본 프레임워크에서 `.proto` 파일을 작성할 때 준수해야 할 설계 원칙은 다음과 같다.
|
||
|
||
1. **모든 메시지에 `DeviceContext` 포함**: 배터리 수준, RSSI, 펌웨어 버전을 표준 필드로 정의하여 관측성을 기본화한다.
|
||
2. **`oneof` 활용**: 디바이스 클래스별 가변 페이로드는 `oneof payload { SensorData sensor = 10; RobotStatus robot = 11; ... }` 구조로 타입 안전하게 설계한다.
|
||
3. **필드 번호 예약**: 삭제된 필드 번호를 `reserved`로 표시하여 OTA 업데이트 중 구버전 디바이스의 역직렬화 오류를 방지한다.
|
||
4. **BSR 등록 필수**: 모든 `.proto`는 Buf Schema Registry에 등록하고, `buf breaking` CI 체크를 PR 조건으로 강제한다.
|
||
5. **서비스별 패키지 분리**: `iot.telemetry.v1`, `iot.command.v1`, `agent.a2a.v1` 등 기능 도메인별로 패키지를 분리하여 독립적 버전 관리를 가능케 한다.
|
||
|
||
---
|
||
|
||
*본 설계 문서는 FINAL_REPORT.md의 연구 결과를 바탕으로 작성되었으며, 실제 구현 시 각 사이트의 물리적 환경과 규제 요구사항에 맞게 조정되어야 한다.*
|