안녕하세요. 계속 춥다가 오늘 다시 풀리는 것 같네요. 아마 마지막 추위겠죠?
어제는 인증에 관한 여러 내용을 작성하느라 오래 걸렸었는데, 이번 시간에는 금방 끝낼 수 있을 것 같네요. 바로 시작해볼게요.
gRPC
gRPC(google Remote Procedure Call) 구글에서 개발한 고성능, 오픈소스 RPC 프레임워크이다. 클라이언트가 원격 서버에 있는 메서드를 마치 자신의 프로그램 안에 있는 함수처럼 호출할 수 있도록 도와주는 통신 방식입니다.
주로 마이크로서비스 환경에나 서비스 간 내부 통신처럼 빠르고 효율적인 데이터 교환이 필요한 상황에서 많이 사용됩니다.
gRPC 등장 배경
HTTP 기반 통신과 REST API
기존 서비스 간 통신에서는 주로 HTTP 기반 통신과 REST API가 사용되었습니다. REST는 이해하기 쉽고 범용성이 높아 외부 API와 웹 서비스에서 널리 사용되었습니다.
하지만 서비스 간 호출이 많아지는 환경에서는 JSON 기반 통신의 성능 부담, 인터페이스 명세 관리의 어려움, 내부 서비스 통신에서의 비효율성이 한계로 드러날 수 있었습니다.
이러한 한계를 보완하기 위해 gRPC가 등장하였습니다. gRPC는 HTTP/2와 Protocol Buffers를 기반으로 더 빠르고 효율적인 통신을 제공하며, .proto 파일을 통해 서비스 계약을 명확하게 정의할 수 있습니다.
Protocol Buffers
Protocol Buffers(Protobuf)는 구조화된 데이터를 효율적으로 직렬화하기 위한 형식입니다. gRPC에서 요청과 응답 데이터를 JSON 대신 Protobuf 형식으로 정의하고 전송합니다.
JSON은 사람이 읽기 쉽다는 장점이 있지만 텍스트 기반이라 상대적으로 크기가 커질 수 있습니다.반면 Protobuf는 더 가볍고 빠르게 처리할 수 있어 서비스 간 통신에서 효율적입니다.
즉, Protocol Buffers는 gRPC에서 데이터를 더 작고 빠르게 주고받기 위해 사용하는 데이터 직렬화 방식입니다.
syntax = "proto3";
service UserService {
rpc GetUser (UserRequest) returns (UserResponse);
}
message UserRequest {
int64 id = 1;
}
message UserResponse {
int64 id = 1;
string name = 2;
int32 age = 3;
}
gRPC와 REST의 차이
| 항목 | REST | gRPC |
| 통신 방식 | 자원 중심 | 메서드 호출 중심 |
| 데이터 형식 | 주로 JSON | Protocol Buffers |
| 전송 프로토콜 | 주로 HTTP/1.1 | HTTP/2 |
| 가독성 | 사람이 읽기 쉬움 | 사람이 바로 읽기 어려움 |
| 성능 | 상대적으로 무거울 수 있음 | 더 빠르고 효율적 |
| 주 사용 환경 | 외부 공개 API, 웹 서비스 | 내부 서비스 간 통신, 마이크로서비스 |
REST는 자원을 URI로 표현하고 HTTP 메서드로 행위를 구분하는 방식이라면, gRPC는 원격 서버의 메서드를 직접 호출하는 방식에 가깝습니다.
또한 REST는 JSON을 많이 사용하고, gRPC는 Protocol Buffers를 사용한다는 차이도 있습니다.
즉, REST는 범용성과 가독성에 강점이 있고, gRPC는 성능과 엄격한 인터페이스 정의에 강점이 있습니다.
gRPC는 언제 사용할까
gRPC는 특히 서비스 간 호출이 자주 발생하는 환경에서 유용합니다. 예를 들어 마이크로서비스 아키텍처에서는 하나의 요청을 처리하기 위해 여러 내부 서비스가 서로 통신하는 경우가 많은데, 이때 gRPC를 사용하면 더 빠르고 효율적인 통신이 가능합니다.
또한 요청과 응답 구조를 명확하게 정의해야 하거나, 성능이 중요한 환경, 스트리밍 기능이 필요한 경우에도 gRPC가 적합합니다.
반면 외부에 공개되는 API나 브라우저와 직접 통신해야 하는 경우에는 REST가 더 적합한 경우가 많습니다.
gRPC 장단점
장점
- HTTP/2와 Protobuf 기반으로 빠른 통신이 가능합니다.
- 요청/응답 구조를 명확하게 정의할 수 있다.
- 클라이언트와 서버 코드를 자동 생성할 수 있다.
- 스트리밍 통신을 지원한다.
단점
- JSON보다 사람이 바로 읽기 어렵다.
- 브라우저에서 직접 사용하기엔 제약이 있다.
- REST보다 디버깅이 직관적이지 않을 수 있다.
- 처음 접할 때 진입 장벽이 있을 수 있다.
gRPC의 간단한 예시
Java에서의 서버 구현 예시를 확인해봅시다.
public class UserServiceImpl extends UserServiceGrpc.UserServiceImplBase {
@Override
public void getUser(UserRequest request, StreamObserver<UserResponse> responseObserver) {
UserResponse response = UserResponse.newBuilder()
.setId(request.getId())
.setName("Kim")
.setAge(20)
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
gRPC 서버에서 GetUser 요청을 처리하는 예시입니다.
클라이언트가 UserRequest를 보내면, 서버는 request.getId()로 요청값을 확인하고 UserResponse를 생성한 뒤 responseObserver.onNext()로 응답을 전달합니다.
즉, Java에서는 서버가 원격 호출 메서드를 구현하는 형태로 gRPC를 사용합니다.
Java 클라이언트 호출 예시
ManagedChannel channel = ManagedChannelBuilder
.forAddress("localhost", 9090)
.usePlaintext()
.build();
UserServiceGrpc.UserServiceBlockingStub stub = UserServiceGrpc.newBlockingStub(channel);
UserRequest request = UserRequest.newBuilder()
.setId(1)
.build();
UserResponse response = stub.getUser(request);
System.out.println(response.getName());
channel.shutdown();
이 코드는 Java 클라이언트가 gRPC 서버의 GetUser 메서드를 호출하는 예시입니다.
- channel은 서버와 연결하기 위한 통신 채널입니다.
- stub는 원격 메서드를 호출하기 위한 객체입니다.
- stub.getUser(request)를 호출하면 로컬 메서드를 실행하듯 서버의 GetUser가 호출됩니다.
즉, Java에서는 stub 객체를 통해 원격 서버 메서드를 호출합니다.
여기까지 gRPC에 대해 학습해보았습니다. REST만 자주 사용해왔기 때문에 저 역시 gRPC 개념이 다소 생소했지만, 내부 서비스 간 통신이나 실시간 데이터 전달처럼 성능과 효율이 중요한 기능을 구현할 때 활용해보고 싶다는 생각이 들었습니다. 다음 시간에는 Swagger에 대해 알아보겠습니다.
'백엔드 공부' 카테고리의 다른 글
| 캐시(1) - 캐시와 CDN 캐시 (0) | 2026.04.27 |
|---|---|
| API(5) - 오픈 API 명세와 Swagger (0) | 2026.04.24 |
| API(3) - API의 다양한 인증 방식 (0) | 2026.04.22 |
| API(2) - API 데이터 형식 : JSON API (0) | 2026.04.21 |
| API(1) - API란 무엇인가 (1) | 2026.04.20 |