gRPC란?
gRPC는 Google에서 개발한 고성능 원격 프로시저 호출(Remote Procedure Call, RPC) 프레임워크입니다. HTTP/2를 기반으로 동작하며, 다양한 언어를 지원하고, 효율적인 바이너리 직렬화(Protocol Buffers, Protobuf)를 사용하여 빠르고 안정적인 서비스 간 통신을 제공합니다. 기존의 REST API와 비교했을 때 더 적은 오버헤드와 높은 성능을 제공하며, 기존 RPC 시스템(예: Thrift, CORBA)보다 표준화된 인터페이스와 광범위한 언어 지원을 통해 활용성이 높습니다. gRPC는 마이크로서비스 아키텍처, 실시간 스트리밍 서비스, IoT 장치 간 통신 등에서 자주 사용됩니다.
🛠️ gRPC의 특징
✅ 1. HTTP/2 기반
- 멀티플렉싱 지원(하나의 연결에서 여러 요청 처리)
- 헤더 압축으로 네트워크 비용 절감
- 서버 푸시 기능 지원
✅ 2. Protocol Buffers (Protobuf) 사용
- JSON보다 빠르고 용량이 작음
- 정형화된 스키마로 안정적인 데이터 구조 유지
✅ 3. 다양한 언어 지원
- Go, Python, Java, C++, C#, JavaScript 등 여러 언어에서 사용 가능
✅ 4. 4가지 통신 방식 지원
Unary RPC: 클라이언트가 요청을 보내고, 서버가 응답을 반환하는 가장 기본적인 방식입니다.
- ✅ 장점: 간단하고 직관적이며, REST API와 유사하여 적용이 쉬움
- ❌ 단점: 요청-응답 패턴이므로 실시간 데이터 스트리밍에는 적합하지 않음
- ✏️ 예제:
response = stub.SayHello(greet_pb2.HelloRequest(name="Alice"))
Server Streaming RPC: 클라이언트가 하나의 요청을 보내면 서버가 여러 개의 응답을 스트리밍으로 보냅니다.
- ✅ 장점: 대량의 데이터를 순차적으로 처리 가능 (예: 실시간 로그 스트리밍)
- ❌ 단점: 클라이언트는 응답을 모두 받을 때까지 추가 요청을 보낼 수 없음
- ✏️ 예제:
responses = stub.GetLogs(greet_pb2.LogRequest()) for response in responses: print(response.message)
Client Streaming RPC: 클라이언트가 여러 개의 요청을 스트리밍 방식으로 보내고, 서버는 최종적으로 한 번 응답을 반환합니다.
- ✅ 장점: 대량의 요청을 하나의 응답으로 처리 가능 (예: 데이터 업로드)
- ❌ 단점: 서버가 클라이언트의 모든 데이터를 받을 때까지 응답하지 않음
- ✏️ 예제:
stream = stub.UploadData() for data in data_list: stream.send(data) response = stream.close_and_receive()
Bidirectional Streaming RPC: 클라이언트와 서버가 동시에 여러 개의 메시지를 스트리밍 방식으로 주고받을 수 있습니다.
- ✅ 장점: 양방향 실시간 통신이 가능하여 채팅, 금융 데이터 스트리밍 등에 유용
- ❌ 단점: 구현이 복잡하며 상태 관리가 필요함
- ✏️ 예제:
responses = stub.Chat(stream_of_messages()) for response in responses: print(response.message)
🏷️ gRPC 서버 및 클라이언트 예제 (Python)
gRPC를 사용한 간단한 서버와 클라이언트를 만들어보겠습니다.
📌 1. Protocol Buffers 정의 (greet.proto)
syntax = "proto3";
package greet;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
string name = 1;
}
message HelloResponse {
string message = 1;
}
이 파일은 gRPC 서비스의 인터페이스를 정의하는 역할을 합니다.
📌 2. Protobuf 컴파일
.proto
파일을 컴파일하여 Python 코드를 생성해야 합니다.
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. greet.proto
📌 3. gRPC 서버 구현 (server.py)
import grpc
from concurrent import futures
import greet_pb2
import greet_pb2_grpc
class GreeterServicer(greet_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
# 요청 로그 추가
print(f"Received request from: {request.name}")
# 인증 로직 (예제)
if request.name == "UnauthorizedUser":
context.set_code(grpc.StatusCode.UNAUTHENTICATED)
context.set_details("Unauthorized access")
return greet_pb2.HelloResponse()
# 응답 반환
return greet_pb2.HelloResponse(message=f"Hello, {request.name}!")
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
greet_pb2_grpc.add_GreeterServicer_to_server(GreeterServicer(), server)
server.add_insecure_port("[::]:50051")
server.start()
print("gRPC Server is running on port 50051...")
server.wait_for_termination()
if __name__ == "__main__":
serve()
✔ gRPC 서버 실행: python server.py
📌 4. gRPC 클라이언트 구현 (client.py)
import grpc
import greet_pb2
import greet_pb2_grpc
def run():
with grpc.insecure_channel("localhost:50051") as channel:
stub = greet_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(greet_pb2.HelloRequest(name="Alice"))
print("Server Response:", response.message)
if __name__ == "__main__":
run()
✔ gRPC 클라이언트 실행: python client.py
🚀 마무리
이제 gRPC를 사용하여 클라이언트와 서버가 효율적으로 데이터를 주고받을 수 있습니다. gRPC는 마이크로서비스 아키텍처에서 강력한 성능과 확장성을 제공하므로, 효율적인 통신이 필요한 프로젝트에서 적극 활용할 수 있습니다.
다음엔 어떤 gRPC 기능을 다뤄볼까? 😃
'프로그래밍 > 일반' 카테고리의 다른 글
Argo CD의 모든 것: 쿠버네티스를 위한 최고의 GitOps 도구 (0) | 2025.04.23 |
---|---|
다양한 해시 알고리즘의 장단점과 용도 (0) | 2025.03.07 |
gRPC: 현대적인 분산 시스템을 위한 강력한 RPC 프레임워크 (0) | 2025.02.20 |
k6: 강력하고 유연한 성능 테스트 도구 (0) | 2025.02.20 |