gRPC란 구글에서 개발한 RPC(remote procedure call) 시스템이다.
gRPC는 데이터 전송을 위해서 HTTP/2를 사용하고, IDL(interface description language)로 Protocal Buffer를 사용한다. 또한 인증, 양방향 스트리밍, blocking, nonblocking 바인딩 등 다양한 기능을 제공한다.
분산 시스템에서, 하나의 프로그램이 실행하는 도중 다른 주소공간(다른 프로세스, 다른 컴퓨터..)의 프로시저(서브루틴)을 실행하는 것을 RPC라고 부른다.
RPC 는 request–response protocol로 동작한다. 원래 프로그램은 다른 주소공간으로 reqeust를 보내고, 이 요청을 받은 서버는 프로시저를 실행하여 그 결과를 다시 원래 프로그램으로 보낸다(response).
이러한 RPC의 구현체로
등 이 있다.
HTTTP/1.1의 단점 중 프로토콜의 성능에 초첨을 맞춰 개선한 전송 프로토콜이다. 기존의 HTTP/2는 다음과 같은 개선사항을 갖는다.
protocol buffers는 구글에서 공개한 cross-platform 포맷으로, IDL의 한 종류이다. 구조화된 데이터를 언어, 플랫폼에 중립적으로 serializing(데이터를 저장될 수 있는 형태로 변환하는 것)하는 방법을 제한다.
syntax = "proto3"; // proto3, proto2 중에 사용할 버전 명시
package proto_test; // package 이름 명시
service RpcService { // RPC service 이름 정의(CamelCase with an initial capital)
rpc 함수명 (입력Message) returns (출력Message);
}
message 입력Message {
string name = 1;
}
message 출력Message {
string code = 1;
string name = 2;
string symbol = 3;
}
IDL은 서로 같거나 다른 소프트웨어 컴포넌트들 사이의 데이터 구조와 인터페이스를 묘사하기 위한 명세 언어이다.
IDL은 어느 한 언어에 국한되지 않는 언어중립적인 방법으로 인터페이스를 표현함으로써, 같은 언어를 사용하지 않는 소프트웨어 컴포넌트 사이의 통신을 가능하게 한다.
gRPC는 gRPC 서버와, gRPC클라이언트(stub)로 구성된다.
gRPC 서버
service의 함수들이 서버의 언어로 정의되어 있어, stub에서 요청이 들어오면 이를 수행한다.
gRPC클라이언트(stub)
정의된 proto파일에 맞는 변환 함수를 가지고 있다. service에 있는 함수를 호출하려면, stub의 언어로 생성된 데이터를 serializing하여 gRPC서버로 전송하고, 그 결과값을 다시 역 serializing한다.
언어별로 gRPC compiler를 통해 .proto파일을 각 언어 맞는 파일로 변환할 수 있다. 우선 .proto 파일을 작성한 후, 공통된 .proto파일을 통해서 server와 client에서 각각 compile한다.
syntax = "proto3";
package helloworld;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
> protoc --proto_path=<.proto파일의 dir경로> \
--go_out=plugins=grpc:<정의한 package이름> \
.proto파일
> python -m grpc_tools.protoc \
--proto_path <.proto파일의 dir경로> \
--python_out=<출력 .py파일 경로> \
--grpc_python_out=<출력 .py파일 경로> \
<.proto파일경로>
가장 단순한 RPC이다. Cilent가 요청을 보내고, Server가 그 요청을 받으면 결과 값을 반환하는 구조이다.
Uray와 비슷하지만, Server가 응답으로 streaming message를 보낸다는 차이가 있다. 서버는 streaming message가 모두 전송될때, 서버의 status혹은 다른 meta data를 추가로 전송한다.
Uray와 비슷하지만, Cilent가 요청으로 streaming message를 보낸다는 차이가 있다. 서버는 streaming message가 모두 받으면 single response(필수x)를 보낸다.
Client가 특정 함수를 호출하여 Sercer가 client metadata, method name, deadline을 받으면 시작된다. Server와 Client가 서로 동시에 스트리밍 데이터를 주고 받을 수 있고, 이 두 스트림은 독립적이다.