gRPC + Spring Boot — 기본 개념·HTTP/2·4 RPC 모드

2026-05-03확률과 통계 마스터 노트

gRPC + Spring Boot 마스터 노트 시리즈 1편. gRPC가 Google 내부 RPC를 오픈소스화한 배경, HTTP/2의 multiplexing·서버 푸시·바이너리 프레임이 gRPC의 토대인 이유, 4 RPC 모드(Unary·Server Streaming·Client Streaming·Bidirectional)의 차이, Spring Boot에 grpc-spring-boot-starter로 통합하는 흐름까지.

이 글은 gRPC + Spring Boot 마스터 노트 시리즈의 첫 번째 편입니다. 마이크로서비스 사이 통신의 클라우드 네이티브 표준은 gRPC. HTTP/2 위 Protobuf로 강력한 타입 + 빠른 성능 + 4 RPC 모드.

이 시리즈 10편은 기본·Protobuf·4 RPC 모드·Interceptor·에러·보안·고급까지. 1편의 목표 — gRPC가 무엇이고 왜 표준이 됐는지 손에 잡히게.

📚 학습 노트

이 시리즈는 gRPC 공식 문서, Protobuf 가이드, grpc-spring-boot-starter 문서, CNCF 학습 자료 등 공개 자료를 참고해 한국어 학습 노트로 풀어쓴 자료입니다.

Spring Boot 프로젝트에 grpc-spring-boot-starter 추가하고 첫 Unary RPC를 직접 띄워 보면 흐름이 한 번에 잡혀요. 30분이면 첫 gRPC 통신이 손에 들어옵니다.

처음 gRPC가 어렵게 느껴지는 이유

처음 이 단원이 어렵게 느껴지는 이유는 두 가지예요. 첫째, HTTP/2·Protobuf·gRPC 셋이 한 번에 등장합니다. 누가 누구 위에? 둘째, 4 RPC 모드가 막연합니다.

해결법은 한 가지예요. "Protobuf = 스키마 / HTTP/2 = 전송 / gRPC = 둘 결합" 한 줄. 셋이 각자 역할 명확. 이 그림이 잡히면 디테일이 따라옵니다.

gRPC = Google RPC

Google 내부 RPC (Stubby)
  ↓ 2015 오픈소스화
gRPC (CNCF 표준)

특징:

  • Protobuf = 인터페이스 정의·직렬화
  • HTTP/2 = 전송 계층
  • 다양한 언어 지원 (10+ 공식)
  • 양방향 스트리밍

왜 표준이 됐나

HTTP/1.1 + JSON:
  - 요청-응답만
  - 큰 헤더 (수백 바이트)
  - 텍스트 (큼·느림)
  - 스키마 X

gRPC:
  - 4 RPC 모드 (양방향 포함)
  - HTTP/2 헤더 압축 (HPACK)
  - 바이너리 (작음·빠름)
  - 강력한 스키마 (Protobuf)

여기서 정말 중요한 시험 함정 — gRPC = CNCF 마이크로서비스 통신 표준. Kubernetes·Envoy·Istio 모두 gRPC 네이티브 지원. 외부 API는 REST, 내부는 gRPC가 표준 패턴.

HTTP/2 — gRPC의 토대

HTTP/1.1 한계

1 요청 = 1 연결 (또는 keep-alive)
헤더 매번 전송 (수백 바이트)
순차 처리 (head-of-line blocking)
양방향 X

HTTP/2 개선

- Multiplexing: 1 연결 + N 동시 스트림
- Header Compression (HPACK): 헤더 90%+ 줄임
- Binary Framing: 텍스트 X, 바이너리
- Server Push: 서버가 클라이언트로 푸시

여기서 시험 함정이 하나 있어요. HTTP/2는 gRPC 전용 X — 일반 HTTP에도 사용. gRPC는 HTTP/2의 기능을 RPC에 활용.

4 RPC 모드

1. Unary RPC                 — 1:1 (HTTP 같음)
2. Server Streaming          — 1:N (서버가 N개 응답)
3. Client Streaming          — N:1 (클라이언트가 N개 보냄)
4. Bidirectional Streaming   — N:N (양방향)

자세한 건 3~6편.

여기서 정말 중요한 시험 함정 — gRPC 4 모드 ≈ RSocket 4 Models (RR·FNF·Stream·Channel). 거의 1:1 매핑. 다만 gRPC = Protobuf 강제, RSocket = 자유.

Protobuf — 스키마 + 직렬화

syntax = "proto3";

service UserService {
  rpc GetUser (UserRequest) returns (User);
  rpc ListUsers (Empty) returns (stream User);
  rpc CreateUsers (stream User) returns (CreateResult);
  rpc Chat (stream Message) returns (stream Message);
}

message UserRequest {
  string id = 1;
}

message User {
  string id = 1;
  string name = 2;
  int32 age = 3;
}

자세한 건 2편.

특징:

  • 매우 컴팩트 (바이너리)
  • 강력한 타입 안전
  • 자동 코드 생성 (Java·Go·Python·...)
  • 스키마 진화 (필드 추가·삭제 안전)

Spring Boot 통합 — grpc-spring-boot-starter

의존성

plugins {
    id 'com.google.protobuf' version '0.9.4'
}

dependencies {
    implementation 'net.devh:grpc-spring-boot-starter:3.x'
    implementation 'io.grpc:grpc-stub'
    implementation 'io.grpc:grpc-protobuf'
}

protobuf {
    protoc { artifact = 'com.google.protobuf:protoc:3.x' }
    plugins {
        grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.x' }
    }
    generateProtoTasks {
        all()*.plugins { grpc {} }
    }
}

디렉토리 구조

src/
├── main/
│   ├── proto/                          # .proto 파일
│   │   └── user.proto
│   ├── java/                           # 자동 생성 코드 + 비즈니스
│   └── resources/
└── build/generated/                    # protoc 자동 생성
    └── source/proto/main/grpc/
        └── UserServiceGrpc.java

application.yml

grpc:
  server:
    port: 9090
    enable-keep-alive: true
    keep-alive-time: 30s
  client:
    user-service:
      address: static://localhost:9090
      negotiation-type: plaintext

가장 단순한 서버

import net.devh.boot.grpc.server.service.GrpcService;

@GrpcService
public class UserServiceImpl extends UserServiceGrpc.UserServiceImplBase {

    @Override
    public void getUser(UserRequest request, StreamObserver<User> responseObserver) {
        User user = User.newBuilder()
            .setId(request.getId())
            .setName("Alice")
            .setAge(30)
            .build();

        responseObserver.onNext(user);
        responseObserver.onCompleted();
    }
}

@GrpcService 어노테이션 + 자동 생성된 UserServiceGrpc.UserServiceImplBase 상속.

가장 단순한 클라이언트

import net.devh.boot.grpc.client.inject.GrpcClient;

@Service
public class UserClient {

    @GrpcClient("user-service")
    private UserServiceGrpc.UserServiceBlockingStub blockingStub;

    public User getUser(String id) {
        UserRequest request = UserRequest.newBuilder().setId(id).build();
        return blockingStub.getUser(request);
    }
}

@GrpcClient 어노테이션 + Stub 자동 주입.

Stub 종류 3

// 1. BlockingStub — 동기 (Unary·Server Streaming만)
UserServiceGrpc.UserServiceBlockingStub blockingStub;

// 2. AsyncStub — 비동기 (모든 모드)
UserServiceGrpc.UserServiceStub asyncStub;

// 3. FutureStub — Future 기반 (Unary만)
UserServiceGrpc.UserServiceFutureStub futureStub;

여기서 시험 함정이 하나 있어요. Streaming 모드 = AsyncStub만. BlockingStub은 Unary·Server Streaming만 지원.

gRPC vs REST vs RSocket

측면 gRPC REST RSocket
프로토콜 HTTP/2 HTTP/1.1·2 TCP·WebSocket
직렬화 Protobuf JSON 자유
양방향 O (4 모드) X O (4 Models)
백프레셔 부분 X 표준
브라우저 gRPC-Web 네이티브 WebSocket transport
생태계 매우 큼 매우 큼 작음
학습 중간 낮음 중간

여기서 정말 중요한 시험 함정 — 공개 API = REST / 내부 마이크로서비스 = gRPC가 표준 패턴. 둘 결합도 OK (Gateway에서 변환).

gRPC 사용 사례

적합

  • 마이크로서비스 사이 (강력한 스키마)
  • 다국어 환경 (Java·Go·Python 등 함께)
  • 고성능 (작은 메시지·바이너리)
  • 양방향·스트리밍
  • Cloud Native (Kubernetes·Envoy·Istio 친화)

부적합

  • 공개 API (REST가 친화)
  • 브라우저 직접 (gRPC-Web 한정)
  • 단순 CRUD (REST 충분)

디버깅 도구

grpcurl

# 서비스 목록
grpcurl -plaintext localhost:9090 list

# 호출
grpcurl -plaintext -d '{"id": "123"}' localhost:9090 UserService/GetUser

curl의 gRPC 버전.

BloomRPC·Postman·Insomnia

GUI 도구. Protobuf 스키마 자동 인식.

Reflection

@Bean
public ServerInterceptor reflection() {
    return ProtoReflectionService.newInstance();
}

서버가 자기 스키마 노출 → 클라이언트 자동 발견. 자세한 건 10편.

시험 직전 한 번 더 — 자주 헷갈리는 함정 모음

여기까지가 1편의 핵심입니다. 시험 직전 또는 실무에서 헷갈릴 때 다시 펼쳐 볼 수 있게 압축 노트로 마무리할게요.

  • gRPC = Google RPC + 오픈소스 (2015 CNCF)
  • Protobuf (스키마) + HTTP/2 (전송) + gRPC (RPC 결합)
  • HTTP/2 — Multiplexing·HPACK·Binary·Server Push
  • HTTP/2는 gRPC 전용 X (일반 HTTP에도)
  • 4 RPC 모드Unary / Server Streaming / Client Streaming / Bidirectional Streaming
  • gRPC 4 모드 ≈ RSocket 4 Models
  • gRPC = Protobuf 강제, RSocket = 자유
  • Protobuf = 컴팩트·타입 안전·자동 코드 생성·스키마 진화
  • grpc-spring-boot-starter Spring Boot 통합
  • 의존성 + protobuf gradle 플러그인
  • .proto 파일 → 자동 코드 생성
  • @GrpcService = 서버 + UserServiceGrpc.UserServiceImplBase 상속
  • @GrpcClient = 클라이언트 Stub 자동 주입
  • Stub 3종BlockingStub (동기, Unary·Server Streaming만) / AsyncStub (비동기, 모든 모드) / FutureStub (Future, Unary만)
  • gRPC vs REST vs RSocket — 표준화·생태계·백프레셔
  • 공개 API = REST / 내부 = gRPC 표준 패턴
  • 적합 — 마이크로서비스·다국어·고성능·스트리밍·Cloud Native
  • 부적합 — 공개 API·브라우저 직접·단순 CRUD
  • 도구 — grpcurl (CLI) / BloomRPC·Postman·Insomnia (GUI) / Reflection

시리즈 다른 편

공식 문서: gRPC Documentation / grpc-spring-boot-starter 에서 더 깊이.

다음 글(2편)에서는 Protobuf — 메시지 정의·필드 번호·기본 타입·반복·중첩·oneof·스키마 진화까지 풀어 갑니다.

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

답글 남기기

error: Content is protected !!