본문으로 건너뛰기
김신건의 로그

[Network] gRPC: HTTP/2 + Protobuf, 4가지 streaming 패턴

· 수정 · 📖 약 2분 · 555자/단어 #grpc #rpc #network #backend #protobuf #http2
gRPC, Protocol Buffers, Protobuf, gRPC streaming, unary RPC, bidirectional streaming, grpc-web

정의

gRPCHTTP/2 위에서 Protobuf 직렬화 로 동작하는 고성능 RPC 프레임워크. Google 내부 Stubby 의 오픈소스 후계.

핵심 4가지:

  1. Protobuf: IDL + binary 직렬화 (JSON 대비 수배 작고 빠름)
  2. HTTP/2: multiplexing + binary framing
  3. Streaming 4종: unary, server-stream, client-stream, bidi
  4. Code generation: .proto → 다국어 stub 자동 생성

Proto 정의

syntax = "proto3";
package shop.v1;

service Shop {
  // Unary: 1 req → 1 res
  rpc GetItem(GetItemRequest) returns (Item);

  // Server streaming: 1 req → N res
  rpc ListItems(ListRequest) returns (stream Item);

  // Client streaming: N req → 1 res
  rpc UploadEvents(stream Event) returns (UploadAck);

  // Bidirectional: N req ↔ N res
  rpc Chat(stream Message) returns (stream Message);
}

message Item {
  string id = 1;
  string name = 2;
  int32 price_cents = 3;
}

4가지 Streaming 패턴

flowchart TB
    subgraph Unary["Unary RPC"]
        U1[Client] -->|1 request| U2[Server]
        U2 -->|1 response| U1
    end
    subgraph ServerStream["Server Streaming"]
        S1[Client] -->|1 request| S2[Server]
        S2 -->|stream of N| S1
    end
    subgraph ClientStream["Client Streaming"]
        C1[Client] -->|stream of N| C2[Server]
        C2 -->|1 response| C1
    end
    subgraph BiDi["Bidirectional Streaming"]
        B1[Client] -->|stream of N| B2[Server]
        B2 -->|stream of M| B1
    end
패턴사용
Unary일반 API
Server stream라이브 피드, log tail, 실시간 시세
Client stream파일 업로드, 이벤트 일괄 전송
Bidi stream채팅, 게임, 협업

HTTP/2 위 동작

:method = POST
:scheme = https
:path = /shop.v1.Shop/GetItem
:authority = api.example.com
content-type = application/grpc
grpc-encoding = gzip
grpc-accept-encoding = identity,deflate,gzip
grpc-timeout = 1S

<protobuf-encoded body>

각 RPC = HTTP/2 stream 하나. Trailersgrpc-status, grpc-message 전달.

Status Code

코드의미
0 OK성공
1 CANCELLED클라이언트가 cancel
2 UNKNOWN정체불명 에러
3 INVALID_ARGUMENT입력 오류
4 DEADLINE_EXCEEDEDtimeout
5 NOT_FOUND리소스 없음
6 ALREADY_EXISTS중복
7 PERMISSION_DENIED권한
8 RESOURCE_EXHAUSTEDquota 초과
9 FAILED_PRECONDITION사전조건 위배
10 ABORTED동시성 충돌
11 OUT_OF_RANGE범위 외
12 UNIMPLEMENTED구현 안됨
13 INTERNAL내부 에러
14 UNAVAILABLE일시 불가, retry 권장
15 DATA_LOSS손실
16 UNAUTHENTICATED인증 실패

IMPORTANT

UNAVAILABLE (14) 만 retry 안전. DEADLINE_EXCEEDED (4)side effect 가 발생했을 수 있어 idempotent operation 만 retry.

Deadline (timeout)

# Python
response = stub.GetItem(req, timeout=1.0)  # 1초

# 또는 metadata
metadata = (("grpc-timeout", "1S"),)

클라이언트의 deadline 은 서버에 전파 (header). 서버가 더 깊은 RPC 를 부르면 남은 deadline 만 전달. 분산 timeout chaining.

gRPC vs REST

항목gRPCREST
Wire 포맷Binary (Protobuf)Text (JSON)
크기수배 작음크다
SchemaIDL 필수옵션 (OpenAPI)
Streaming4 모드SSE / WebSocket 별도
브라우저 직접 호출grpc-web 필요기본 지원
Debugging도구 필요curl 가능
캐싱직접 구현HTTP cache
Mobile / IoT유리OK

내부 microservice 통신 → gRPC. 외부 public API → REST/GraphQL.

gRPC-Web

브라우저는 HTTP/2 trailer 미지원 → Envoy / proxygRPC ↔ gRPC-Web 변환:

flowchart LR
    Browser -->|gRPC-Web<br/>over HTTP/1.1| Envoy
    Envoy -->|gRPC<br/>over HTTP/2| Backend

흔한 함정

WARNING

  1. Field number 재사용 = proto 의 tag 번호wire format 의 identity. 한 번 쓴 번호 영구히 reserved.
  2. required 필드 = proto2 의 legacy. proto3 는 모든 필드가 optional 류. required 사용 금지.
  3. string vs bytes = string 은 UTF-8 검증. binary 데이터는 bytes.
  4. stream 의 완료 표시 = 클라이언트 stream 은 반드시 half-close (closeSend) 해야 서버가 finalize.

관련 위키

이 글의 용어 (4개)
[API Design] GraphQL: 단일 endpoint, N+1, persisted queriesapi-design
정의 GraphQL (Facebook, 2015) 은 클라이언트가 필요한 필드만 명시 하는 query language + 런타임. 단일 endpoint, typed schema,…
[API Design] REST API: 원칙, 자원 모델링, HATEOAS, 버전 관리api-design
정의 REST (Representational State Transfer) 는 Roy Fielding 의 2000년 박사논문에서 정립된 분산 시스템 아키텍처 스타일. HTTP 의…
[Network] HTTP/2: multiplexing, HPACK, server push의 종말network
정의 HTTP/2 (2015, RFC 9113) 는 HTTP/1.1 의 문법은 유지하되 전송을 바이너리 + 멀티플렉싱 으로 바꾼다. Head-of-Line Blocking (HT…
[Pattern] Microservices vs Monolith: 언제 분리, 언제 통합distributed-systems
정의 | | Monolith | Modular Monolith | Microservices | |---|---|---|---| | 배포 단위 | 1개 | 1개 (모듈 명확) | …

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기