개발자를 위한 gRPC 기본 개념
안녕하세요. 오늘도 개발 중인 stark입니다!
최근 마이크로서비스 아키텍처(MSA)가 널리 도입되면서, 서비스 간 통신 방식에 대한 고민이 깊어지고 있습니다. 그중에서도 Google이 개발한 gRPC는 기존 REST API의 한계를 뛰어넘는 새로운 대안으로 주목받고 있습니다.
저 또한 MSA 프로젝트를 하면서 FeignClient의 대안을 알아보던 중 gRPC에 대해 알게 되었고 도입까지 해보게 되었습니다. 그러나 gRPC를 사용만 했지 무엇인지에 대해서는 이론적으로 잘 알지 못하고 있다는 것을 깨달았습니다. 그래서 이번 포스팅에서는 gRPC에 대한 경험이 아닌 이론을 정리해 보았습니다. 이번 포스팅을 통해 gRPC가 어떤 특징을 가졌는지 그리고 기존의 REST API와 비교했을 때 어떤 차별점이 있는지에 대해 알아봅시다.
어떤 글이 있든 제일 좋은 글은 공식 문서입니다. 하단의 링크에 들어가셔서 읽어보시는 것을 추천합니다!
gRPC의 탄생 배경
Google은 대규모 서비스 간 통신에서 높은 성능과 효율성을 요구했습니다. 기존의 REST API는 간단하고 범용적인 통신 방식이지만, 서비스 간 통신에서 네트워크 오버헤드와 성능 저하가 문제였습니다. 또한, REST API의 단점 중 하나는 텍스트 기반의 JSON 형식을 사용하기 때문에 데이터 크기가 커지고, 직렬화 및 역직렬화 과정에서 추가적인 비용이 발생한다는 점입니다.
이러한 문제들을 해결하기 위해 Google은 gRPC를 개발했습니다. gRPC는 HTTP/2의 멀티플렉싱 기능을 통해 네트워크 지연을 최소화하고, Protobuf를 사용해 전송 데이터의 크기를 줄였습니다. 이로 인해 대규모 마이크로서비스 간 통신에서 특히 유리하게 사용할 수 있게 되었습니다.
아래의 링크를 통해 gRPC의 등장 배경과 설계 원칙을 확인해 봅시다.
gRPC의 특징
gRPC는 HTTP/2를 기반으로 하여 빠르고 효율적인 데이터 전송을 지원하며, Protobuf(Protocol Buffers)라는 직렬화 형식을 사용해 메시지를 이진 데이터로 압축합니다. 이는 JSON을 사용하는 REST API에 비해 데이터 크기가 작고, 전송 속도가 빠르다는 큰 장점을 지닙니다. 이러한 효율성 덕분에 마이크로서비스, 모바일, IoT 등 저성능 환경에서도 적합하게 사용할 수 있습니다.
HTTP/2와 Protobuf의 장점은 다음과 같습니다.
- HTTP/2 기반 멀티플렉싱
- HTTP/2는 멀티플렉싱을 지원하여 여러 요청을 하나의 연결에서 동시에 처리할 수 있습니다. 이를 통해 네트워크 대역폭을 최적화하고 지연 시간을 줄일 수 있습니다.
- HTTP/2는 멀티플렉싱을 지원하여 여러 요청을 하나의 연결에서 동시에 처리할 수 있습니다. 이를 통해 네트워크 대역폭을 최적화하고 지연 시간을 줄일 수 있습니다.
- Protobuf 직렬화
- Protobuf는 데이터를 이진 형식으로 직렬화하여 전송합니다. 이는 JSON보다 크기가 작아 전송 속도가 빠르고, 파싱 과정에서도 성능 이점을 제공합니다.
- Protobuf는 데이터를 이진 형식으로 직렬화하여 전송합니다. 이는 JSON보다 크기가 작아 전송 속도가 빠르고, 파싱 과정에서도 성능 이점을 제공합니다.
- 양방향 통신 지원
- HTTP/2 기반의 양방향 스트리밍을 지원하므로, 서버와 클라이언트 간에 실시간으로 데이터를 주고받을 수 있습니다. 이는 게임 서버, 채팅 서비스 등 실시간 통신이 중요한 경우 특히 유용합니다.
- HTTP/2 기반의 양방향 스트리밍을 지원하므로, 서버와 클라이언트 간에 실시간으로 데이터를 주고받을 수 있습니다. 이는 게임 서버, 채팅 서비스 등 실시간 통신이 중요한 경우 특히 유용합니다.
아래의 링크를 통해 Protobuf에 대해 자세히 알아봅시다.
gRPC에는 아래의 추가적인 특징도 존재합니다.
- 로드 밸런싱 및 장애 복구
- gRPC는 클라이언트 측 로드 밸런싱을 지원하여 분산 환경에서의 확장성과 신뢰성을 높입니다. 또한, 장애가 발생한 경우 재시도 메커니즘을 통해 통신의 신뢰성을 보장할 수 있습니다.
- gRPC는 클라이언트 측 로드 밸런싱을 지원하여 분산 환경에서의 확장성과 신뢰성을 높입니다. 또한, 장애가 발생한 경우 재시도 메커니즘을 통해 통신의 신뢰성을 보장할 수 있습니다.
- 다양한 서비스 호출 방식
- gRPC는 여러 가지 호출 방식을 제공합니다. 예를 들어, 단일 요청-응답, 서버 스트리밍, 클라이언트 스트리밍, 양방향 스트리밍 등 다양한 통신 패턴을 지원하여, 상황에 맞는 최적의 통신 방법을 사용할 수 있습니다.
- gRPC는 여러 가지 호출 방식을 제공합니다. 예를 들어, 단일 요청-응답, 서버 스트리밍, 클라이언트 스트리밍, 양방향 스트리밍 등 다양한 통신 패턴을 지원하여, 상황에 맞는 최적의 통신 방법을 사용할 수 있습니다.
양방향 스트리밍을 지원하는 HTTP/2의 장점에 대한 설명도 확인해 봅시다.
스프링 부트에서 gRPC의 적용
스프링 부트에서도 gRPC를 활용해 마이크로서비스 간 통신을 쉽게 구성할 수 있습니다. 이를 위해 grpc-spring-boot-starter와 같은 라이브러리를 사용할 수 있습니다. 이 라이브러리를 통해 스프링 애플리케이션에서 gRPC 서버와 클라이언트를 간편하게 설정할 수 있으며, 이를 통해 마이크로서비스 간 통신을 더 빠르고 효율적으로 구성할 수 있습니다.
아래의 포스팅은 제가 springBoot에 gRPC를 적용시켜서 데모 프로젝트를 공유한 내용입니다.
스프링 부트에서 gRPC를 사용하는 주요 장점은 다음과 같습니다.
- 낮은 네트워크 오버헤드: HTTP/2와 Protobuf 덕분에 네트워크 오버헤드가 줄어들고, 데이터 전송이 빠릅니다.
- 양방향 스트리밍 지원: REST API와 달리 gRPC는 클라이언트와 서버 간의 실시간 데이터 스트리밍을 지원하여, 양방향 통신이 가능합니다.
- 안전한 통신: gRPC는 기본적으로 TLS(전송 계층 보안)를 사용하여 안전한 데이터 전송을 보장합니다. 이는 민감한 데이터를 주고받는 환경에서 특히 유리합니다.
마이크로서비스 아키텍처(MSA)에서 gRPC의 강점
마이크로서비스 아키텍처(MSA)에서는 각 서비스가 독립적으로 운영되며, 서로 통신을 통해 데이터를 주고받아야 합니다. 이때 REST API는 단순하고 익숙하지만 몇 가지 단점이 있습니다.
- 높은 네트워크 대역폭 소모: JSON 형식을 사용하므로 데이터 크기가 크고, 파싱에 오버헤드가 발생합니다.
- 응답 시간문제: HTTP/1.1 기반의 REST는 각 요청마다 새로운 연결을 생성해야 하므로 네트워크 지연이 발생할 수 있습니다.
반면에 gRPC는 다음과 같은 방법으로 이러한 문제를 해결합니다.
- HTTP/2 기반 멀티플렉싱을 통해 여러 요청을 동시에 처리해 네트워크 지연을 줄이고 대역폭을 효율적으로 사용합니다.
- Protobuf 직렬화를 통해 JSON보다 작고 빠른 데이터 전송이 가능하여, 전송 효율이 높습니다.
- 양방향 스트리밍을 지원하여, 서버와 클라이언트 간 실시간 통신이 가능합니다.
이러한 이유로, MSA 환경에서 gRPC는 Feign이나 WebClient에 비해 성능적인 이점을 제공합니다. Feign은 REST 기반으로 HTTP/1.1의 한계를 가지고 있고, WebClient는 비동기 처리가 가능하지만 여전히 JSON 형식의 오버헤드가 존재합니다.
또한, gRPC의 IDL(Interface Definition Language)을 사용해 서비스 인터페이스를 정의하고, 다양한 언어로 클라이언트 및 서버 코드를 생성할 수 있어 다언어로 구성된 마이크로서비스 환경에서 매우 유리합니다.
좀 더 이해하기 쉽도록 Rest와 gRPC를 비교표를 만들어 봤습니다.
항목 | REST | gRPC |
통신 프로토콜 | HTTP/1.1 | HTTP/2 |
데이터 포맷 | JSON (텍스트 기반) | Protobuf (이진 형식) |
성능 및 효율성 | 상대적으로 느림 (텍스트 파싱 필요) | 빠름 (이진 직렬화 및 역직렬화) |
스트리밍 지원 | 제한적 (서버 센트 이벤트 등 추가 구현 필요) | 클라이언트 및 서버 양방향 스트리밍 지원 |
브라우저 지원 | 모든 브라우저에서 직접 사용 가능 | 추가 라이브러리(gRPC-Web) 필요 |
언어 지원 | 언어에 구애받지 않음 | 다양한 언어에서 Protobuf 컴파일러 지원 |
스키마 정의 | 일반적으로 명시적 스키마 없음 | Protobuf를 통한 명확한 인터페이스 정의 |
보안 | HTTPS를 통한 암호화 | 기본적으로 TLS 사용 |
로드 밸런싱 | 서버 측 로드 밸런싱 주로 사용 | 클라이언트 측 로드 밸런싱 지원 |
주요 활용 분야 | 웹 애플리케이션, 공개 API | 마이크로서비스 간 통신, 고성능 시스템 |
Rest와 gRPC의 차이점을 설명하는 하단의 글을 읽어보는 것도 큰 도움이 될 것입니다.
gRPC의 장점과 단점
"There is no silver bullet" : 은탄환은 없다. (프레데릭 브룩스)
"복잡한 문제를 해결할 만능의 해결책이나 단순한 방법은 없다"는 의미입니다.
즉, gRPC는 성능과 효율성 면에서 많은 장점이 있지만, 당연히 단점도 존재합니다.
장점은 다음과 같습니다.
- 높은 성능: Protobuf를 통한 이진 직렬화 덕분에 데이터 크기가 작아 빠른 전송이 가능합니다.
- HTTP/2 기반 멀티플렉싱: 하나의 연결에서 여러 요청을 동시에 처리할 수 있어, 처리 속도가 향상됩니다.
- 양방향 스트리밍 지원: 실시간 데이터 교환이 필요한 경우 특히 유리합니다.
- 다양한 언어 지원: 다양한 프로그래밍 언어에서 쉽게 사용할 수 있어 다언어 환경에 적합합니다.
- 자동 코드 생성: Protobuf를 사용하여 서비스 인터페이스에 대한 클라이언트와 서버 코드를 자동으로 생성할 수 있어 개발 생산성이 높습니다.
- 보안성: 기본적으로 TLS 암호화를 사용해 데이터를 안전하게 보호합니다.
단점은 다음과 같습니다.
- 브라우저 호환성 부족: 대부분의 브라우저가 HTTP/1.1을 사용하므로, gRPC를 직접 사용하기 어렵습니다. 이를 해결하기 위해 gRPC-Web 같은 추가적인 컴포넌트가 필요합니다.
- 러닝 커브: REST API에 비해 설정과 Protobuf 직렬화 도구에 대한 학습이 필요해 초기 도입이 어렵습니다.
- 디버깅의 어려움: JSON과 같은 텍스트 기반이 아니라 이진 데이터 형식을 사용하기 때문에 디버깅이 쉽지 않습니다. 또한, 이진 데이터를 사람이 읽기 위해서는 Protobuf를 사용해 디코딩해야 하므로 디버깅 도구나 로그 분석이 더 복잡합니다.
마무리하며
이번 포스팅에서는 gRPC에 대해서 알아봤습니다.
사실 이 글만으로 gRPC를 이론적으로 배웠다고 하기에는 내용이 너무 부실합니다. 예를 들면 HTTP1.1과 HTTP2의 차이점이나 Protobuf의 사용법이나 TLS암호화가 무엇인지나 양방향 스트리밍이 무엇인지나 이렇게 gRPC를 이해하기 위해 알아봐야 할 것은 끝이 없습니다. 즉, 부채꼴 효과처럼 gRPC하나를 알기 위해서는 이 많은 것들을 공부해야 한다는 것입니다.
사실 저도 좀 더 확실하게 모든 정보를 공부해서 정리할까 고민했지만 그렇게 하면 오히려 이 글의 목적과 가독성을 해칠 수 있겠다는 생각이 들어 다른 정보에 대해서는 정리하지 않았습니다. 그래서 내용이 조금은 부실하고 이해하기 힘들게 느껴질 수도 있을 것입니다.
그래도 제가 바라는 것은 이번 포스팅을 통해 gRPC가 이런 거구나? 이 정도의 도움은 되었으면 합니다.
긴 글 읽어주신 독자분들께 감사의 인사를 드리며 저는 출근 준비하러 가보겠습니다!