Blog / Architecture / gRPC 에 대해서

gRPC 에 대해서

gRPC란

Java/Spring Boot 개발자 입장에서 처음 gRPC를 접하면 다음과 같은 의문이 생긴다.

  • REST API와 무엇이 다른가?
  • DTO는 어떻게 정의하는가?
  • Front-End에서 직접 호출할 수 있는가?
  • 실무에서 언제 사용하는가?

본 글에서는 gRPC의 개념과 REST와의 차이점, 그리고 실제 활용 방안을 정리해본다.


REST vs gRPC

REST

Spring Boot에서는 일반적으로 다음과 같이 API를 구현한다.

java
@RestController
@RequestMapping("/users")
public class UserController {

    @GetMapping("/{id}")
    public UserResponse getUser(@PathVariable Long id) {
        return new UserResponse(id, "Walter");
    }
}

요청

http
GET /users/1

응답

json
{
  "id": 1,
  "name": "Walter"
}

REST는 HTTP와 JSON을 기반으로 동작하며, 사람이 읽고 디버깅하기 쉽다.


gRPC

gRPC는 Google이 개발한 RPC(Remote Procedure Call) 프레임워크이다. REST가 URL과 JSON 중심이라면, gRPC는 함수 호출 중심이다.

java
userService.getUser(1L);

REST와 비슷한 형태로 원격 서비스를 호출한다.


Proto 파일이란?

gRPC의 핵심은 .proto 파일이다.

예를 들어:

proto
syntax = "proto3";

package user;

service UserService {
  rpc GetUser(UserRequest)
      returns (UserResponse);
}

message UserRequest {
  int64 id = 1;
}

message UserResponse {
  int64 id = 1;
  string name = 2;
}

이 파일은 다음 세 가지 역할을 동시에 수행한다.

  • API 인터페이스 정의
  • Request/Response DTO 정의
  • 직렬화 규칙 정의

즉, Proto는 OpenAPI + DTO + Interface 를 합쳐놓은 개념으로 이해할 수 있다.


Proto → Java 코드 생성

Proto를 작성한 뒤 protoc 컴파일러를 실행하면 Java 코드가 자동 생성된다.

text
user.proto
    ↓
protoc
    ↓
generated/
 ├─ UserRequest.java
 ├─ UserResponse.java
 ├─ UserServiceGrpc.java

Spring Boot에서 gRPC 구현

생성된 클래스를 이용하여 서비스를 구현한다.

java
@GrpcService
public class UserGrpcService
        extends UserServiceGrpc.UserServiceImplBase {

    @Override
    public void getUser(UserRequest request, StreamObserver<UserResponse> responseObserver) {
        UserResponse response =
                UserResponse.newBuilder()
                        .setId(request.getId())
                        .setName("Walter")
                        .build();

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

여기서 사용하는

  • UserRequest
  • UserResponse
  • UserServiceGrpc

는 모두 Proto에서 자동 생성된 코드이다.


DTO는 Proto가 대신한다

REST에서는 DTO를 직접 작성한다.

java
public record UserResponse(
        Long id,
        String name
) { }

gRPC에서는 DTO를 직접 작성하지 않는다.

proto
message UserResponse {
  int64 id = 1;
  string name = 2;
}

이 정의만 작성하면 Java DTO가 자동 생성된다.

즉,

text
REST
↓
DTO 직접 작성

gRPC
↓
Proto 작성
↓
DTO 자동 생성

이런 구조이다.


REST와 gRPC의 성능 차이

REST는 JSON을 사용한다.

json
{
  "id": 1,
  "name": "Walter"
}

gRPC는 Protobuf 바이너리를 사용한다.

text
08 01 12 06 57 61 6c 74 65 72

결과적으로

  • Payload 크기 감소
  • 직렬화 비용 감소
  • 네트워크 비용 감소

효과를 얻을 수 있다.


HTTP/2 기반

gRPC는 HTTP/2를 사용한다.

REST(HTTP/1.1)

text
Request
Response

Request
Response

gRPC(HTTP/2)

text
Request1
Request2
Request3

Response1
Response2
Response3

동일 Connection에서 Multiplexing이 가능하다. 서비스 간 호출이 많은 환경에서는 큰 장점이 된다.


Streaming 지원

REST는 일반적으로 Request/Response 구조이다.

text
Client
 ↓
Request

30초 대기

Response

gRPC는 Streaming을 지원한다.

text
Client
 ↓

Token1
Token2
Token3
Token4

대표적인 활용 사례

  • AI 모델 추론
  • 실시간 로그
  • 실시간 모니터링
  • 채팅 시스템

Front-End에서 gRPC 호출 가능할까?

가능은 하다고 한다. 하지만 일반 브라우저는 순수 gRPC를 직접 지원하지 않는다. 따라서 보통 다음 구조가 필요하다.

text
Browser
   ↓
gRPC-Web
   ↓
Envoy
   ↓
gRPC Server

JavaScript 예시

javascript
const request = new UserRequest();
request.setId(1);

client.getUser(request, {}, (err, response) => {
    console.log(response.getName());
});

실무에서 많이 쓸 것 같지는 않다.


실무에서 가장 적용해 볼 만한 구조

대부분 다음 구조를 사용한다.

text
Frontend
     ↓ REST

API Gateway / BFF
     ↓ gRPC

User Service
Order Service
Payment Service
AI Service

  • 외부 인터페이스 → REST
  • 내부 서비스 간 통신 → gRPC

패턴이 가장 일반적이다.


Spring Boot 개발자 관점에서의 체감 차이

비즈니스 로직 관점에서는 REST와 gRPC의 차이가 크지 않다.

REST

java
@GetMapping
public UserResponse getUser(...)

gRPC

java
@Override
public void getUser(...)

정도의 차이다. 실제로 개발자가 구현하는 Service, Facade, Repository 계층은 거의 동일하다.


언제 gRPC를 선택해야 할까?

gRPC가 적합한 경우
  • 내부 마이크로서비스 간 통신
  • 고빈도 호출
  • 저지연 요구사항
  • AI 모델 서빙
  • 다국어(Java, Go, Python) 환경
  • Streaming 필요

REST가 적합한 경우
  • Frontend 연동
  • 외부 업체 연동
  • 공개 API
  • 단순 CRUD
  • 디버깅 편의성 우선

결론

gRPC는 REST를 대체하기 위한 기술이라기보다는, REST가 잘 해결하지 못하는 내부 서비스 간 고성능 통신 문제를 해결하기 위한 기술이라고 볼 수 있다. 다음과 같이 정리할 수 있다.

text
Frontend
    ↓ REST

API Gateway / BFF
    ↓ gRPC

Internal Services

즉,

REST는 외부 인터페이스, gRPC는 내부 서비스 간 통신

이라는 역할 분담이 현재 가장 널리 사용되는 아키텍처 패턴이다.
Spring Boot 개발자 입장에서 gRPC는 생각보다 어렵지 않다.
Controller가 gRPC Service로 바뀌고, DTO 대신 Proto를 사용한다고 이해하면 대부분의 개념을 빠르게 습득할 수 있다.

Written by
author
풍우래기

여행을 좋아하는 집돌이 개발자입니다.

블로그에 새로운 글이 발행되었습니다.