gRPC란?
gRPC는 고성능의 오픈 소스 RPC 프레임워크로, 마이크로서비스와 실시간 통신에 적합하다.
gRPC란 무엇인가요?
gRPC는 Google에서 개발한 고성능, 오픈 소스 RPC (Remote Procedure Call) 프레임워크입니다.
다양한 환경에서 실행될 수 있으며, 데이터 센터 내부 및 외부 서비스를 효율적으로 연결합니다. 또한, 분산 컴퓨팅의 마지막 단계에서 장치, 모바일 애플리케이션 및 브라우저를 백엔드 서비스에 연결하는 데에도 적용할 수 있습니다. gRPC는 2015년 Google에서 Stubby라는 내부 RPC 인프라를 개선하여 오픈소스로 공개한 것입니다. 현재는 마이크로서비스, API 게이트웨이, 실시간 통신 등 다양한 분야에서 사용되고 있습니다.
gRPC의 주요 특징
gRPC는 다음과 같은 주요 특징을 가지고 있습니다.
- HTTP/2 기반: gRPC는 HTTP/2를 전송 계층 프로토콜로 사용합니다. HTTP/2는 HTTP/1.1의 한계를 극복하고 다중화, 헤더 압축, 서버 푸시 등의 기능을 제공하여 네트워크 오버헤드를 줄이고 효율성을 향상시킵니다. 예를 들어, HTTP/2는 메시지를 프레임으로 분할하여 하나의 TCP 연결에서 여러 요청과 응답을 동시에 처리할 수 있도록 합니다. 또한 헤더 압축을 통해 헤더 크기를 줄여 데이터 전송량을 감소시킵니다.
- Protocol Buffers: gRPC는 Protocol Buffers (protobuf)를 인터페이스 정의 언어 (IDL) 및 메시지 교환 형식으로 사용합니다. Protobuf는 Google에서 개발한 언어 중립적이고 플랫폼 중립적인 IDL로, 데이터를 바이너리 형식으로 직렬화하여 효율적인 데이터 전송을 가능하게 합니다. Protobuf는 JSON이나 XML보다 더 작고 빠르며, 효율적인 데이터 직렬화를 통해 gRPC의 성능 향상에 기여합니다.
- IDL (Interface Definition Language): gRPC는 IDL을 사용하여 서비스 인터페이스와 메시지 구조를 정의합니다. IDL을 통해 클라이언트와 서버 간의 계약을 명확하게 정의하고, 다양한 프로그래밍 언어로 클라이언트 및 서버 코드를 생성할 수 있습니다. gRPC는 기본적으로 Protobuf를 IDL로 사용하지만, JSON과 같은 다른 데이터 형식을 사용할 수도 있습니다.
- 코드 생성: gRPC는 Protobuf 정의를 사용하여 다양한 언어로 클라이언트 및 서버 코드를 자동으로 생성합니다. 이를 통해 개발자는 코드 작성 시간을 단축하고, 여러 언어로 gRPC 서비스를 쉽게 구현할 수 있습니다.
- 양방향 스트리밍: gRPC는 HTTP/2를 통해 양방향 스트리밍을 지원합니다. 클라이언트와 서버는 비동기적으로 여러 메시지를 주고받을 수 있으며, 실시간 통신을 가능하게 합니다.
- 인터셉터: gRPC는 인터셉터를 지원합니다. 인터셉터는 로깅, 인증, 모니터링 등과 같은 gRPC 기능을 확장하는 데 사용할 수 있는 강력한 메커니즘입니다.
gRPC 작동 방식
gRPC는 클라이언트와 서버 간에 메시지를 교환하여 작동합니다. 클라이언트는 서버에서 제공하는 서비스의 메서드를 호출하고, 서버는 해당 메서드를 실행하고 결과를 클라이언트에게 반환합니다. gRPC는 HTTP/2를 사용하여 메시지를 전송하며, Protobuf를 사용하여 메시지를 직렬화합니다. gRPC는 채널을 사용하여 클라이언트와 서버 간의 연결을 관리합니다. 채널은 연결된 상태와 유휴 상태를 포함한 상태를 가지며, 채널을 닫는 방법은 언어에 따라 다릅니다.
gRPC는 다음과 같은 4가지 유형의 서비스 메서드를 지원합니다.
- Unary: 클라이언트가 단일 요청을 보내고 서버가 단일 응답을 반환하는 가장 일반적인 유형입니다. 이는 일반적인 함수 호출과 유사합니다. 예를 들어, 클라이언트가 사용자 정보를 요청하면 서버는 해당 사용자 정보를 응답으로 반환합니다.
- Server streaming: 클라이언트가 단일 요청을 보내고 서버가 여러 개의 응답을 스트림 형태로 반환하는 유형입니다. 클라이언트는 서버에서 더 이상 메시지가 없을 때까지 반환된 스트림에서 메시지를 읽습니다. gRPC는 개별 RPC 호출 내에서 메시지 순서를 보장합니다. 예를 들어, 클라이언트가 특정 기준에 맞는 여러 책을 요청하면 서버는 찾은 책들을 순차적으로 스트리밍하여 클라이언트에 전송합니다.
- Client streaming: 클라이언트가 여러 개의 요청을 스트림 형태로 보내고 서버가 단일 응답을 반환하는 유형입니다. 클라이언트는 제공된 스트림을 사용하여 일련의 메시지를 작성하고 서버에 보냅니다. 클라이언트가 메시지 작성을 완료하면 서버가 메시지를 모두 읽고 응답을 반환할 때까지 기다립니다. gRPC는 개별 RPC 호출 내에서 메시지 순서를 보장합니다. 예를 들어, 차량 공유 앱에서 운전자가 운행을 시작하면 클라이언트 애플리케이션은 실시간 위치 데이터를 서버에 스트리밍합니다. 운행이 종료되면 서버는 이동 거리와 요금을 요약하여 클라이언트에 응답합니다.
- Bidirectional streaming: 클라이언트와 서버가 모두 스트림 형태로 메시지를 주고받는 유형입니다. 두 스트림은 독립적으로 작동하므로 클라이언트와 서버는 원하는 순서대로 메시지를 읽고 쓸 수 있습니다. 예를 들어, 서버는 모든 클라이언트 메시지를 수신할 때까지 기다렸다가 응답을 작성하거나, 메시지를 읽은 다음 메시지를 쓰거나, 읽기와 쓰기의 다른 조합을 사용할 수 있습니다. 각 스트림의 메시지 순서는 유지됩니다
gRPC의 장점
gRPC는 다음과 같은 장점을 제공합니다.
- 성능: Protobuf를 사용한 바이너리 직렬화와 HTTP/2의 다중화 및 헤더 압축 기능을 통해 gRPC는 REST API보다 높은 성능을 제공합니다. 특히 대규모 데이터를 처리하거나 실시간 통신이 필요한 경우 gRPC는 매우 효율적인 선택입니다. 벤치마크 테스트 결과에 따르면, gRPC는 REST API보다 최대 10배 빠른 성능을 보여줍니다. 예를 들어, 500개의 클라이언트 스레드와
count = 100
인 페이로드를 사용한 테스트에서 REST API의 응답 시간은 gRPC 및 HTTP/protobuf보다 약 5배 느렸습니다. Akka gRPC의 경우, 최적화를 통해 처리량이 1231% 증가하고 평균 지연 시간이 93% 감소했습니다. - 효율성: Protobuf는 JSON이나 XML보다 더 작고 효율적인 메시지 형식을 제공합니다. 이는 네트워크 대역폭 사용량을 줄이고 데이터 전송 속도를 높여줍니다.
- 강력한 타이핑: Protobuf는 IDL을 통해 서비스 인터페이스와 메시지 구조를 명확하게 정의합니다. 이는 타입 안전성을 보장하고 API 문서화를 용이하게 합니다
- 사용성: gRPC는 다양한 프로그래밍 언어를 지원하며, 코드 생성 기능을 통해 개발자가 직접 코드를 작성해야 하는 부담을 줄여줍니다.
- 보안: gRPC는 TLS/SSL을 사용하여 전송 계층 보안을 지원합니다. 또한 JWT, OAuth 등 다양한 인증 메커니즘을 지원하여 API에 대한 액세스를 제어할 수 있습니다.
- 데드라인/타임아웃: gRPC는 클라이언트가 RPC 완료까지 대기할 시간을 지정할 수 있도록 합니다. 데드라인이 초과되면
DEADLINE_EXCEEDED
오류와 함께 RPC가 종료됩니다. 서버 측에서는 특정 RPC가 시간 초과되었는지 또는 RPC를 완료하는 데 남은 시간을 확인할 수 있습니다.
gRPC의 단점
gRPC는 다음과 같은 단점을 가지고 있습니다.
- 브라우저 지원 제한: gRPC는 HTTP/2를 기반으로 하기 때문에 모든 웹 브라우저에서 직접 지원되지 않습니다. gRPC-Web과 같은 해결 방법이 있지만, 프록시 설정 및 호환성 문제를 해결해야 합니다
- 디버깅 및 로깅: Protobuf의 바이너리 형식은 사람이 읽기 어렵기 때문에 gRPC 애플리케이션을 디버깅하고 로깅하는 것이 REST API보다 어려울 수 있습니다.
- 학습 곡선: REST API에 익숙한 개발자는 gRPC를 배우는 데 시간이 필요할 수 있습니다. Protobuf 및 HTTP/2에 대한 이해가 필요하며, gRPC의 개념과 작동 방식을 숙지해야 합니다.
gRPC 사용 사례
gRPC는 다음과 같은 다양한 사용 사례에 적합합니다.
- 마이크로서비스: gRPC는 마이크로서비스 아키텍처에서 서비스 간 통신에 이상적입니다. 낮은 지연 시간과 높은 처리량을 제공하며, 다양한 언어로 작성된 서비스를 효율적으로 연결할 수 있습니다.
- API 게이트웨이: gRPC는 API 게이트웨이에서 백엔드 서비스와 통신하는 데 사용될 수 있습니다. gRPC의 효율성과 성능은 API 게이트웨이의 응답 시간을 단축하고 처리량을 높이는 데 도움이 됩니다.
- 실시간 통신: gRPC는 양방향 스트리밍을 지원하여 실시간 통신 애플리케이션에 적합합니다. 채팅 애플리케이션, 게임, 실시간 데이터 스트리밍 등에 사용될 수 있습니다.
- IoT: gRPC는 IoT 장치와 백엔드 서비스 간의 통신에 효율적인 솔루션입니다. 낮은 대역폭 환경에서도 효율적으로 작동하며, 다양한 장치 및 플랫폼을 지원합니다.
- 실제 사례: Dropbox는 서비스 지향 아키텍처의 핵심 RPC 프레임워크인 "Courier"의 다음 버전을 gRPC 기반으로 마이그레이션한다고 발표했습니다. Lyft는 gRPC 클라이언트 스트리밍을 사용하여 운전자의 실시간 위치를 사용자와 공유합니다.
gRPC와 REST API 비교
gRPC와 REST API는 모두 클라이언트-서버 통신을 위한 아키텍처 스타일이지만, 몇 가지 중요한 차이점이 있습니다

gRPC는 성능, 효율성, 스트리밍 기능 측면에서 REST API보다 우수하지만, 브라우저 지원 및 디버깅 측면에서는 제한적입니다. 따라서 애플리케이션의 요구 사항에 따라 적합한 아키텍처 스타일을 선택해야 합니다. gRPC는 대규모 마이크로서비스 연결, 실시간 통신, 저전력 및 저대역폭 시스템, 다국어 환경에 적합합니다. 반면 REST API는 사람이 읽기 쉽고 웹 브라우저에서 폭넓게 지원되므로, 간단한 데이터 소스 및 범용적인 API에 적합합니다.
gRPC 보안
gRPC는 API 보안을 위해 다음과 같은 기능을 제공합니다.
- TLS/SSL: gRPC는 TLS/SSL을 사용하여 클라이언트와 서버 간에 교환되는 데이터를 암호화합니다. 이는 전송 중 데이터의 기밀성을 보장하고 도청 및 데이터 변조를 방지합니다.
- 인증: gRPC는 JWT, OAuth, x.509 인증서와 같은 다양한 인증 메커니즘을 지원합니다. 이를 통해 클라이언트와 서버의 신원을 확인하고 권한 없는 액세스를 방지할 수 있습니다.
- 액세스 제어: gRPC는 특정 리소스 또는 기능에 대한 클라이언트 액세스를 제한하는 세분화된 액세스 제어 메커니즘을 제공합니다. 개발자는 역할 기반 액세스 제어 (RBAC) 또는 기타 권한 부여 모델을 구현하여 권한을 정의하고 액세스 정책을 적용할 수 있습니다.
gRPC 보안을 위한 몇 가지 추가적인 모범 사례는 다음과 같습니다.
- OAuth2를 통한 토큰 기반 인증: OAuth2는 안전한 토큰 기반 인증 및 권한 부여를 제공하는 널리 사용되는 프로토콜입니다. gRPC 서버에서 검증되는 액세스 토큰을 발급하여 권한 있는 서비스 또는 클라이언트만 API에 액세스할 수 있도록 합니다.
- JWT (JSON Web Token)를 사용한 클레임 기반 인증: JWT는 gRPC에 대한 OAuth2의 이상적인 보완책입니다. 클레임 기반 인증을 통해 서비스는 토큰을 사용하여 사용자 ID 및 역할을 확인할 수 있습니다. JWT는 컴팩트하고 자체 포함된 토큰이므로 분산 시스템에 효율적입니다.
- 상호 TLS (mTLS): 상호 TLS에서 클라이언트와 서버는 모두 인증서를 사용하여 서로 인증합니다. 이렇게 하면 신뢰할 수 있는 클라이언트만 서버와 통신할 수 있고 그 반대의 경우도 마찬가지입니다.
- 인증서 고정: 클라이언트 애플리케이션에서 서버의 인증서를 고정하여 서버의 특정 인증서만 신뢰하도록 하여 MITM (Man-in-the-Middle) 공격을 방지합니다.
- 정기적인 보안 감사 및 침투 테스트: 정기적인 보안 감사 및 침투 테스트를 통해 공격에 사용되기 전에 인증 메커니즘의 취약성을 식별하고 수정할 수 있습니다.
gRPC 성능
gRPC는 Protobuf를 사용한 바이너리 직렬화와 HTTP/2의 다중화 및 헤더 압축 기능을 통해 REST API보다 높은 성능을 제공합니다. 벤치마크 테스트 결과에 따르면, gRPC는 REST API보다 최대 10배 빠른 성능을 보여줍니다.
gRPC 성능을 측정한 몇 가지 벤치마크 테스트 결과는 다음과 같습니다.
- 페이로드 크기 비교: 페이로드 크기가 증가함에 따라 REST API의 성능은 크게 저하되는 반면, gRPC는 훨씬 더 높은 처리량을 유지합니다.
- 클라이언트 부하 비교: 클라이언트 부하가 증가함에 따라 gRPC는 HTTP/protobuf보다 약 15%에서 40% 더 높은 처리량을 제공합니다.
- 응답 시간 비교: 500개의 클라이언트 스레드와
count = 100
인 페이로드를 사용한 테스트에서 REST API의 응답 시간은 gRPC 및 HTTP/protobuf보다 약 5배 느렸습니다.
gRPC를 지원하는 프로그래밍 언어 및 프레임워크
gRPC는 다음과 같은 다양한 프로그래밍 언어를 지원합니다.
- Go
- C++
- Java
- Python
- Ruby
- Node.js
- C#
- Objective-C
- PHP
- Dart
또한, gRPC는 다양한 프레임워크와 통합될 수 있습니다. 예를 들어, Spring Boot 애플리케이션에서 gRPC를 사용할 수 있습니다.
gRPC를 사용하는 방법 (간단한 예제 코드 포함)
gRPC를 사용하려면 먼저 Protobuf를 사용하여 서비스 정의 및 메시지 형식을 정의해야 합니다. 그런 다음 protoc 컴파일러를 사용하여 .proto 파일에서 클라이언트 및 서버 코드를 생성합니다. 마지막으로 생성된 코드를 사용하여 서버를 구현하고 클라이언트에서 서버의 메서드를 호출합니다.
다음은 Python으로 작성된 간단한 gRPC 서버 예제입니다.
Python
from concurrent import futures
import logging
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
def serve():
port = '50051'
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
server.add_insecure_port('[::]:' + port)
server.start()
print("Server started, listening on " + port)
server.wait_for_termination()
if __name__ == '__main__':
logging.basicConfig()
serve()
다음은 Python으로 작성된 간단한 gRPC 클라이언트 예제입니다.
Python
import logging
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
def run():
# NOTE(gRPC Python Team): .close() is possible on a channel and should be
# used in circumstances in which the with statement does not fit the needs
# of the code.
with grpc.insecure_channel('localhost:50051') as channel:
stub = helloworld_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
print("Greeter client received: " + response.message)
if __name__ == '__main__':
logging.basicConfig()
run()
gRPC 관련 추가 정보
- 참고 자료: gRPC 공식 웹사이트 (https://grpc.io/)에서에서) gRPC에 대한 자세한 정보를 찾아볼 수 있습니다.
- 커뮤니티: gRPC 커뮤니티 포럼 (https://groups.google.com/g/grpc-io)에서에서) 다른 개발자들과 gRPC에 대한 질문과 답변을 주고받을 수 있습니다.
결론
gRPC는 고성능, 오픈 소스 RPC 프레임워크로, 마이크로서비스, API 게이트웨이, 실시간 통신 등 다양한 분야에서 사용됩니다. HTTP/2, Protobuf, IDL, 코드 생성, 양방향 스트리밍 등의 기능을 통해 효율적이고 안전한 통신을 가능하게 합니다. gRPC는 REST API보다 높은 성능을 제공하지만, 브라우저 지원 및 디버깅 측면에서는 제한적입니다. 따라서 애플리케이션의 요구 사항에 따라 적합한 아키텍처 스타일을 선택해야 합니다. gRPC는 마이크로서비스 아키텍처의 발전과 함께 점점 더 많은 관심을 받고 있으며, Dropbox와 Lyft와 같은 회사에서 실제 서비스에 gRPC를 적용하는 사례가 늘어나고 있습니다. gRPC의 성능과 효율성은 분산 시스템의 미래를 위한 핵심 기술로 자리매김할 가능성이 높습니다.