gRPC는 google 사에서 개발한 오픈소스 RPC(Remote Procedure Call) 프레임워크이다. 이전까지는 RPC 기능은 지원하지 않고, 메세지(JSON 등)을 Serialize할 수 있는 프레임워크인 PB(Protocol Buffer, 프로토콜 버퍼)만을 제공해왔는데, PB 기반 Serizlaizer에 HTTP/2를 결합하여 RPC 프레임워크를 탄생 시켰다.
REST와 비교했을 때 기반 기술이 다르기에 특징도 많이 다르지만, 가장 두드러진 차이점은 HTTP/2를 사용한다는 것과 프로토콜 버퍼로 데이터를 전달한다는 점이다. 그렇기에 Proto File만 배포하면 환경과 프로그램 언어에 구애받지 않고 서로 간의 데이터 통신이 가능하다.
HTTP/1.1은 플레인 텍스트를 주고 받는 request - response 모델을 사용한다.
HTTP/2은 HTTP/1.1과 동일한 시멘틱을 공유하지만 (e.g. GET, POST 와 같은 메서드 / 헤더와 바디로 구성된 메세지 포맷 등) 메세지를 바이너리로 인코딩해서 주고 받는다는 커다란 차이가 있다.
HTTP/1.0의 경우 매번 새로운 리퀘스트에 대해서 TCP 커넥션을 새로 만들어야 했으므로 시간과 리소스를 더 소비했다. 이에 비해 HTTP/1.1은 지속적인 연결(persistant connection)을 가능하게 해서 하나의 TCP 커넥션이 유지된 채로, 응답을 기다릴 필요 없이 여러 개의 리퀘스트를 보낼 수 있다.
HTTP/1.1은 1.0에 비해 성능을 향상시켰지만 여전히 latency 이슈가 있다. 하나의 커넥션에 여러 개의 요청을 보낼 때, 이 요청들을 queue에 관리하므로 queue의 헤드 요청이 오래 걸리는 경우 뒤에 있는 요청들은 블로킹되는 병목현상이 나타난다. 이를 head-of-line(HOL) blocking 이라고 부른다.
병렬적으로 여러 개의 TCP 커넥션을 만들면 이 문제를 완화할 수는 있지만, 클라이언트와 서버 사이에 동시에 유지할 수 있는 TCP 커넥션의 수가 제한되어 있을 뿐더러 TCP 커넥션을 새로 만들 때마다 추가적으로 리소스가 든다. (e.g. TCP handshake)
반면 HTTP/2 는 하나의 TCP 연결이 여러 개의 양방향 스트림(bidirectional streams)을 지원한다. 하나의 커넥션은 여러 개의 스트림으로 구성되고, 각 스트림들은 여러 개의 메세지들(req-res 관계에서 주고 받는 포맷)로 구성되며 각 메세지들은 또 여러 개의 프레임으로 구성된다. 프레임들은 바이너리로 인코딩돼 있는 작은 단위이며, 특정 스트림에 속해 있다는 태그를 달고 있다. 이 식별 태그들은 커넥션이 인터리빙할 수 있게 해주고 결과적으로 블로킹 없이 여러 개의 요청-응답을 가능하게 한다. 즉 새로운 연결을 만들지 않고도 여러 개의 메세지가 병렬적으로 동시에 보낼 수 있는데 이를 Multiplexing 이라고 한다
https://medium.com/naver-cloud-platform/nbp-%EA%B8%B0%EC%88%A0-%EA%B2%BD%ED%97%98-%EC%8B%9C%EB%8C%80%EC%9D%98-%ED%9D%90%EB%A6%84-grpc-%EA%B9%8A%EA%B2%8C-%ED%8C%8C%EA%B3%A0%EB%93%A4%EA%B8%B0-1-39e97cb3460
https://meetup.toast.com/posts/261
https://alledy.netlify.app/posts/rest-vs-grpc/