GRPC(Google Remote Procedure Call)
RPC의 개념
먼저 gRPC를 설명하기 전에 RPC의 기본적인 개념부터 알고 가야합니다.
RPC는 프로세스간 통신을 위한 기법입니다. 별도의 원격 제어 없이 프로세스 간의 함수나 프로시저를 호출할 수 있도록 하는 통신 기술입니다.
- 클라이언트가 서버의 특정 메소드를 호출할때, 마치 같은 컴퓨터에 있는 것처럼 호출할 수 있는 구조
- 클라이언트와 서버간에 각자가 일반 로컬 메소드를 호출하는 것처럼 사용할 수 있음
- 다양한 언어환경에 제약없이, 플랫폼 제약없이 사용할 수 있음
Caller(클라이언트)와 Callee(서버)는 IDL(Interface define Language)를 통해 서로의 인터페이스를 명세합니다.
Caller가 RPC + Stub(StubComplier를 통해 IDL을 기반으로 각각의 플랫폼, 언어에 맞춰 호출할 수 있는 Code)을 통해 Callee에게 요청 Request합니다.
Call ID, dispatcherHint, dispatcherID, prodedure, arguments과 같은 데이터(IDL)를 담아서 데이터를 주고 받습니다.
Invoke가 일어나고 서버는 결과값을 리턴해줍니다.
gRPC
기존의 RPC는 소켓 프로그래밍에서 Stup을 통해 인터페이스를 명시해서 데이터를 주고 받는 구조였는데, HTTP를 이용한 Rest API가 인기가 생기다보니 자연스럽게 RPC에 대한 인기가 식고 말았습니다.
여기서 RPC의 한계점을 보완하기 위해 구글에서 HTTP2 기반으로 RPC를 구현한 것이 gRPC입니다.
위의 흐름도와 같이 다양한 언어환경에서 Proto를 사용해 Request, Response가 자유롭게 이루어지는 것을 확인할 수 있죠.
message Person {
string name = 1;
int32 id = 2;
bool has_ponycopter = 3;
}
여기서의 Proto는 프로토콜 버퍼(Protocol Buffer)로 RPC의 IDL에 해당합니다. Message로 구성되고, 필드와 이름, value pair(값 쌍)로 구성되어 있습니다.
이러한 proto 데이터 자체가 바이너리기 때문에, 컴퓨터에서 변환과정 없이 매우 빠르게 처리할 수 있고, 바이너리이기 때문에 경량 패킷을 만들 수 있습니다.
Json이나 Xml을 사용하게 되면 각각의 언어에서 언어에 맞게 파싱하는 과정이 필요했었는데... (사실 이 과정이 불편해서 찾아보게 되었습니다… C#에서 Json을 파싱하는 부분이나 Java에서 Json을 파싱하는 부분이 다릅니다) 위의 proto를 사용하게 되면 파싱하는 과정이 생략이 되어버립니다.
이미 타입과 변수, 변수에 들어가는 값(field, name, value pair)이 모두 proto에 명시가 되어있기 때문에!
gRPC 라이브러리에서 이러한 .proto의 파일을 각각의 언어의 특성에 맞게 변환해줍니다.
즉, 프로토콜 버퍼인 proto3가 기존의 Rest에서 쓰이는 Json, Xml과 같은 역할을 한다고 생각하면 되는 거죠.
또한 클래스와 메서드까지도 전송이 된다는 장점이 있습니다.
사실상 JSON을 주고 받는 HTTP의 과정에서 개발자끼리 URL, HTTP payload, 응답코드 등을 서로맞추어야 하는 문제가 있었는데, gRPC는 gRPC가 따라야하는 명확한 형식이 있기 때문에 gRPC를 사용하게 될 경우 그러한 과정을 굳이 할 필요가 없어지게 됩니다.
위와 같은 코드로 .proto 파일을 작성하게 되면 protoc를 이용해서 원하는 언어로 컴파일을 할 수 있고 컴파일 된 소스는 message로 정의된 각 필드에 대해 Getter와 Setter 메서드를 제공해줍니다.
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply);
}
gRPC에서는 호출될 메서드를 service를 통해서 정의합니다. 클라이언트가 정의된 service를 호출하면 이 service 메서드와 동일한 메서드가 서버에서 실행되고 message를 리턴해주게 됩니다.
REST API로 비유하자면 message가 JSON이고, service가 controller의 request mapping uri라고 생각하시면 됩니다.
gRPC는 하나의 큰 어플리케이션을 여러 개의 작은 어플리케이션으로 나누어 분리/조합을 가능하게 만드는 MSA(Micro Sevice Architecture, 마이크로 서비스 아키텍쳐)나 CRUD 웹 어플리케이션에서도 사용할 수 있다는 장점이 있습니다.
추가적으로, gRPC는 HTTP2 기반이기 때문에 서버와 클라이언트가 데이터를 스트리밍 형식으로 주고 받습니다.
service UserService {
rpc getUser(id) returns (user){} // 1
rpc getUser(id) returns (stream user){} // 2
rpc getUser(stream id) returns (user){} // 3
rpc getUser(stream id) returns (stream user){} // 4
}
이와 같이 스트리밍 형식을 4가지 종류의 서비스 형태로 지원합니다.
1번이 클라이언트가 서버에 단일 요청을 보내고 일반 함수 호출과 마찬가지로 단일 응답을 받는 단항 RPC
2번이 클라이언트가 서버에 요청을 보내고 메시지 시퀀스를 다시 읽기 위한 스트림을 가져오는 서버 스트리밍 RPC. 이때 클라이언트는 더 이상 받을 메시지가 없을 때까지 스트림을 읽습니다.
3번이 클라이언트가 메시지를 작성하고 제공된 스트림을 사용해 서버로 보내는 클라이언트 스트링 RPC. 이때 클라이언트가 메시지 쓰기를 마치면 클라이언트는 서버가 메시지를 읽고 리턴할 때까지 기다립니다.
4번이 양방향 스트리밍 RPC로 양측이 읽기 쓰기 스트림을 사용해 일련의 메시지를 전송합니다. 두 스트림은 독립적으로 작동하기 때문에 양측 모두 원하는 순서대로 읽고 쓰기가 가능합니다. 예를 들어 서버는 리턴하기 전에 모든 클라이언트의 메시지를 수신할 때 까지 기다리거나, 메시지를 읽은 다음 다음 메시지를 작성할 수 있습니다.
현재 gRPC에서 지원하는 언어의 플랫폼은 아래와 같습니다.
Language | Platform | Compilers / SDK |
C/C++ | Linux, Mac | GCC 4.9+, Clang 3.4+ |
C/C++ | Windows 7+ | Visual Studio 2015+ |
C# | Linux, Mac | .NET Core, Mono 4+ |
C# | Windows 7+ | .NET Core, NET 4.5+ |
Dart | Windows, Linux, Mac | Dart 2.2+ |
Go | Windows, Linux, Mac | Go 1.12+ |
Java | Windows, Linux, Mac | JDK 8 recommended (Jelly Bean+ for Android) |
Kotlin/JVM | Windows, Linux, Mac | Kotlin 1.3+ |
Node.js | Windows, Linux, Mac | Node v4+ |
Objective-C | Mac OS X 10.11+, iOS 7.0+ | Xcode 7.2+ |
PHP (beta) | Linux, Mac | PHP 5.5+, PHP 7.0+ |
Python | Windows, Linux, Mac | Python 2.7, Python 3.4+ |
Ruby | Windows, Linux, Mac | Ruby 2.3+ |
Proto2 버전과 Proto3 버전이 있는데 범용성이 있는 Proto3을 사용하는 추세입니다.
위는 grpc의 게이트웨이의 흐름을 정리한 것으로 protoc의 플러그인입니다.
REST API를 gRPC로 변환하는 리버스 프록시 서버를 생성해 proto로 변환해주는 것인데 자세한 사항은 아래 링크를 참고하시면 됩니다.
추가적으로 gRPC의 보안 측면에서는 SSL / TLS, OAuth 2.0, Google 서비스를 통한 인증 및 자체 인증 추가를 할 수 있는 2단계 보안을 지원합니다.
grpc 게이트웨이 :: https://grpc-ecosystem.github.io/grpc-gateway/
참고 사이트 :: https://grpc.io/docs/what-is-grpc/core-concepts/
'프로토콜 > gRPC' 카테고리의 다른 글
[gRPC] Protocol Buffer란? (0) | 2022.05.31 |
---|---|
[C#] gRPC Server(Sevice) (0) | 2020.09.04 |
[C#] gRPC Client (0) | 2020.09.03 |
[Java] gRPC Maven (3) | 2020.09.03 |