gRPC 정리
- gRPC는 구글에서 개발한 RPC(RPC, Remote Procedure Call) 시스템이며 모든 환경에서 실행할 수 있는 오픈 소스 고성능 RPC 프레임워크이다.
- HTTP/2기반, 다양한 언어 Java, C ++, Python, Java Lite, Ruby, JavaScript, Objective-C 및 C#에서 사용이 가능하며 스텁, 프로토콜버퍼 등의 특징이 있으며 서비스들을 효율적으로 연결할 수 있는 강점을 가진다.
RPC란 무엇이인가?
- RPC(Remote Procedure Call)는 프로세스 간 통신 (IPC)의 한 형태로 떨어져 있거나 분산되어 있는 컴퓨터간의 통신을 위한 기술이다.
클라이언트가 스텁을 거처 RPC의 런타임을 거처 다시 런타임, 스텁, 서버로 전달되는 과정이 들어가있는 것이 RPC의 매커니즘이다.
스텁 [ Stub ] 이란?
- 스텁은 RPC의 핵심 개념으로 매개변수 [ parameter ] 객체를 메세지 [ Message ] 로 변환 [ Marshaling ] , 역변환 [ Unmarshaling ] 하는 레이어로, 클라이언트 스텁, 서버 스텁으로 나뉜다.
- 클라이언트 스텁 [ Main ] : 함수 호출에 사용된 파라미터의 변환 및 함수 실행 후 서버에서 전달된 결과의 변환을 담당한다.
- 서버 스텁 [ feature-api ]: 클라이언트가 전달한 매개 변수의 역변환 및 함수 실행 결과 반환을 담당한다.
위 그림처럼 스텁을 이용하여 서버와 클라이언트간의 언어가 달라도 요청과 응답을 구현할 수 있다.
프로토콜 버퍼 [ protocol buffer ]
- gRPC는 IDL [ interface Definition Language ] 로 프로토콜 버퍼를 사용한다.
- 프로토콜 버퍼는 구조화된 데이터를 직렬화하기 위한 구글의 언어 중립적, 플랫폼 중립적, 확장 가능한 메커니즘을 말한다.
- 보통 XML 이나 JSON을 생각할 수 있지만 더 작고 빠르다.
- 프로토콜 버퍼를 통해 데이터를 주고 받을 수 있기 때문에 어떤 언어나 플랫폼에서도 통신 프로토콜 등에 쉽게 적용할 수 있다.
장점
- gRPC는 대부분의 아키텍쳐에 사용할 수 있지만, MSA에 가장 적합한 기술로, 많은 서비스 간의 API 호출로 인한 성능 저하를 개선하며 보안, API 게이트웨이, 로깅등을 개발하기 쉽다.
- 높은 생산성을 가지고, 프로토콜 버퍼의 IDL 만 정의하면 서비스와 메세지에 대한 소스코드가 자동으로 생성되고 데이터를 주고 받을 수 있다.
- gRPC는 HTTP/2 기반으로 통신하며 이 때문에 양방향 스트리밍이 가능하다.
- gRPC는 HTTP/2 레이어 위에서 프로토콜 버퍼를 사용하여 ‘직렬화된 바이트 스트림’으로 통신하여 JSON 기반의 통신보다 더 가볍고 통신속도가 빠르다.
- 런타임 환경과 개발환경 구축이 쉽다.
- 다양한 언어를 기반으로 만들 수 있다.
- 유지보수가 쉽다.
단점
- rest api 와 다르게 메세지가 바이너리로 전달되기 때문에 테스트가 어렵다.
- 메세지 구조가 많이 변할 경우 안정성 확보가 어렵다.
- 개발 프로세스의 복잡도가 증가할 수 있다.
- 브라우저와 서버간의 gRPC 통신이 지원되지 않는다.
- 브라우저에서 JSON으로 서버에 요청하면 서버는 grpc-gateway를 통해 protobuf 형식으로 데이터 변환 후 사용
- 사람이 읽을 수 없는 데이터 형식이기 때문에 네트워크 단에서 데이터를 보고 싶으면 추가적인 작업이 필요하다.
프로토파일 작성법
- Proto 파일 생성 [ 파일명.proto ] 만들기
// 프로토 버전 명시 [ 명시하지 않을 시 컴파일러는 2를 사용하는걸로 가정합니다. ]
syntax = "proto3";
// 패키지 이름 작성하기
package tutorial;
// 서비스 이름을 작성 후 서비스 내에 존재하는 함수 선언 후 파라미터와 Return 타입 지정해주기
service TutorialService {
rpc Accumulate (NumberArray) returns (SumOfNumberArray);
rpc NameArrayReturn (NameArray) returns (NameArrayResponse);
}
// 파라미터가 필요없는 함수를 위한 빈 타입
message Empty {}
// 배열은 앞에 repeated 를 붙인 후 배열 안 타입을 지정해준다.
message NumberArray {
repeated double data = 1;
}
message SumOfNumberArray {
double sum = 1;
}
message NameArray {
repeated string name = 1;
}
message NameArrayResponse {
repeated string name = 1;
}