728x90
1. gRPC 개요 및 핵심 개념
gRPC는 Google에서 개발한 오픈소스 원격 프로시저 호출(RPC) 프레임워크입니다. HTTP/2와 Protocol Buffers(Protobuf)를 기반으로 하며, 마이크로서비스 아키텍처(MSA) 및 분산 시스템 환경에서 고성능·고효율 통신을 위해 설계되었습니다.
- 모든 환경에서 동작: 데이터센터, 클라우드, 엣지, 모바일 등 다양한 환경 지원
- 다국어 지원: Python, Java, Go 등 10여개 이상의 언어 지원
- 자동 코드 생성: .proto 파일만 있으면 서버/클라이언트 코드가 자동 생성됨
1.1. RPC란?
RPC(Remote Procedure Call)는 클라이언트가 네트워크를 통해 원격 서버의 함수를 마치 로컬 함수처럼 호출할 수 있게 하는 프로토콜입니다.
→ 개발자는 네트워크 통신의 복잡성을 신경쓰지 않고, 함수 호출에 집중할 수 있습니다.
1.2. gRPC의 주요 특징
- 고성능: Protobuf 이진 직렬화 + HTTP/2 멀티플렉싱으로 REST 대비 빠름
- 스트리밍 지원: 단항, 서버/클라이언트/양방향 스트리밍 등 4가지 패턴 제공
- 엄격한 타입 체크: 컴파일 타임 타입 검증
- 코드 자동 생성: proto 파일만 있으면 여러 언어의 코드를 자동 생성
- 보안 내장: TLS/SSL, mTLS 등 강력한 보안 지원
2. gRPC vs REST
구분 | gRPC | REST API |
설계 방식 | 서비스(함수) 지향 | 리소스(엔터티) 지향 |
통신 모델 | 단항, 서버/클라이언트/양방향 스트리밍 | 요청-응답(단방향) |
데이터 형식 | Protobuf(이진), JSON(옵션) | JSON(텍스트), XML, HTML 등 |
프로토콜 | HTTP/2 | HTTP 1.1 |
코드 생성 | proto → 자동 코드 생성 | 서드파티 도구 필요 |
결합도 | 긴밀(계약 기반, proto 공유 필수) | 느슨(동적 스펙) |
적합한 용도 | 고성능, 대용량, 실시간, 다국어 서비스 | 공개 API, 브라우저, 단순 데이터 |
REST는 느슨한 결합, gRPC는 강력한 타입·계약 기반의 긴밀한 결합이 특징입니다.
3. Python gRPC 환경 설정
3.1. 필수 패키지 설치
pip install grpcio grpcio-tools
- grpcio: Python gRPC 런타임
- grpcio-tools: Protobuf 컴파일러 및 코드 생성 플러그인
3.2. 서비스 정의 (.proto 파일)
예시: Greeter 서비스
syntax = "proto3";
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest { string name = 1; }
message HelloReply { string message = 1; }
3.3. 코드 생성
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. helloworld.proto
- helloworld_pb2.py: 메시지 클래스 정의
- helloworld_pb2_grpc.py: 클라이언트 스텁/서버 인터페이스
4. Python gRPC 서버/클라이언트 기본 예제
4.1. 서버 구현
import grpc
from concurrent import futures
import helloworld_pb2
import helloworld_pb2_grpc
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message=f"Hello, {request.name}!")
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
server.add_insecure_port('[::]:50051')
server.start()
server.wait_for_termination()
if __name__ == '__main__':
serve()
4.2. 클라이언트 구현
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
def run():
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__':
run()
5. gRPC 스트리밍
gRPC의 진짜 매력은 스트리밍입니다.
한 번 연결로 여러 메시지를 주고받을 수 있어, 실시간 채팅·알림·대용량 데이터 송수신에 최적입니다.
5.1. 4가지 스트리밍 패턴
gRPC는 아래 4가지 통신 패턴을 지원합니다.
패턴 | 설명 | 예시 활용 |
Unary | 1개 요청 → 1개 응답 | 로그인, 조회 등 |
Server Streaming | 1개 요청 → 여러 응답(스트림) | 실시간 피드, 대용량 데이터 다운로드 |
Client Streaming | 여러 요청(스트림) → 1개 응답 | 대용량 업로드, 센서 데이터 수집 |
Bidirectional | 여러 요청/응답을 양방향 스트림으로 동시 교환 | 실시간 채팅, 게임, 협업 도구 |
5.2. 양방향 스트리밍 예제
stream_example.proto
syntax = "proto3";
service StreamService {
rpc StreamData (stream StreamRequest) returns (stream StreamResponse);
}
message StreamRequest { string data = 1; }
message StreamResponse { string result = 1; }
서버
class StreamService(stream_example_pb2_grpc.StreamServiceServicer):
def StreamData(self, request_iterator, context):
for request in request_iterator:
yield stream_example_pb2.StreamResponse(result=f"Received: {request.data}")
클라이언트
def generate_requests():
for i in range(5):
yield stream_example_pb2.StreamRequest(data=f"Message {i}")
def run():
with grpc.insecure_channel('localhost:50051') as channel:
stub = stream_example_pb2_grpc.StreamServiceStub(channel)
responses = stub.StreamData(generate_requests())
for response in responses:
print(f"응답: {response.result}")
6. gRPC 에러 처리 및 보안
6.1. 에러/상태 코드
상태 코드 | 설명 |
CANCELLED | 작업이 클라이언트에 의해 취소됨 |
INVALID_ARGUMENT | 잘못된 인수 |
DEADLINE_EXCEEDED | 마감 시간 초과 |
NOT_FOUND | 리소스 없음 |
PERMISSION_DENIED | 권한 없음 |
INTERNAL | 내부 서버 에러 |
UNAVAILABLE | 서비스 불가 |
UNAUTHENTICATED | 인증 실패 |
서버에서 에러 반환 예시
def MyMethod(self, request, context):
if not request.valid:
context.set_code(grpc.StatusCode.INVALID_ARGUMENT)
context.set_details('입력값이 잘못되었습니다.')
return MyResponse()
클라이언트에서 에러 처리
try:
response = stub.MyMethod(MyRequest())
except grpc.RpcError as e:
status = e.code()
print(f"gRPC 에러: {status}, {e.details()}")
6.2. 보안 (TLS/SSL, mTLS)
- TLS/SSL: 서버 인증서 기반 암호화 통신
- mTLS: 서버와 클라이언트 모두 인증서로 신원 검증 (양방향 인증)
- Python 예시
# 서버
server_credentials = grpc.ssl_server_credentials([(private_key, certificate_chain)])
server.add_secure_port('[::]:50051', server_credentials)
# 클라이언트
credentials = grpc.ssl_channel_credentials(root_certificates=ca_cert)
channel = grpc.secure_channel('localhost:50051', credentials)
7. 마이크로서비스 아키텍처(MSA)에서 gRPC의 역할
- 고성능 통신: 서비스 간 빈번한 데이터 교환을 빠르고 효율적으로 처리
- 언어 중립성: Python, Java, Go 등 다양한 언어 조합 가능
- 강력한 타입 체크: 서비스 계약이 명확함 (컴파일 시점 검증)
- 스트리밍 지원: 실시간 데이터, 대용량 데이터 처리에 최적
- 코드 자동 생성: .proto 파일만 관리하면 모든 서비스가 일관된 인터페이스로 통신 가능
Tip:
중앙화된 proto 관리 시스템(예: 별도 git repo)에서 .proto 파일을 관리하고, 각 서비스에서 빌드 파이프라인으로 자동 배포하는 것이 실무적입니다.
8. gRPC 테스트 및 디버깅 도구
- Apidog: gRPC 스트리밍까지 지원하는 웹 기반 API 테스트/디버깅 도구
- 다양한 언어 지원, .proto 기반 문서 자동화
- 요청/응답 모니터링, 스트리밍 실시간 확인
- gRPCurl: 터미널에서 gRPC API 호출 및 테스트
- BloomRPC: GUI 기반 gRPC 클라이언트
'Python' 카테고리의 다른 글
[Python] 손글씨 숫자 이미지 분류 모델 만들기 (MNIST 데이터셋 활용) (1) | 2025.08.27 |
---|---|
[Python] PyTorch 텐서 차원 다루기 (0) | 2025.08.26 |
[Python] 음성 데이터 품질 검사(QC) 자동화 리포트 만들기 (0) | 2025.08.20 |
[Python] Pytorch에서 벡터 합치기 (임베딩 결합 방식) (0) | 2025.08.19 |
[Python] JSONL 포맷으로 음성 데이터셋 정리하기 (1) | 2025.08.18 |