docs: remap gRPC-over-QUIC transport to per-RPC stream mapping, resolve HOLB contradiction
This commit is contained in:
@@ -220,7 +220,7 @@ MCP 도구 호출은 T2 게이트웨이의 gRPC 인터셉터를 통해 tracepare
|
|||||||
|
|
||||||
**Rationale**: Bidi Streaming을 T2↔T2 엣지 합의에 사용하는 이유는, 다수 엣지 노드가 단일 소켓을 통해 ms 단위의 상호 메시지 교환을 진행할 수 있어 소켓 수를 O(n²)에서 O(n)으로 줄이기 때문이다.
|
**Rationale**: Bidi Streaming을 T2↔T2 엣지 합의에 사용하는 이유는, 다수 엣지 노드가 단일 소켓을 통해 ms 단위의 상호 메시지 교환을 진행할 수 있어 소켓 수를 O(n²)에서 O(n)으로 줄이기 때문이다.
|
||||||
|
|
||||||
#### 3.2.2 gRPC over QUIC (T1↔T2) [기본] 및 HTTP/2 폴백
|
#### 3.2.2 gRPC over QUIC (T1↔T2) [기본] 및 다이얼 실패 기반 전송 폴백
|
||||||
|
|
||||||
T1↔T2 광역 구간은 gRPC over QUIC(HTTP/3) 프로토콜을 기본(Primary) 전송 채널로 사용하며, 다음의 이점을 제공한다:
|
T1↔T2 광역 구간은 gRPC over QUIC(HTTP/3) 프로토콜을 기본(Primary) 전송 채널로 사용하며, 다음의 이점을 제공한다:
|
||||||
|
|
||||||
@@ -236,7 +236,7 @@ gRPC Frame
|
|||||||
└── 5G NR / LTE / Wi-Fi Physical
|
└── 5G NR / LTE / Wi-Fi Physical
|
||||||
```
|
```
|
||||||
|
|
||||||
또한, 엣지 게이트웨이(T2)와 클라우드(T1) 사이의 전송 신뢰성을 보장하기 위해 **HTTP/2 폴백 협상(Fallback Negotiation)** 메커니즘을 내장한다. 클라이언트(게이트웨이)는 최초 접속 시 ALPN(Application-Layer Protocol Negotiation)에 `h3` 프로토콜을 우선 협상하며, UDP 포트 차단이나 방화벽 제약으로 인해 QUIC 연결이 실패하는 경우 즉시 표준 TCP 기반의 `h2`(gRPC over HTTP/2) 채택으로 강등(Downgrade)하여 연결 연속성을 유지한다.
|
QUIC 연결 내부에서는 **개별 RPC 호출(Request/Response)과 네트워크 수준의 QUIC 스트림을 1:1로 매핑**하여 개별 호출의 독립 전송을 보장하고 스트림 수준의 Head-of-Line Blocking(HOLB)을 완전히 차단한다. 또한, 엣지 게이트웨이(T2)와 클라우드(T1) 사이의 전송 신뢰성을 보장하기 위해 **다이얼 실패 기반 전송 폴백(Dial-Failure-Based Transport Fallback)** 메커니즘을 내장한다. 클라이언트(게이트웨이)는 기본적으로 UDP/QUIC 다이얼러를 통해 연결을 시도하며, 방화벽 UDP 차단이나 패킷 영구 손실 등 UDP 연결 실패가 감지되는 경우 즉시 표준 TCP 기반의 `h2`(gRPC over HTTP/2) 다이얼러로 폴백하여 연결 연속성을 유지한다.
|
||||||
|
|
||||||
#### 3.2.3 T2↔T3 프로토콜 선택 기준
|
#### 3.2.3 T2↔T3 프로토콜 선택 기준
|
||||||
|
|
||||||
|
|||||||
@@ -548,11 +548,22 @@ var defaultDeadlines = map[string]int64{
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
> **참고**: 실제 quic-go와 gRPC-Go 통합 시 `grpc.WithContextDialer`를 사용하여 클라이언트 측에서 QUIC 다이얼러를 주입하는 방식이 더 실용적이다. 위 코드는 서버 측 리스너 래핑 패턴을 보여준다. 프로덕션에서는 `quic-go/http3` 패키지의 `ServeListener` 방식 또는 별도 gRPC-QUIC 어댑터 라이브러리(`github.com/open-telemetry/opentelemetry-collector-contrib` 참조)를 활용한다. 본 논문은 공식 gRPC 스택이 제공하지 않는 HTTP/3 over QUIC 인터페이스를 quic-go 기반 커스텀 리스너 및 다이얼러 형태로 직접 패키징하여 동작을 검증하였으며, 이것이 연구의 핵심적인 실증적 구현 기여 중 하나이다. 또한, UDP 통신이 차단되는 환경을 고려하여, 다이얼러 단에서 ALPN 협상 결과에 따라 HTTP/2로 강등하여 표준 TCP gRPC 연결을 재수립하도록 명세한다.
|
> **참고**: 실제 quic-go와 gRPC-Go 통합 시 공식 gRPC 스택의 HTTP/3 지원이 실험적 단계임을 감안하여, 본 논문은 전송 계층의 독립 스트림 멀티플렉싱(HOLB 해소)을 실질적으로 확보하기 위한 두 가지 커스텀 어댑터 설계 및 다이얼 실패 기반 폴백 메커니즘을 정의한다.
|
||||||
|
|
||||||
#### HTTP/2 폴백(Fallback) 전송 어댑터 명세
|
#### 다이얼 실패 기반 전송 폴백(Dial-Failure-Based Transport Fallback) 명세
|
||||||
|
|
||||||
클라이언트(게이트웨이)가 UDP/QUIC 연결을 시도하고 실패하거나 UDP 차단을 감지한 경우 즉시 TCP/HTTP/2로 자동 전환하기 위해 `internal/gateway/fallback_dialer.go` 명세를 추가한다.
|
T1 클라우드와 T2 엣지 게이트웨이 간 무선 링크의 신뢰성을 보장하기 위해, 기본 UDP/QUIC 연결 수립 실패 시 TCP/HTTP/2 경로로 자동 전환하는 전송 폴백 메커니즘을 구현한다. 본 구조는 포트나 전송 프로토콜이 상이하여 단일 핸드셰이크 내 ALPN 강등 협상이 불가하므로, 클라이언트 단의 다이얼러에서 명시적인 연결 실패 감지 후 폴백을 수행한다.
|
||||||
|
|
||||||
|
##### 1. 클라이언트 측 전송 어댑터 및 폴백 다이얼러 (`internal/gateway/fallback_dialer.go`)
|
||||||
|
|
||||||
|
공식 gRPC-Go의 단일 커넥션 다이얼러 방식은 하나의 QUIC 스트림으로 HTTP/2 전체 프레임을 터널링할 경우 QUIC 세션 내부에서 TCP 수준의 HOLB를 그대로 재현하는 설계 결함(naive 구현)을 갖는다. 이를 방지하기 위해 각 RPC 호출을 독립된 QUIC 스트림에 1:1로 매핑하는 구조를 채택하며, 다음의 두 가지 대안을 명세한다:
|
||||||
|
|
||||||
|
- **(a) 권장 구현 — HTTP/3 의미론 기반 매핑 (connect-go 활용)**:
|
||||||
|
`quic-go/http3` 패키지의 `http3.RoundTripper`를 기반으로 동작하는 HTTP/3 클라이언트를 활용하여 gRPC와 와이어 프로토콜 수준에서 호환되도록 구성한다. 이 방식은 HTTP/3 명세에 따라 **개별 RPC 호출(Request/Response)이 네트워크 수준의 독립된 QUIC 스트림으로 자동 매핑**되므로 패킷 유실 시에도 다른 RPC 스트림이 정체되지 않는다.
|
||||||
|
- **(b) 대안 구현 — per-RPC 커스텀 ClientTransport**:
|
||||||
|
gRPC-Go의 커스텀 `ClientTransport` 인터페이스를 직접 구현하여, 클라이언트가 RPC를 개시할 때마다 `quic.Connection.OpenStreamSync`를 호출하여 새 QUIC 스트림을 동적으로 개방하고, 해당 스트림에 length-prefixed gRPC 바이트 프레임을 직접 매핑하여 송수신한다. 단, 이 대안은 gRPC-Go 내부의 private transport API 변동에 따른 유지보수 리스크가 있음을 명시한다.
|
||||||
|
|
||||||
|
아래는 다이얼 실패 감지 및 `tls.Config` 분리 복제(`Clone`)가 적용된 폴백 다이얼러 구현 명세이다:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package gateway
|
package gateway
|
||||||
@@ -567,39 +578,49 @@ import (
|
|||||||
"github.com/quic-go/quic-go"
|
"github.com/quic-go/quic-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FallbackDialer는 QUIC 연결 시도 후 실패 시 TCP/HTTP2로 자동 전환하는 다이얼러이다.
|
// FallbackDialer는 QUIC 연결 시도 실패 시 TCP/HTTP2로 전환하는 다이얼러이다.
|
||||||
type FallbackDialer struct {
|
type FallbackDialer struct {
|
||||||
tlsConfig *tls.Config
|
quicTLSConfig *tls.Config // QUIC 전용 ALPN (h3)
|
||||||
|
tcpTLSConfig *tls.Config // TCP 전용 ALPN (h2)
|
||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFallbackDialer(tlsConfig *tls.Config, timeout time.Duration) *FallbackDialer {
|
func NewFallbackDialer(baseConfig *tls.Config, timeout time.Duration) *FallbackDialer {
|
||||||
tlsConfig.NextProtos = []string{"h3", "h2"} // QUIC(h3) 우선 협상, 실패 시 HTTP/2(h2)로 폴백
|
// 호출자 tls.Config의 사이드 이펙트 방지를 위해 복제(Clone) 수행
|
||||||
return &FallbackDialer{tlsConfig: tlsConfig, timeout: timeout}
|
quicTLS := baseConfig.Clone()
|
||||||
|
quicTLS.NextProtos = []string{"h3"} // QUIC은 h3 프로토콜에 한정
|
||||||
|
|
||||||
|
tcpTLS := baseConfig.Clone()
|
||||||
|
tcpTLS.NextProtos = []string{"h2"} // TCP/HTTP2는 h2 프로토콜에 한정
|
||||||
|
|
||||||
|
return &FallbackDialer{
|
||||||
|
quicTLSConfig: quicTLS,
|
||||||
|
tcpTLSConfig: tcpTLS,
|
||||||
|
timeout: timeout,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DialContext는 UDP/QUIC 연결을 시도하고 실패 시 TCP/HTTP/2 연결로 폴백한다.
|
// DialContext는 UDP/QUIC 다이얼을 시도하고 실패 시 0-RTT 이내에 TCP 기반 HTTP/2 연결로 폴백한다.
|
||||||
func (d *FallbackDialer) DialContext(ctx context.Context, addr string) (net.Conn, error) {
|
func (d *FallbackDialer) DialContext(ctx context.Context, addr string) (net.Conn, error) {
|
||||||
quicCtx, cancel := context.WithTimeout(ctx, d.timeout)
|
quicCtx, cancel := context.WithTimeout(ctx, d.timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// 1. QUIC(HTTP/3) Dial 시도
|
// 1. QUIC(HTTP/3) Dial 시도
|
||||||
quicConn, err := quic.DialAddr(quicCtx, addr, d.tlsConfig, nil)
|
// 각 RPC 호출마다 개별 스트림을 매핑하는 connect-go 또는 커스텀 Transport 구조의 세션을 관리
|
||||||
|
quicConn, err := quic.DialAddr(quicCtx, addr, d.quicTLSConfig, nil)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
stream, err := quicConn.OpenStreamSync(ctx)
|
// 단일 커넥션 내부 스트림 생성을 래핑하는 커넥션 핸들러 반환
|
||||||
if err == nil {
|
return &quicSessionWrapper{conn: quicConn}, nil
|
||||||
return &quicStreamConn{stream: stream, conn: quicConn}, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 실패 시 TCP 기반 HTTP/2 Fallback 실행
|
// 2. QUIC 다이얼 실패 또는 UDP 블로킹 감지 시 TCP/HTTP/2 Fallback 실행
|
||||||
dialer := &net.Dialer{Timeout: d.timeout}
|
dialer := &net.Dialer{Timeout: d.timeout}
|
||||||
tcpConn, err := dialer.DialContext(ctx, "tcp", addr)
|
tcpConn, err := dialer.DialContext(ctx, "tcp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("both QUIC and HTTP/2 fallback failed: %w", err)
|
return nil, fmt.Errorf("both QUIC dial and HTTP/2 fallback failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsConn := tls.Client(tcpConn, d.tlsConfig)
|
tlsConn := tls.Client(tcpConn, d.tcpTLSConfig)
|
||||||
if err := tlsConn.HandshakeContext(ctx); err != nil {
|
if err := tlsConn.HandshakeContext(ctx); err != nil {
|
||||||
tcpConn.Close()
|
tcpConn.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -609,6 +630,83 @@ func (d *FallbackDialer) DialContext(ctx context.Context, addr string) (net.Conn
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
##### 2. 서버 측 전송 어댑터 명세 (`internal/gateway/server.go`)
|
||||||
|
|
||||||
|
서버 측 역시 단일 연결을 무조건 수락(Accept)하여 gRPC 서버에 전달할 경우 동적 다중 스트림 매핑이 손실된다. 따라서 서버 측은 다음과 같이 HTTP/3 서버 위에 `connect-go` 등의 gRPC 호환 서비스 핸들러를 마운트하여 **단일 비즈니스 로직(Handler)이 HTTP/3와 HTTP/2 폴백 연결에서 공유**되도록 구성한다.
|
||||||
|
|
||||||
|
```go
|
||||||
|
package gateway
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/quic-go/quic-go/http3"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GatewayServer struct {
|
||||||
|
h3Server *http3.Server
|
||||||
|
h2Server *http.Server
|
||||||
|
handler http.Handler // HTTP/3 및 HTTP/2 공용 gRPC-compatible 핸들러
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGatewayServer(addr string, tlsConfig *tls.Config, handler http.Handler) *GatewayServer {
|
||||||
|
h3TLS := tlsConfig.Clone()
|
||||||
|
h3TLS.NextProtos = []string{"h3"}
|
||||||
|
|
||||||
|
h2TLS := tlsConfig.Clone()
|
||||||
|
h2TLS.NextProtos = []string{"h2"}
|
||||||
|
|
||||||
|
return &GatewayServer{
|
||||||
|
h3Server: &http3.Server{
|
||||||
|
Addr: addr,
|
||||||
|
TLSConfig: h3TLS,
|
||||||
|
Handler: handler,
|
||||||
|
},
|
||||||
|
h2Server: &http.Server{
|
||||||
|
Addr: addr,
|
||||||
|
TLSConfig: h2TLS,
|
||||||
|
Handler: handler, // 동일 비즈니스 핸들러 공유
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *GatewayServer) Start() error {
|
||||||
|
errChan := make(chan error, 2)
|
||||||
|
|
||||||
|
// HTTP/3 (UDP) 서버 기동
|
||||||
|
go func() {
|
||||||
|
errChan <- s.h3Server.ListenAndServeTLS("", "")
|
||||||
|
}()
|
||||||
|
|
||||||
|
// HTTP/2 (TCP) 서버 기동 (폴백 대비 수신 채널)
|
||||||
|
go func() {
|
||||||
|
errChan <- s.h2Server.ListenAndServeTLS("", "")
|
||||||
|
}()
|
||||||
|
|
||||||
|
return <-errChan
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### 3. 소거 실험용 비교군 명세 (Naive Single-Stream Tunneling)
|
||||||
|
|
||||||
|
스트림 매핑 유무가 HOLB 해소에 미치는 실질적인 영향을 입증하는 소거 실험(Ablation Study) 비교군 구성을 위해, 기존에 논의된 단일 QUIC 스트림 고정 터널링(Naive) 코드를 아래와 같이 별도로 명세한다. 이 명세는 평가 단계(Evaluation)에서 패킷 손실 시 TCP와 동등한 수준의 지연시간 병목이 유발됨을 입증하는 대조군으로 기능한다.
|
||||||
|
|
||||||
|
```go
|
||||||
|
// naiveStreamConn은 하나의 QUIC 커넥션에서 단 하나의 스트림만을 점유하여
|
||||||
|
// gRPC-Go에 net.Conn 인터페이스로 노출함으로써 강제로 단일 채널 터널링을 수행한다.
|
||||||
|
type naiveStreamConn struct {
|
||||||
|
quic.Stream
|
||||||
|
conn quic.Connection
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *naiveStreamConn) LocalAddr() net.Addr { return c.conn.LocalAddr() }
|
||||||
|
func (c *naiveStreamConn) RemoteAddr() net.Addr { return c.conn.RemoteAddr() }
|
||||||
|
// (본 naive 구현은 개별 RPC의 독립 스트림 권한을 박탈하여 세션 내 HOLB를 유발함)
|
||||||
|
```
|
||||||
|
|
||||||
### 4.2 MQTT→gRPC 변환 엔진
|
### 4.2 MQTT→gRPC 변환 엔진
|
||||||
|
|
||||||
#### MQTT Topic 네이밍 규칙
|
#### MQTT Topic 네이밍 규칙
|
||||||
@@ -1338,7 +1436,7 @@ import (
|
|||||||
telemetryv1 "github.com/your-org/edge-aiot-mas/gen/go/telemetry/v1"
|
telemetryv1 "github.com/your-org/edge-aiot-mas/gen/go/telemetry/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// QUICDialer는 quic-go를 사용하여 gRPC 연결을 수립하는 다이얼러다.
|
// QUICDialer는 소거 실험(Ablation Study) 비교용 naive 단일 스트림 터널링 다이얼러다. (HOLB 재현 구조)
|
||||||
type QUICDialer struct {
|
type QUICDialer struct {
|
||||||
tlsConfig *tls.Config
|
tlsConfig *tls.Config
|
||||||
}
|
}
|
||||||
@@ -1348,7 +1446,7 @@ func NewQUICDialer(tlsConfig *tls.Config) *QUICDialer {
|
|||||||
return &QUICDialer{tlsConfig: tlsConfig}
|
return &QUICDialer{tlsConfig: tlsConfig}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DialContext는 gRPC의 WithContextDialer에 전달될 다이얼 함수다.
|
// DialContext는 소거 실험군(naive) gRPC 다이얼러 함수다.
|
||||||
func (d *QUICDialer) DialContext(ctx context.Context, addr string) (net.Conn, error) {
|
func (d *QUICDialer) DialContext(ctx context.Context, addr string) (net.Conn, error) {
|
||||||
// QUIC connection 수립
|
// QUIC connection 수립
|
||||||
conn, err := quic.DialAddr(ctx, addr, d.tlsConfig, &quic.Config{
|
conn, err := quic.DialAddr(ctx, addr, d.tlsConfig, &quic.Config{
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ AI 에이전트의 자율적 문제 해결 능력은 산업 현장의 제어 및
|
|||||||
본 논문에서는 이러한 4대 문제를 해소하기 위하여 **gRPC 기반의 통합 에이전트 인터페이스 모듈(gRPC-based Unified Interface Module)**을 설계하고 제안한다. 통신 백본으로 gRPC를 채택한 것은 다음의 세 가지 기술적 근거에 기반한다:
|
본 논문에서는 이러한 4대 문제를 해소하기 위하여 **gRPC 기반의 통합 에이전트 인터페이스 모듈(gRPC-based Unified Interface Module)**을 설계하고 제안한다. 통신 백본으로 gRPC를 채택한 것은 다음의 세 가지 기술적 근거에 기반한다:
|
||||||
|
|
||||||
- 첫째, 산업용 AIoT 구조는 온도·습도 값을 특정하여 edge 또는 cloud로 전송하는 하부의 '센싱 계층'(MQTT/CoAP 최적)과, "농약 살포"와 같이 명령을 내리고 결과를 확인해야 하는 '제어 계층'으로 자연스럽게 나뉜다. gRPC는 바로 이 제어 계층의 명령 호출에 특화된 프로토콜이며, 교환 가능한 기능과 데이터 형식을 계약서처럼 사전에 못박아 두는 인터페이스 명세(IDL)가 이종 에이전트의 기능 명세서인 Agent Card(A2A 계열 표준)와 정합적으로 매핑되어 표준 준수형 연동의 토대가 된다.
|
- 첫째, 산업용 AIoT 구조는 온도·습도 값을 특정하여 edge 또는 cloud로 전송하는 하부의 '센싱 계층'(MQTT/CoAP 최적)과, "농약 살포"와 같이 명령을 내리고 결과를 확인해야 하는 '제어 계층'으로 자연스럽게 나뉜다. gRPC는 바로 이 제어 계층의 명령 호출에 특화된 프로토콜이며, 교환 가능한 기능과 데이터 형식을 계약서처럼 사전에 못박아 두는 인터페이스 명세(IDL)가 이종 에이전트의 기능 명세서인 Agent Card(A2A 계열 표준)와 정합적으로 매핑되어 표준 준수형 연동의 토대가 된다.
|
||||||
- 둘째, TCP 기반 HTTP/2는 무선 손실 환경에서 패킷 유실 시 전체 스트림이 지연되는 Head-of-Line Blocking(HOLB) 한계를 갖는다. 본 제안은 단일 연결 내 차선별 독립 주행이 가능한 gRPC over QUIC(HTTP/3)를 채택하여, 신호 손실이 잦은 무선 환경에서도 텍스트 제어 명령, 카메라 이미지 스트림, 장치 상태 회신이 상호 간섭 없이 동시에 흐르게 한다. 이는 connection migration 및 0-RTT 재연결 특성과 결합되어, 상시 연결 상태의 장치 계층과 필요 시 작업 단위로 기동되는 에이전트 계층 간의 주기 차이를 전송 계층 수준에서 저지연으로 완벽히 중재한다 [2, 11].
|
- 둘째, TCP 기반 HTTP/2는 무선 손실 환경에서 패킷 유실 시 전체 스트림이 지연되는 Head-of-Line Blocking(HOLB) 한계를 갖는다. 이를 비유하면 **하나의 파이프라인(TCP 연결) 내에 여러 차선(스트림)을 설계하더라도, 한 차선에서 사고(패킷 유실)가 발생하면 도로 전체가 정체되는 구조**와 같다. 본 제안은 UDP 기반 연결 위에서 **각 RPC 호출을 네트워크 수준의 독립된 QUIC 스트림으로 1:1 매핑하는 gRPC over QUIC(HTTP/3)**을 채택하여 이 한계를 해소한다. 한 차선(스트림)의 사고가 다른 독립 차선에 영향을 주지 않는 구조적 독립 주행을 통해, 신호 손실이 잦은 무선 환경에서도 텍스트 제어 명령, 카메라 이미지 스트림, 장치 상태 회신이 상호 간섭 없이 동시에 흐르게 한다. 이는 connection migration 및 0-RTT 재연결 특성과 결합되어, 상시 연결 상태의 장치 계층과 필요 시 작업 단위로 기동되는 에이전트 계층 간의 주기 차이를 전송 계층 수준에서 저지연으로 완벽히 중재한다 [2, 11].
|
||||||
- 셋째, gRPC의 Protobuf는 송수신 양측이 미리 약속한 스키마에 따라 데이터를 압축된 이진 형태로 주고받으므로 텍스트(JSON)를 한 글자씩 해석하는 비용이 사라지고 전송 크기도 크게 줄어든다. 여기에 Envoy 로드 밸런서·Kubernetes 상태 감시 등 이미 검증된 클라우드 네이티브 인프라를 기존 전력망과 도로망에 접속하듯 그대로 활용할 수 있어, 대량 에이전트 태스크의 생명주기 관리와 부하 분산을 밑단부터 새로 구축할 필요가 없다(상세 논거는 2장에서 다룬다).
|
- 셋째, gRPC의 Protobuf는 송수신 양측이 미리 약속한 스키마에 따라 데이터를 압축된 이진 형태로 주고받으므로 텍스트(JSON)를 한 글자씩 해석하는 비용이 사라지고 전송 크기도 크게 줄어든다. 여기에 Envoy 로드 밸런서·Kubernetes 상태 감시 등 이미 검증된 클라우드 네이티브 인프라를 기존 전력망과 도로망에 접속하듯 그대로 활용할 수 있어, 대량 에이전트 태스크의 생명주기 관리와 부하 분산을 밑단부터 새로 구축할 필요가 없다(상세 논거는 2장에서 다룬다).
|
||||||
|
|
||||||
본 연구의 주요 기여는 다음과 같이 요약된다:
|
본 연구의 주요 기여는 다음과 같이 요약된다:
|
||||||
@@ -57,7 +57,7 @@ AIoT 기반 지능형 에이전트 시스템은 텍스트뿐 아니라 고해상
|
|||||||
|
|
||||||
gRPC가 기반하는 HTTP/2의 다중화(Multiplexing)는 단일 TCP 연결 상에서 여러 스트림을 전송하여 연결 수립 오버헤드를 낮추는 개선을 이루었으나 [10], TCP 프로토콜 수준의 Head-of-Line Blocking(HOLB) 한계로 인해 무선 엣지 네트워크에서 패킷 유실 발생 시 전체 스트림이 함께 지연되는 구조적 문제를 안고 있다. 또한 게이트웨이의 이동에 따른 핸드오버 발생 시 연결이 전면 재수립되어야 하는 취약점이 존재한다.
|
gRPC가 기반하는 HTTP/2의 다중화(Multiplexing)는 단일 TCP 연결 상에서 여러 스트림을 전송하여 연결 수립 오버헤드를 낮추는 개선을 이루었으나 [10], TCP 프로토콜 수준의 Head-of-Line Blocking(HOLB) 한계로 인해 무선 엣지 네트워크에서 패킷 유실 발생 시 전체 스트림이 함께 지연되는 구조적 문제를 안고 있다. 또한 게이트웨이의 이동에 따른 핸드오버 발생 시 연결이 전면 재수립되어야 하는 취약점이 존재한다.
|
||||||
|
|
||||||
본 제안 모듈은 UDP 위에서 독립된 스트림 멀티플렉싱과 Connection ID 기반의 세션 유지를 지원하는 **gRPC over QUIC(HTTP/3) 프로토콜을 핵심 전송 백본으로 채택**하여 이 한계를 근본적으로 해결한다 [2, 11]. 한 차선(스트림)의 유실이 다른 차선에 영향을 주지 않아 무선 손실 환경에서도 저지연 스트리밍을 유지하며, IP가 변경되는 핸드오버 상황에서도 기존 전송 연결을 유지(Connection Migration)함으로써 에이전트 제어 안정성을 보장한다. 비록 현재 공식 gRPC 스택에서의 HTTP/3 표준 지원은 부분적이거나 실험적 단계에 있으나, 본 연구는 `quic-go`를 기반으로 커스텀 전송 계층 어댑터를 구현하여 무선 엣지 환경에서의 실효성을 실증한다. 이는 본 논문의 핵심적인 실증/구현 기여 중 하나이며, 동시에 방화벽 UDP 차단 등 QUIC 사용이 불가한 예외 환경에 대응하기 위한 HTTP/2 폴백(Fallback) 전송 협상 구조를 함께 내장하여 범용적 호환성을 확보한다. gRPC가 이미 마이크로서비스 아키텍처(MSA)의 사실상 표준 인터페이스로 통용되고 있다는 점은 제안 모듈의 현업 시스템 이식성과 확장 속도 측면에서도 이점으로 작용한다.
|
본 제안 모듈은 UDP 위에서 독립된 스트림 멀티플렉싱과 Connection ID 기반의 세션 유지를 지원하는 **gRPC over QUIC(HTTP/3) 프로토콜을 핵심 전송 백본으로 채택**하여 이 한계를 근본적으로 해결한다 [2, 11]. 특히 **각 RPC 호출을 네트워크 수준의 독립된 QUIC 스트림에 1:1로 매핑**함으로써, 한 차선(스트림)의 유실이 다른 차선에 영향을 주지 않는 구조적 차선 독립 주행을 구현하여 무선 손실 환경에서도 저지연 스트리밍을 유지하며, IP가 변경되는 핸드오버 상황에서도 기존 전송 연결을 유지(Connection Migration)함으로써 에이전트 제어 안정성을 보장한다. 비록 현재 공식 gRPC 스택에서의 HTTP/3 표준 지원은 부분적이거나 실험적 단계에 있으나, 본 연구는 `quic-go`를 기반으로 커스텀 전송 계층 어댑터를 구현하여 무선 엣지 환경에서의 실효성을 실증한다. 이는 본 논문의 핵심적인 실증/구현 기여 중 하나이며, 동시에 방화벽 UDP 차단 등 QUIC 사용이 불가한 예외 환경에 대응하기 위한 다이얼 실패 기반 HTTP/2 폴백(Fallback) 전송 구조를 함께 내장하여 범용적 호환성을 확보한다. gRPC가 이미 마이크로서비스 아키텍처(MSA)의 사실상 표준 인터페이스로 통용되고 있다는 점은 제안 모듈의 현업 시스템 이식성과 확장 속도 측면에서도 이점으로 작용한다.
|
||||||
|
|
||||||
### 구조화된 직렬화 기반의 태스크 생명주기 관리 및 부하 분산 효율
|
### 구조화된 직렬화 기반의 태스크 생명주기 관리 및 부하 분산 효율
|
||||||
|
|
||||||
@@ -113,8 +113,8 @@ AIoT 서비스 환경에서 멀티 에이전트 오케스트레이션(Multi-Agen
|
|||||||
|
|
||||||
## gRPC Communication Backbone
|
## gRPC Communication Backbone
|
||||||
- Protobuf 기반 메시지 스키마 정의 (태스크, 이벤트, 제어 명령 규격)
|
- Protobuf 기반 메시지 스키마 정의 (태스크, 이벤트, 제어 명령 규격)
|
||||||
- QUIC(HTTP/3) 기반 양방향 스트리밍을 통한 상시 연결 계층과 작업 단위 계층의 중재 및 HTTP/2 폴백(Fallback) 전송 협상 절차 (시간 축 해소)
|
- QUIC(HTTP/3) 기반 양방향 스트리밍(RPC별 독립 스트림 매핑)을 통한 상시 연결 계층과 작업 단위 계층의 중재 및 다이얼 실패 기반 HTTP/2 폴백(Fallback) 전송 절차 (시간 축 해소)
|
||||||
- Request/Response 및 스트리밍 기반 Pub/Sub 패턴 구현
|
- Request/Response 및 스트리밍 기반 Pub/Sub 패턴 구현 (과대 주장 방지: N:N 팬아웃 및 보존이 필요한 대규모 통신은 별도 메시지 브로커 연동 필요 제약 명기)
|
||||||
|
|
||||||
## Agent Card-based Dynamic Binding Layer
|
## Agent Card-based Dynamic Binding Layer
|
||||||
- 에이전트/장치/추론 모델 명세의 Agent Card 규격화 및 서빙 (`/.well-known/agent-card.json`)
|
- 에이전트/장치/추론 모델 명세의 Agent Card 규격화 및 서빙 (`/.well-known/agent-card.json`)
|
||||||
@@ -141,7 +141,7 @@ AIoT 서비스 환경에서 멀티 에이전트 오케스트레이션(Multi-Agen
|
|||||||
|
|
||||||
## Software Stack and Agent Deployment
|
## Software Stack and Agent Deployment
|
||||||
- 에이전트 프레임워크 및 제안 모듈 구현 스택 (gRPC/Protobuf 버전 포함)
|
- 에이전트 프레임워크 및 제안 모듈 구현 스택 (gRPC/Protobuf 버전 포함)
|
||||||
- 비교군(Baseline) 구성: 기존 REST/MQTT 기반 연동 방식 및 gRPC over HTTP/2 (전송 기여 분리 증명용 비교군)
|
- 비교군(Baseline) 구성: 기존 REST/MQTT 기반 연동 방식 및 gRPC over HTTP/2, 그리고 gRPC/QUIC 단일 스트림 터널링 naive 구현체 (어댑터 기여 분석을 위한 소거 실험 비교군)
|
||||||
|
|
||||||
## Evaluation Scenarios and Metrics
|
## Evaluation Scenarios and Metrics
|
||||||
- 평가 시나리오: 정상 경로, 무선 손실(패킷 유실 주입) 및 핸드오버(IP 변경), 재시도/장애 주입(Fault Injection), 동시 다중 위임
|
- 평가 시나리오: 정상 경로, 무선 손실(패킷 유실 주입) 및 핸드오버(IP 변경), 재시도/장애 주입(Fault Injection), 동시 다중 위임
|
||||||
@@ -150,7 +150,7 @@ AIoT 서비스 환경에서 멀티 에이전트 오케스트레이션(Multi-Agen
|
|||||||
# Performance Analysis
|
# Performance Analysis
|
||||||
|
|
||||||
## Experimental Results
|
## Experimental Results
|
||||||
- 전송 계층 및 프로토콜별 비교 (gRPC/QUIC vs. gRPC/HTTP2 vs. REST/MQTT): 정상, 무선 유실 및 핸드오버 조건 하에서의 지연 시간 및 처리량
|
- 전송 계층 및 어댑터 매핑별 비교 (gRPC/QUIC per-RPC 스트림 vs. gRPC/QUIC naive 터널링 vs. gRPC/HTTP2 vs. REST/MQTT): 정상, 무선 유실 및 핸드오버 조건 하에서의 지연 시간 및 처리량 (단, naive 터널링 비교군의 HOLB 재현 지표는 RQ 1 지표에 한해 한정 분석)
|
||||||
- 자원 효율성 분석: 이벤트 기반 위임 구조의 노드 점유율 절감 효과
|
- 자원 효율성 분석: 이벤트 기반 위임 구조의 노드 점유율 절감 효과
|
||||||
- 안정성 검증: 재시도 루프 하에서의 중복 제어 억제율 (멱등성 보장 효과)
|
- 안정성 검증: 재시도 루프 하에서의 중복 제어 억제율 (멱등성 보장 효과)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user