들어가기 앞서 gRPC를 spring boot를 이용해서 4가지 방식에 대한 실습 git repo
https://github.com/Eeap/Springboot-with-gRPC
gRPC
기존 함수 호출 방법 종류
- 정적 링킹 - 실행 파일 생성시 필요한 라이브러리를 포함하여 생성하는 링킹 방식
- 동적 링킹
- 실행 파일 안에 라이브러리 코드 X, 하나의 메모리 공간에 매핑 후 여러 프로그램에서 공유하여 사용
- 필요한 함수 호출하면 필요한 모듈을 메모리 상으로 불러와서 실행
- 원격 함수 호출(RPC)
- 함수 호출했을 때 호출된 함수의 실행이 통신을 타고 원격지에 있는 컴퓨터에서 실행(분산 네트워크 환경)
- 컴퓨터를 연결하는 RPC 프로토콜이 필요
- 필요한것 - IDL : 원격지와의 연결 지원. 서로 다른 컴퓨터의 정보를 표현하는 기법. - Stub : 본인에게 함수 호출하는 것처럼 하도록 지원
하지만 RPC 프로토콜은 구현의 어려움과 지원 등의 한계로 제대로 활용되지 못함.
그래서 구글에서 나온 gRPC라는 기술!!
gRPC Remote Procedure Call
- http2 기반
- 프로토콜 버퍼 IDL
- 단방향 / 양방향 스트리밍 지원
- 흐름제어/차단/비차단/취소/타임아웃 등 부가기능
- 주용도 : MSA, Mobile App - Backend communication
Client - Stub호출 : 함수가 호출이 되고 결국 호출 받는 언어는 클라이언트가 뭐로 구현이 되어있든 상관이 없다. RPC가 통신이랑 호출되는 언어를 가려버린다. -> MSA에서 유용
stub이라는 애가 rpc 네트워킹 통해서 서버로 보냄.
grpc 특징
- 다양한 언어에서 제공된다
- 심플함 → 싱글 라인으로 실행할 수 있고 대규모 초당 수백만개 rpc 처리 가능하고 성능 좋다
- streaming : 정보를 끊임없이 쏟아낸다.(양방향 streaming이 가능)
- HTTP2 기반 - 보안, 암호화된 통신 하에서 보안이 제공된다.
gRPC vs REST
REST는 하나의 철학이지 표준이 아님→ parameter와 응답 값이 명시적x 또한 HTTP 메소드의 형태가 제한적이기 때문에 세부 기능 구현에는 제약이 존재
덧붙여, 웹 데이터 전달 format으로 xml, json을 많이 사용하는데요.
XML은 html과 같이 tag 기반이지만 미리 정의된 태그가 없어(no pre-defined tags) 높은 확장성을 인정 받아 이기종간 데이터 전송의 표준이었으나, 다소 복잡하고 비효율적인 데이터 구조탓에 속도가 느리다는 단점이 있었습니다. 이런 효율 문제를 JSON이 간결한 Key-Value 구조 기반으로 해결하는 듯 하였으나, 제공되는 자료형의 한계로 파싱 후 추가 형변환이 필요한 경우가 많아졌습니다. 또한 두 타입 모두 string 기반이라 사람이 읽기 편하다는 장점은 있으나, 바꿔 말하면 데이터 전송 및 처리를 위해선 별도의 Serialization이 필요하다는 것을 의미합니다.
프로토콜 특징
- HTTP REST는 하나의 철학
- gRPC : 호출하고 받아오는 규칙(contract)이 strict하다. 프로그래밍 언어의 일환이라 규칙 꼭 지켜야 한다. 그리고 브라우저에서 지원이 안됨.(grpc-web이라는걸 써야함.)
주고받는 정보
- REST : 결과값, 컨텐츠, json
- gRPC : Protobuf 통해서 정보 주고받고 0과 1 비트 조합(binary)으로 주고받는다. 통신 대역폭 줄이고 메시지 작아져서 지연 줄인다.
정보 교환 횟수
- REST : 한 번 교환하면 끝이다(클라이언트와 서버 간의 req res 끝)
- gRPC : 양방향에서 끊임없이 계속 주고받을 수 있다.
.proto(protocol buffer)
- 클라이언트는 호출하고 서버는 호출 당할 함수를 위한 문법 정의하는 파일
- 내가 할 서비스에 대해 정의(서비스 안에 호출할 함수 정의)
- rpc (functionName) (request) returns (response) 형태로 정의
- 함수를 정의한 구문을 서비스가 감싸고, 이 서비스가 호출된다.
- 프로토콜 버퍼 컴파일러가 proto파일 입력받아서 결과 파일(메시지 코드 & 서버 클라이언트 코드) 만들어준다.
- gRPC tool이 .proto 파일로 클라이언트와 서버간의 호출할 코드(message class 파일, client/server class 파일)를 자동으로 생성해줌.
.proto 파일에서의 기본 문법
syntax - 서비스의 문법. protocol buffer언어(protobuf의 버전을 정의)
service - 내가 호출할 함수에 대한 정의를 작성
message - 주고 받을 메시지 객체 작성
gRPC 4가지 타입
- Unary RPC
- 간단한 gRPC 일반 함수처럼 호출되는.
- 함수 호출하면서 결과 가져온다. 간단한 req ,res 구조.
- 한꺼번에 만들어서 보내고 한꺼번에 받는다.
Bidirectional Streaming gRPC
- 스트리밍 : 끊임없이 정보 주고받는다. 각 element를 하나씩 보낸다.
- 클라이언트 -> 서버, 서버 -> 클라이언트 독립적으로 동작한다.
- 서로가 끊임없이 양방향으로 주고받는 것이 기본
- proto : rpc (funcName) (stream request) returns ( stream response)
- 클라이언트 : stub에다가 메시지 리스트를 하나씩 준다 - yield
- 서버 : request_iterator로 데이터를 받아서 for문으로 하나씩 꺼냄. 그 다음 yield를 이용해서 stream으로 데이터를 보냄.
Client Streaming gRPC
- 클라이언트가 메시지를 시퀀스로 흘려보낸다. 서버는 이걸 다 받고 처리 or 받으면서 처리
Server Streaming gRPC
- 클라이언트가 요청에 value 하나 보내면 서버가 리스폰스 스트림으로 보내는 것.
Protobuf (Protocol Buffer)
- 언어, 운영체제 상관없이 정보 주고 받을 수 있도록 한다.
- Serialization(직렬화) 되어 정보를 주고받는다.
- 파이프 있고 거기에 정보 하나하나 흘려보낸다(stream과 비슷한 의미)
- 구조화된 데이터를 직렬화하는 오픈소스 크로스 플랫폼 라이브러리이다.
- 왼쪽에 있는 프로세스, 오른쪽에 있는 프로세스에 쓸 수 있도록 한다.
- 네트워크 건너서 통신하는데 os도 다르고 언어도 다를 때 프로토콜 버퍼에 맞춰서 저장해 어떤 언어가 호출하던지 동일하게 읽어낼 수 있다. (네트워크를 사용해서 서로 개발 정보를 주고 받는데 많이 사용!)
- binary encoding
- required, optional(있을수도, 없을수도)
- 왼쪽이 작은값, 오른쪽으로 갈수록 큰 값 (오른쪽이 주소값이 커서)
- 하드웨어 단까지 내려가서 데이터 표현 -> 표준 정해져 있으니까 다른 컴퓨터에 읽어도 동일.
gRPC 장점
- http 몰라도 grpc 통해서 통신할 수 있다.
- gRPC의 메시지들은 Protobuf(바이너리 메시지 포맷 형식 지원)를 이용해서 직렬화됨
- 직렬화는 small message payloads를 제공하고, mobile같은 제한된 대역폭에서 효율적
- http2 based
- binary framing and compression. bit단위로 커뮤니케이션이 굉장히 작아진다. 주고 받을 때 압축을 해서 앞과 뒤의 차이점만 보냄.
- 하나의 tcp connection에서 multiplexing이 가능 → HOL 블로킹 문제 해결
- proto가 클래스, 메시지 자동으로 만들어준다(auto-generated)
- 클라이언트, 서버 개발자는 proto만 공유하고, 맞추는 작업하지 않아도된다.
- 생산성 향상
- Strict specification : 컴파일하지 않아도 그 전에 에러를 잡을 수 있다. HTTP API 같은 경우 url, format 등을 정하기 위해 논의가 필요하지만 gRPC의 경우 플랫폼 및 구현에 관해 일관성 있는 규칙이 있기 때문에 논의가 필요가 없음. → 개발자들은 시간 절약이 가능.
- Streaming : 데이터를 끊임없이 보내주고 받을 수 있다.
- Deadling/timeouts & cancellation
- client가 호출하는 gRPC에 대한 waiting 타이머, deadline이 server에게 보내지고 서버는 넘어가면 어떻게 할지 결정할 수 있음. 캔슬, 우선순위 지정도 모두 할 수 있다.
- 하위 gRPC call 을 사용해서 deadline과 cancellation을 전파해서 resource를 사용을 제한할 수 있음.
Usage
- Microservices: 가장 효과적인 것은 server to server communication. gRPC가 낮은 지연율과 높은 처리율을 갖고 있기 때문에 경량화된 마이크로서비스에서 효과적
- polygot 환경: gRPC는 웬만한 언어는 다 지원하니 서버들 사이에서 다른 언어로 되어있어도 잘돌아감.
- IPC
- 네트워크 환경이 안좋을 때: json 메시지보다 경량화된 메시지 포맷을 제공(Protobuf)
- 1대1 실시간 통신: 양방향 통신이 가능해서 polling 없이 메시지 푸시 가능.
단점
- 웹브라우저와 서버 사이에 사용하기는 힘들다.
- gRPC 메시지들은 Protobuf로 인코딩되어 있어서 사람이 읽으려면 별도의 인코딩이 필요하다. 중간에 쳐다보기 어려워 성능 점검, 튜닝이 어려워서 다른 도구들이 필요함.
- 메시징을 하는 측면에서는 다른 통신 기법보다 성능이 안좋음 → 목적에 부합하는 도구, 요구사항에 맞는지 성능을 분석할 수 있는 능력이 필요.
- grpc는 보안 설정 + 보안압축 + 해제에 시간 많이 들어서 적절하게 선택해서 사용해야한다.
gRPC 관련 참고 글
'기타' 카테고리의 다른 글
CI / CD 에 대해서.. (0) | 2023.06.04 |
---|---|
QUIC HTTP/3 내용 정리 (0) | 2022.12.08 |
WebRTC 내용 정리 (0) | 2022.12.08 |
HTTP2 정리 내용 (0) | 2022.12.08 |
HTTP2 특징 정리 및 springboot로 테스트하기 (0) | 2022.10.08 |