🗂️ Etc

gRPC와 그에 관한 지식

loose 2023. 6. 13. 22:20
반응형

gRPC란?

 

구글에서 만든 원격 프로시저 호출(RPC)을 뜻한다.

RPC는 원격 위치 서버에 함수를 실행하는 기술을 말한다.

HTTP나 TCP와는 다르게 원격 서버에 함수를 직접 호출한다라는 의미를 갖고 있다.

gRPC는 항상 HTTP나 TCP 위에서 동작한다.

gRPC는 보통 클라이언트 - 서버간의 요청 응답으로 주로 쓰이며 HTTP 통신의 대안으로 쓰인다.

 

여기서 말하는 클라이언트 - 서버는 React - Spring Boot와 같은 개념이 아니다.

MSA 환경에서 분산된 모듈끼리의 통신을 의미한다.

물론 React에도 gRPC로 된 Return을 보낼 수 있지만 인간 친화적이지 않기 때문에 데이터를 알아먹기 힘들어서 외부 API로는 안쓴다.

 



프로토콜 버퍼란?

 

gRPC는 프로토컬 버퍼를 사용해서 동작한다.
프로토콜 버퍼는 가볍고, 이식성이 좋으며, 이해하기 쉬운 데이터 직렬화 형식을 말하며 데이터를 직렬화하고, 클라이언트와 서버 간에 이진 형태로 효율적으로 전송할 수 있다.

보통 HTTP는 텍스트, TCP는 바이트 스트림(바이너리 형식의 바이트 단위 통신), gRPC는 바이너리 형식으로 메시지를 주고 받는다.

바이트는 데이터의 크기를 나타내는 단위이고, 바이너리는 데이터의 형식을 나타내는 개념이다.

gRPC와 TCP 둘다 바이너리 형식으로 메시지를 주고받지만 gRPC는 직렬화, 역직렬화를 통해 더 효율적으로 통신이 가능하다. 텍스트 데이터, 이미지, 오디오, 비디오, 파일 등 어떤 종류의 데이터든지 바이트로 표현할 수 있다면 TCP를 통해 전송할 수 있습니다
데이터가 작기 때문에 직렬화 및 역직렬화 속도가 빠르며 효율적 네트워크 사용이 가능하다.
일반적인 HTTP나 TCP 통신에서도 프로토콜 버퍼를 사용할 수 있지만, gRPC는 이를 보다 효율적으로 사용하기 위해 디자인된 프레임워크다.

 

인텔리제이의 플러그인에서 Protocol Buffer를 검색해보면 미리 깔려있고, 구문강조, 의미론적 분석, 참조 및 탐색 등의 기능을 제공해준다.

 

프로토 버퍼를 통한 프로토콜 버퍼 파일 추가(.proto 파일 작성)

.proto 파일은 자신이 사용할 언어에 기반해서 컴파일이 된다. 컴파일해서 나온 파일은 .protoc파일을 의미한다.

syntax = "proto3"; //proto3을 사용함

option java_multiple_files = true;
option java_package = "org.chb.examples.lib"; 
option java_outer_classname = "HelloWorldProto";

//service규정
service Simple { 
  //SayHello가 오면 HelloReply를 하겠다의 의미
  rpc SayHello (HelloRequest) returns (HelloReply) {  
  }
}

//요청 data 규약 : 문자열 name을 1로 사용하겠다.
message HelloRequest { 
  string name = 1;
}

//응답 data 규약 : 문자열 message을 1로 사용하겠다.
message HelloReply {
  string message = 1;
}

 

java_package 부분이 외부에서 아래와 같이 연결된다.

server Simple 부분이 위의 코드에서 SimpleGrpc로 변환된다.

그래서 이렇게 사용할 수 있다.

프로토콜 버퍼의 코드 생성 기능?

 

프로토콜 버퍼는 코드 생성 기능도 담당한다. 

프로토콜 버퍼는 .proto 파일에 정의된 서비스와 메시지를 기반으로 클라이언트 및 서버 코드를 자동 생성한다.


소켓


컴퓨터 네트워크에서 프로세스 간 통신을 가능하게 하는 인터페이스, 끝점을 말한다.

이 소켓은 코드로서 구현되는데 자바 서버로 따지자면 Socket 클래스로 구현되고 TCP에 구현되어있다. 클라이언트로 따지자면 웹 브라우저가 소켓을 생성해준다. 그래서 서로의 소켓끼리 통신을 주고받는다고 보면된다.

소켓은 TCP/IP를 포함한 다양한 네트워크 프로토콜에서 사용됩니다.

일반적으로 소켓은 양방향 연결 지향성 네트워크에 많이 사용되지만 무조건 양방향으로만 쓰이는 것은 아니다.

HTTP도 TCP을 기본으로 해서 동작하는 프로토콜이다. HTTP 통신은 단방향으로 쓰인다. HTTP 통신에서는 TCP의 연결 유지를 빼고 통신한다고 보면된다.

하지만 HTTP 1.1 이상부터는 양방향 통신이 가능해졌다. 그 양방향 통신을 도와주는게 Websocket이다.

UDP 통신만 단방향이다.

여튼 소켓은 "컴퓨터 네트워크를 경유하는 프로세스 간 통신의 종착점"을 말한다.

결과적으로 HTTP 통신도 소켓 통신을 한다고 볼 수 있다.


gRPC의 사용처?


보통 분산 시스템 혹은 마이크로서비스에서 사용된다. 메시지를 효율적으로 통신할 수 있고 느슨한 결합을 유지시킬 수 있기 때문이다.
양방향 스트리밍, 단방향 스트리밍에서도 사용한다.
실시간 스트리밍, 채팅 시스템, 게임 서버에서 실시간 통신이 중요할 때 사용할 수 있다.

 

느슨한 결합이란?


Contract-First 설계: gRPC는 프로토콜 버퍼(Protocol Buffers)를 사용하여 서비스 인터페이스를 정의합니다. 프로토콜 버퍼는 언어에 독립적인 데이터 직렬화 형식으로, 서비스 간의 통신을 위한 메시지 형식을 명시적으로 정의합니다. 이를 통해 클라이언트와 서버 간의 명확한 계약(Contract)이 형성되며, 이는 느슨한 결합을 유지하는 데 도움을 줍니다. 클라이언트와 서버는 해당 계약에 따라 통신하고, 서비스 인터페이스에 변경이 발생하면 양측이 동시에 업데이트할 수 있습니다.

표준화된 프로토콜: gRPC는 HTTP/2 프로토콜을 기반으로합니다. HTTP/2는 다중화된 양방향 스트림을 지원하고, 헤더 압축, 서버 푸시 등의 기능을 제공합니다. 이러한 표준화된 프로토콜은 서비스 간에 일관된 통신 메커니즘을 제공하며, 서로 다른 프로그래밍 언어와 플랫폼을 사용하는 시스템 간에도 상호 운용성을 보장합니다. 따라서 서비스를 변경하거나 새로운 서비스를 추가할 때에도 다른 서비스에 영향을 미치지 않고 독립적으로 확장할 수 있습니다.

비동기 통신: gRPC는 비동기적인 클라이언트-서버 통신을 지원합니다. 비동기 통신은 여러 요청을 동시에 처리할 수 있고, 일부 요청이 지연되더라도 전체 시스템의 성능에 영향을 덜 주는 장점이 있습니다. 마이크로서비스 아키텍처에서는 여러 서비스 간의 통신이 늘어나므로 비동기 통신은 시스템의 유연성과 확장성을 향상시키는 데 도움이 됩니다.

서비스 디스커버리: gRPC는 서비스 디스커버리 메커니즘을 지원합니다. 서비스 디스커버리는 서비스 인스턴스의 위치를 자동으로 찾아주는 기능을 말합니다. 이를 통해 마이크로서비스 간의 상호 작용이 유연하게 이루어질 수 있고, 서비스의 인스턴스 수를 동적으로 조정할 수 있습니다.



스트리밍이란? 


스트리밍은 데이터를 일정한 흐름으로 전송하는 것을 말한다.
예를 들어 유튜브나 실시간 채팅도 스트리밍이라고 볼 수 있다. 양방향 단방향 스트리밍 모두 존재한다.

RestFul의 ful의 의미?

'잘 따르다'라는 의미다.


gRPC는 만능?


여태까지 정리해보면 gRPC가 HTTP나 TCP를 대체할 수 있는 것처럼 보인다.

왜냐면 gRPC는 HTTP에서 사용하는 기능과 TCP에서 사용하는 기능을 그대로 쓰되 플러스로 프로토콜 버퍼를 이용한 효율적인 네트워크 응답 요청이 가능하기 때문이다. 그럼 gRPC만 쓰는게 정답아닌가요?
다만 gRPC도 한계점은 존재한다.

1. HTTP API에 비해 구현이 복잡한다는 단점이 존재한다.

2. gRPC는 HTTP/2를 기반으로 동작한다. 레거시 시스템에 gRPC를 구현해야할 경우 레거시 시스템의 RESTful API가 HTTP/1.1 프로토콜을 사용중이었다면 구현이 불가능하다.

3. 모든 언어에서 gRPC를 지원하는 것은 아니다.(C++, Java, Go, Python, C#, Node.js, Ruby, Objective-C, PHP, Dart, Kotlin 등 다양한 언어를 지원)

 

 


Spring MVC에서 WebClient를 쓰면 WebFlux를 안써도되는가?


그렇지 않다. MVC에서 WebClient를 쓰는건 외부 API 통신할 때 비동기로 하는 것 뿐이지
Request와 Response까지 비동기처리하진 않는다. WebFlux에서는 Request와 Response까지 비동기 처리한다.


gRPC로 통신을 하면 비동기 처리를 한다. 그럼 Spring MVC환경에서 gRPC를 사용하면 WebFlux를 안써도되는가?

 

그렇다. 말그대로 WebFlux의 기능을 그대로 가져온거기 때문에 안써도된다.

 

마이크로서비스 환경에서 모듈간의 통신의 효율을 위해 비동기 메시지큐인 RabbitMQ를 사용할 수 있는데 이것도 마찬가지로 gRPC를 쓰면 RabbitMQ를 안써도되는가?

그렇다.

마이크로서비스 환경에서는 비동기 통신으로 모듈간 통신을 하면 A라는 모듈은 통신 처리를 기다리지 않고 다른 작업을 수행할 수 있는 장점이 있다. 

 

그럼 gRPC는 WebFlux와 RabbitMQ의 기능을 모두 대체하는 수단이 되는건가?

그렇지는 않다. gRPC는 메시지큐를 대체하지 않는다.

메시지큐는 중간 매개체의 역할과 브로커에 대한 각종 메소드를 지원하기 때문이다.

gRPC와 RabbitMQ를 함께 사용하면 서비스 간의 결합도를 낮출 수 있습니다.

 

 

WebFlux에서의 성능 테스트

 

 

WebFlux는 쓰레드를 Core개수 * 2로 쓰레드로 잡는다.webflux는 gatling으로 부하 테스트한다WebFlux에서 동영상 인코딩을 하면 어쩔수없이 쓰레드에대한 CPU 점유가 많아지는데 쓰레드 풀의 쓰레드가 총 4개라고하면 1개가 아예 뺏기는것이라 WebFlux가 적절한 프로젝트가 아닐 수 있따.r2dbc대신 lettuce를 써서 테스트할 수 있다.pinpoint로 성능확인이 된다.WebFlux에서는 람다에서 log()를 쓰면 동기가 걸리고 map()을 써도 동기가 걸린다.block()은 당연히 동기인데 block 쓰지 못하게 하는게 BlockHound Libarary라고 한다.

 

 

728x90