RPC(Remote Procedure Call)
는 분산 시스템 내에 존재하는 다른 컴퓨터 프로세스의 메서드를 원격으로 호출하는 것이다. 마치 로컬 메서드를 호출하는 것처럼 말이다.
IDL(Interfacte Definition Langauge)
를 활용해 호출 규약을 정의하고 stub
코드를 생성한다.
RPC
는 stub
이란 프록시 객체를 통해 서로 통신할 수 있게 도와준다. 프로그래머가 네트워크 지식이 없더라도 이 stub
을 활용해 원격 함수 호출을 할 수 있다. (RPC
호출을 돕는 인터페이스라고 보면 된다.)
gRPC
는 구글이 개발한 RPC
이다.
gRPC
는 IDL
로 protobuf
를 사용한다. 프로그램 상에서 사용하려면 .proto
stub
이 생성되어 있어야 한다.
여러 가지 통신 방식을 제공하는데, 다음과 같다.
1. 서버 측에서 스트리밍하는 방식
2. 클라이언트 측에서 스트리밍하는 방식
3. 서버와 클라이언트 양방향으로 스트리밍하는 방식
그리고 동기 방식 뿐만 아니라 비동기 방식도 제공한다.
1 .proto
파일 작성: 개발자가 서비스와 메시지 구조를 정의하는 .proto
파일을 작성한다.
2. protoc
실행: protoc
컴파일러를 실행하여 .proto
파일을 컴파일한다.
3. 언어별 코드 생성:protoc
는 .proto
파일을 분석하고, 지정된 프로그래밍 언어에 맞는 코드를 자동으로 생성한다.
4. 코드 사용:생성된 코드를 프로젝트에 포함시켜 gRPC
클라이언트와 서버를 구현한다.
.pb.go
파일.proto
파일에서 정의한 모든 메시지 타입에 대한 Go 클래스를 포함한다._grpc.pb.go
파일:gRPC
서비스 인터페이스를 정의한다.Servicer
클래스를 포함한다.Stub
클래스를 포함한다.REST API
는 client to server
뿐만 아니라 server to server
통신도 가능하다. 근데 왜 MSA
내에서 서버 간 통신에는 REST
보다 gRPC
를 사용할까?
바로 데이터 포맷 때문이다.
REST API
는 JSON
기반으로 데이터를 교환한다. JSON
은 사람이 보기에는 아주 편하다. 하지만, 컴퓨터 입장에서는 데이터 크기가 큰 편이고 파싱 비용도 발생한다. 반면 gRPC
는 protobuf
라는 데이터 포맷으로 직렬화해서 json
보다 더 데이터 크기도 작으면서 처리속도도 빠르다. 서버 간 통신에서는 네트워크 사용량을 줄이고, 응답 시간이 빠른 gRPC
가 더 낫다. (서버 간에는 대규모 데이터 전송도 빈번하게 일어난다.)
이제 서버 간 통신 외의 것들도 살펴보자.
gRPC
는 http 2.0
기반으로 만들어졌기 때문에 멀티플렉싱
을 제공한다. 그래서 하나의 TCP
연결로도 여러 요청과 응답 메시지를 주고 받을 수 있어 효율적이다. 만약, REST API
를 http 1.1
이하에서 사용한다면 하나의 TCP
연결로 하나의 요청/응답만 처리하기 때문에 비효율적이다. 물론, REST API
를 http 2.0
에서 사용한다면 REST API
역시 멀티플렉싱
을 사용할 수 있다.
그리고 REST API
는 요청 / 응답 방식이다. 따라서 실시간 데이터 스트리밍에는 적합하지 않다. 하지만 gRPC
는 양방향 스트리밍을 지원하여 클라이언트와 서버가 실시간으로 데이터를 주고 받을 수 있다.
그러나 REST API
의 경우 브라우저에서 기본적으로 지원되지만, gRPC
는 브라우저에서 직접 사용할 수 없다. 사용하려면 gRPC-web
과 같은 솔루션이 필요하다.
메시지 큐
와 gRPC
는 서버 간 통신에서 많이 쓰인다. 물론 여러 가지 차이가 있겠지만, 가장 큰 것은 브로커
의 유무인 것 같다.
gRPC
의 경우, 클라이언트가 서버를 알아야 하지만 서버는 클라이언트를 알 필요가 없다.
메시지 큐
의 경우, 브로커로 인해 클라이언트와 서버 모두 서로를 알 필요가 없다.
이 차이로 인해 설계에 있어서 메시지 큐가 좀 더 확장성이 높다.
https://velog.io/@dasd412/protobuf-namspace-collision-in-MSA-golang-ent
.proto
라는 것은 클라이언트와 서버 간의 규약이라고 볼 수 있다. 규약은 버전이 호환되야 한다. field number 정리하겠답시고 .proto
를 수정하면 다음과 같은 일이 일어난다.
.proto
를 사용하던 클라이언트는 field number 2에서 int age가 올줄 알았지만 string name이 와서 터진다.https://grpc.io/docs/what-is-grpc/core-concepts/
https://protobuf.dev/overview/
https://mclub4.tistory.com/47
https://wisysta.tistory.com/entry/RPC-gRPC