등장배경
1. Server-Client Model
하나의 메인 프레임에서 동작하는 Monolothic 구조로 설계 시절 네트워크 통신 중요 X
고가인 메인 프레임워크 → 비교적 저가의 워크스테이션 서버로 대체하고 싶어함
But, 메인 프레임워크의 초고양 사양 그대로 제공하는데 한계
⇒ 메인 프레임워크 기능 → 워크스테이션 서버로 분산 + 네트워크 연결로 서비스하는 방식 채택
= Server-Client Model
⇒ 서버-서버, 서버-개인PC 간 네트워크 연결 및 통신 중요
→ OSI 7 layer, TCP/IP 등 네트워크 계층 구조 정의, 발전
2. IPC
프로세스는 기본적으로 상호독립적
메모리 공유 X → 각자 자신의 일만 하고 서로 간섭 X
But, 필요에 따라 프로세스 간 정보를 교환해야 하는 경우
→ 별도의 수단 이용하여 프로세스 통신하는 방법론 = IPC(Inter Process Communication)
1) Socket
OSI 7 layer 구조의 Application Layer(L7)에서 Transport Port(L4)의 TCP or UDP를 이용하기 위한 수단
일종의 창구 역할
일련의 통신 과정 직접 구현 → 통신 관련 장애 처리 ⇒ 개발자의 몫
서비스 고도화 → data formatting 하는 것 어려워짐 ⇒ RPC
2) RPC(Remote Procedure Call)
네트워크로 연결된 서버 상의 프로시저(함수, 메서드 등) 원격으로 호출할 수 있는 기능
네트워크 통신을 위한 작업 챙기지 X 통신이나 call 방식 신경 X 원격자의 자원을 내 것처럼 사용 가능
IDL(Interface Definication Language) 기반으로 다양한 언어를 가진 환경에서도 쉽게 확장 가능
인터페이스 협업에도 용이
지원 언어: C++, Java, Python, Ruby, Node.js, C#, Go, PHP, Objective-C…
서버-클라이언트는 서로 다른 주소 공간 사용 → 함수 호출에 사용된 매개 변수를 꼭 변환해줘야 함
→ 메모리 매개 변수에 대한 포인터가 다른 데이터를 가리키게 될 수 있기 때문
이러한 변환 담당: 스텁(Stub)
- client stub
- 함수 호출에 사용된 파라미터의 변환(Marshalling, 마샬링) 및 함수 실행 후 서버에서 전달된 결과 반환
- server stub
- 클라이언트가 전달한 매개 변수의 역변환(Unmarshalling, 언마샬링) 및 함수 실행 결과 변환 담당

RPC 통신 과정
- IDL(Interface Definition Language) 사용 → 호출 규약 정의
- 함수명, 인자, 반환값에 대한 데이터형이 정의된 IDL 파일 → rpcgen으로 컴파일 ⇒ stub code가 자동으로 생성
- Stub Code에 명시된 함수: 원시코드의 형태, 상세 기능: server에서 구현됨
- 만들어진 stub 코드 → 클라이언트/서버와 함께 빌드
- client에서 stub에 정의된 함수 사용시
- client stub) RPC runtime ~> 함수 호출
- server) 수신된 procedure 호출에 대한 처리 후 결과값 반환
- 최종적으로 client는 server의 결과값 반환받고, 함수를 local에 있는 것처럼 사용 가능
⇒ 원격지의 것을 끌어다 로컬처럼 사용,
구현체 CORBA, RMI 등 여러가지
→ 로컬에서 제공하는 빠른 속도, 가용성 등 분산 프로그래밍에서도 제공
But, 구현의 어려움/지원 한계 등 → 제대로 활용 X
⇒ 데이터 통신을 익숙한 Web을 활용해보려는 시도 → REST
3) REST(REpresentational State Transfer)
HTTP/1.1 기반으로 URI ~> 자원(resource) 명시 + HTTP Method ~> 처리하는 아키텍처
자원 그 자체를 표현 ⇒ 직관적, HTTP 그대로 계승 → 별도 작업 X 쉽게 사용할 수 있음
But, 일종의 스타일이지 표준 X → parameter와 응답값 명시적 X,
HTTP 메소드 형태 제한적 → 세부 기능 구현에는 제약
+XML, JSON
html과 같이 tag 기반이지만 미리 정의된 태그 X(no pre-defined tags) → 높은 확장성 인정
But, 복잡, 비효율적인 데이터 구조 → 속도 느림
⇒ JSON이 간결한 key-value 구조 기반으로 해결하는 듯 했지만
제공되는 자료형의 한계로 파싱 후 추가 형변환이 필요한 경우 많아짐
두 타입 모두 string 기반이라 사람이 읽기 편하지만, 데이터 전송 및 처리 → 별도의 serialization 필요
gRPC(Google Remote Procedure Call)
goolge 사에서 개발한 오픈소스 RPC 프레임워크
이전까지는 RPC 기능 지원 X, 메시지(JSON 등)을 serialize할 수 있는 프레임워크인 PB(Protocol Buffer, 프로토콜 버퍼)만 제공
⇒ PB 기반 serializer + HTTP/2 결합
REST와 비교: 기반 기술 다름, HTTP/2 사용, 프로토콜 버퍼로 데이터 전송
→ Proto File만 배포하면 환경과 프로그램 언어에 구애 X 서로 간의 데이터 통신 가능
1. HTTP

- HTTP/1.1
- 클라이언트의 요청이 올 때만 서버가 응답을 하는 구조 → 매 요청마다 connection 생성해야 함
- cookie 등 많은 메타 정보를 저장하는 무거운 header 요청마다 중복 전달 ⇒ 비효율, 느린 속도
- HTTP/2
- 한 connection으로 동시에 여러 개 메시지 주고 받음
- header 압축 → 중복 제거 후 전달 ⇒ 효율적
- 필요 시 클라이언트 요청 X 서버가 리소스를 전달 할 수 있음 ⇒ 클라이언트 요청 최소화
2. ProtoBuf(Protocol Buffer, 프로토콜 버퍼)
google 사에서 개발한 구조화된 데이터를 직렬화(serialization)하는 기법
직렬화: 데이터 표현을 바이트 단위로 변환하는 작업
- text 기반인 json: 82 byte 소요
- 직렬화 된 protocol buffer
- 필드 번호, 필드 유형 등 → 1 byte 받아서 식별, 주어진 length 만큼만 읽도록 해 33 byte 필요

3. Proto File
1) Message and Field
주고 받는 data → message라는 것으로 정의
메시지는 여러가지 타입의 필드로 구성
이름은 CamelCase 형태, field 이름은 under_bar 형태로 사용 권장
field 이름은 숫자로 시작 X
2) Package
message type 이름을 중첩없이 구분할 때 사용
3) Service
RPC ~> 서버가 클라이언트에게 제공할 함수의 형태를 정의
서비스명과 RPC 메소드명 모두 CamelCase 권장
옵션 X → 단일 요청/응답으로 동작, stream 옵션 → RPC 구현할 수 있음
gRPC와 서버 간 통신
고성능과 효율성 요구할 때 많이 사용 ⇒ 마이크로서비스 아키텍처 or 분산 시스템에서 많이 사용
- 바이너리 프로토콜
- protobuf라는 바이너리 직렬화 방식 사용 → JSON or XML 같은 텍스트 기반 포맷에 비해 데이터 전송 속도 빠름
- HTTP/2
- 다중 요청/응답 스트림, 멀티플렉싱, 헤더 압축 등 기능 제공 → 클라이언트-서버 효율적인 연결 가능하게 함
- 양방향 스트리밍
- 서버와 클라이언트 동시에 메시지 주고받을 수 있어 실시간 데이터 통신이 필요한 서비스에 적합
- 엄격한 타입 검사
- proto 파일 ~> 명확한 스키마 정의 ⇒ 서버 간에 주고받는 데이터 타입을 컴파일 시점에 검증할 수 있음 ⇒ 타입 안정성이 보장
사용 사례
- 마이크로서비스 간의 통신
- 여러 개의 서비스가 상호 통신해야 하는 경우가 많은데 서버 간 데이터 전송 빈번하고, 속도와 성능 중요한 경우 사용
- ex. 추천 시스템에서 사용자 데이터를 수집하는 서비스, 이를 기반으로 분석을 수행하는 서비스 간 통신
- 여러 개의 서비스가 상호 통신해야 하는 경우가 많은데 서버 간 데이터 전송 빈번하고, 속도와 성능 중요한 경우 사용
- 실시간 스트리밍
- HTTP/2 기반의 스트리밍 지원 → 실시간으로 대규모 데이터를 주고받는 서비스에 적합
- ex. 비디오 스트리밍, 채팅 시스템, 실시간 게임 서버 간 통신
- HTTP/2 기반의 스트리밍 지원 → 실시간으로 대규모 데이터를 주고받는 서비스에 적합
- 다중 요청/응답 처리
- HTTP/2 멀티플렉싱 기능 활용 → 다중 요청 동시에 처리할 수 있음
- 클라우드 서비스 간 통신
- 서버 간 통신 최적화
- ex. Goole Cloud, Kubernetes 등 클라우드 네이티브 환경
- 서버 간 통신 최적화

단점
- 브라우저 지원 제한
- gRPC-Web이라는 프로토콜 사용 or 프록시 서버(Nginx, Envoy 등) 사용
- 복잡성 증가
- 바이너리 형식의 Protocol Buffers 사용 → 추가적인 설정과 학습 필요
- 텍스트 디버깅 어려움
- 바이너리 기반 직렬화 사용 → 데이터를 사람이 쉽게 읽거나 디버깅하기 어려움
- protoc 도구 사용 → 메시지 디코딩
- Postman과 같은 gRPC 클라이언트 사용
- 바이너리 기반 직렬화 사용 → 데이터를 사람이 쉽게 읽거나 디버깅하기 어려움
- 호환성 문제
- 메시지 크기 제한
- 기본 설정에서 최대 메시지 크기 제한적 → 대용량 데이터 전송시 값을 변경해야 함
- (해결) gRPC 스트리밍 기능 사용 → 데이터 분할
- 클라이언트-서버 강한 결합
- 동일한 프로토콜 정의(.proto 파일) 사용해야 함
- 표준적인 인증 및 보안 모델 부족
- (해결) TLS(전송 계층 보안) ~> 보안 설정 or OAuth 같은 기존 인증 방식 추가로 적용
사용하는 기업

출처
[NBP 기술&경험] 시대의 흐름, gRPC 깊게 파고들기 #1
안녕하세요, 네이버 클라우드 플랫폼입니다.
medium.com
'BE' 카테고리의 다른 글
Saga & 2PC (0) | 2025.02.23 |
---|---|
MyBatis VS. JPA (0) | 2025.02.23 |
등장배경
1. Server-Client Model
하나의 메인 프레임에서 동작하는 Monolothic 구조로 설계 시절 네트워크 통신 중요 X
고가인 메인 프레임워크 → 비교적 저가의 워크스테이션 서버로 대체하고 싶어함
But, 메인 프레임워크의 초고양 사양 그대로 제공하는데 한계
⇒ 메인 프레임워크 기능 → 워크스테이션 서버로 분산 + 네트워크 연결로 서비스하는 방식 채택
= Server-Client Model
⇒ 서버-서버, 서버-개인PC 간 네트워크 연결 및 통신 중요
→ OSI 7 layer, TCP/IP 등 네트워크 계층 구조 정의, 발전
2. IPC
프로세스는 기본적으로 상호독립적
메모리 공유 X → 각자 자신의 일만 하고 서로 간섭 X
But, 필요에 따라 프로세스 간 정보를 교환해야 하는 경우
→ 별도의 수단 이용하여 프로세스 통신하는 방법론 = IPC(Inter Process Communication)
1) Socket
OSI 7 layer 구조의 Application Layer(L7)에서 Transport Port(L4)의 TCP or UDP를 이용하기 위한 수단
일종의 창구 역할
일련의 통신 과정 직접 구현 → 통신 관련 장애 처리 ⇒ 개발자의 몫
서비스 고도화 → data formatting 하는 것 어려워짐 ⇒ RPC
2) RPC(Remote Procedure Call)
네트워크로 연결된 서버 상의 프로시저(함수, 메서드 등) 원격으로 호출할 수 있는 기능
네트워크 통신을 위한 작업 챙기지 X 통신이나 call 방식 신경 X 원격자의 자원을 내 것처럼 사용 가능
IDL(Interface Definication Language) 기반으로 다양한 언어를 가진 환경에서도 쉽게 확장 가능
인터페이스 협업에도 용이
지원 언어: C++, Java, Python, Ruby, Node.js, C#, Go, PHP, Objective-C…
서버-클라이언트는 서로 다른 주소 공간 사용 → 함수 호출에 사용된 매개 변수를 꼭 변환해줘야 함
→ 메모리 매개 변수에 대한 포인터가 다른 데이터를 가리키게 될 수 있기 때문
이러한 변환 담당: 스텁(Stub)
- client stub
- 함수 호출에 사용된 파라미터의 변환(Marshalling, 마샬링) 및 함수 실행 후 서버에서 전달된 결과 반환
- server stub
- 클라이언트가 전달한 매개 변수의 역변환(Unmarshalling, 언마샬링) 및 함수 실행 결과 변환 담당

RPC 통신 과정
- IDL(Interface Definition Language) 사용 → 호출 규약 정의
- 함수명, 인자, 반환값에 대한 데이터형이 정의된 IDL 파일 → rpcgen으로 컴파일 ⇒ stub code가 자동으로 생성
- Stub Code에 명시된 함수: 원시코드의 형태, 상세 기능: server에서 구현됨
- 만들어진 stub 코드 → 클라이언트/서버와 함께 빌드
- client에서 stub에 정의된 함수 사용시
- client stub) RPC runtime ~> 함수 호출
- server) 수신된 procedure 호출에 대한 처리 후 결과값 반환
- 최종적으로 client는 server의 결과값 반환받고, 함수를 local에 있는 것처럼 사용 가능
⇒ 원격지의 것을 끌어다 로컬처럼 사용,
구현체 CORBA, RMI 등 여러가지
→ 로컬에서 제공하는 빠른 속도, 가용성 등 분산 프로그래밍에서도 제공
But, 구현의 어려움/지원 한계 등 → 제대로 활용 X
⇒ 데이터 통신을 익숙한 Web을 활용해보려는 시도 → REST
3) REST(REpresentational State Transfer)
HTTP/1.1 기반으로 URI ~> 자원(resource) 명시 + HTTP Method ~> 처리하는 아키텍처
자원 그 자체를 표현 ⇒ 직관적, HTTP 그대로 계승 → 별도 작업 X 쉽게 사용할 수 있음
But, 일종의 스타일이지 표준 X → parameter와 응답값 명시적 X,
HTTP 메소드 형태 제한적 → 세부 기능 구현에는 제약
+XML, JSON
html과 같이 tag 기반이지만 미리 정의된 태그 X(no pre-defined tags) → 높은 확장성 인정
But, 복잡, 비효율적인 데이터 구조 → 속도 느림
⇒ JSON이 간결한 key-value 구조 기반으로 해결하는 듯 했지만
제공되는 자료형의 한계로 파싱 후 추가 형변환이 필요한 경우 많아짐
두 타입 모두 string 기반이라 사람이 읽기 편하지만, 데이터 전송 및 처리 → 별도의 serialization 필요
gRPC(Google Remote Procedure Call)
goolge 사에서 개발한 오픈소스 RPC 프레임워크
이전까지는 RPC 기능 지원 X, 메시지(JSON 등)을 serialize할 수 있는 프레임워크인 PB(Protocol Buffer, 프로토콜 버퍼)만 제공
⇒ PB 기반 serializer + HTTP/2 결합
REST와 비교: 기반 기술 다름, HTTP/2 사용, 프로토콜 버퍼로 데이터 전송
→ Proto File만 배포하면 환경과 프로그램 언어에 구애 X 서로 간의 데이터 통신 가능
1. HTTP

- HTTP/1.1
- 클라이언트의 요청이 올 때만 서버가 응답을 하는 구조 → 매 요청마다 connection 생성해야 함
- cookie 등 많은 메타 정보를 저장하는 무거운 header 요청마다 중복 전달 ⇒ 비효율, 느린 속도
- HTTP/2
- 한 connection으로 동시에 여러 개 메시지 주고 받음
- header 압축 → 중복 제거 후 전달 ⇒ 효율적
- 필요 시 클라이언트 요청 X 서버가 리소스를 전달 할 수 있음 ⇒ 클라이언트 요청 최소화
2. ProtoBuf(Protocol Buffer, 프로토콜 버퍼)
google 사에서 개발한 구조화된 데이터를 직렬화(serialization)하는 기법
직렬화: 데이터 표현을 바이트 단위로 변환하는 작업
- text 기반인 json: 82 byte 소요
- 직렬화 된 protocol buffer
- 필드 번호, 필드 유형 등 → 1 byte 받아서 식별, 주어진 length 만큼만 읽도록 해 33 byte 필요

3. Proto File
1) Message and Field
주고 받는 data → message라는 것으로 정의
메시지는 여러가지 타입의 필드로 구성
이름은 CamelCase 형태, field 이름은 under_bar 형태로 사용 권장
field 이름은 숫자로 시작 X
2) Package
message type 이름을 중첩없이 구분할 때 사용
3) Service
RPC ~> 서버가 클라이언트에게 제공할 함수의 형태를 정의
서비스명과 RPC 메소드명 모두 CamelCase 권장
옵션 X → 단일 요청/응답으로 동작, stream 옵션 → RPC 구현할 수 있음
gRPC와 서버 간 통신
고성능과 효율성 요구할 때 많이 사용 ⇒ 마이크로서비스 아키텍처 or 분산 시스템에서 많이 사용
- 바이너리 프로토콜
- protobuf라는 바이너리 직렬화 방식 사용 → JSON or XML 같은 텍스트 기반 포맷에 비해 데이터 전송 속도 빠름
- HTTP/2
- 다중 요청/응답 스트림, 멀티플렉싱, 헤더 압축 등 기능 제공 → 클라이언트-서버 효율적인 연결 가능하게 함
- 양방향 스트리밍
- 서버와 클라이언트 동시에 메시지 주고받을 수 있어 실시간 데이터 통신이 필요한 서비스에 적합
- 엄격한 타입 검사
- proto 파일 ~> 명확한 스키마 정의 ⇒ 서버 간에 주고받는 데이터 타입을 컴파일 시점에 검증할 수 있음 ⇒ 타입 안정성이 보장
사용 사례
- 마이크로서비스 간의 통신
- 여러 개의 서비스가 상호 통신해야 하는 경우가 많은데 서버 간 데이터 전송 빈번하고, 속도와 성능 중요한 경우 사용
- ex. 추천 시스템에서 사용자 데이터를 수집하는 서비스, 이를 기반으로 분석을 수행하는 서비스 간 통신
- 여러 개의 서비스가 상호 통신해야 하는 경우가 많은데 서버 간 데이터 전송 빈번하고, 속도와 성능 중요한 경우 사용
- 실시간 스트리밍
- HTTP/2 기반의 스트리밍 지원 → 실시간으로 대규모 데이터를 주고받는 서비스에 적합
- ex. 비디오 스트리밍, 채팅 시스템, 실시간 게임 서버 간 통신
- HTTP/2 기반의 스트리밍 지원 → 실시간으로 대규모 데이터를 주고받는 서비스에 적합
- 다중 요청/응답 처리
- HTTP/2 멀티플렉싱 기능 활용 → 다중 요청 동시에 처리할 수 있음
- 클라우드 서비스 간 통신
- 서버 간 통신 최적화
- ex. Goole Cloud, Kubernetes 등 클라우드 네이티브 환경
- 서버 간 통신 최적화

단점
- 브라우저 지원 제한
- gRPC-Web이라는 프로토콜 사용 or 프록시 서버(Nginx, Envoy 등) 사용
- 복잡성 증가
- 바이너리 형식의 Protocol Buffers 사용 → 추가적인 설정과 학습 필요
- 텍스트 디버깅 어려움
- 바이너리 기반 직렬화 사용 → 데이터를 사람이 쉽게 읽거나 디버깅하기 어려움
- protoc 도구 사용 → 메시지 디코딩
- Postman과 같은 gRPC 클라이언트 사용
- 바이너리 기반 직렬화 사용 → 데이터를 사람이 쉽게 읽거나 디버깅하기 어려움
- 호환성 문제
- 메시지 크기 제한
- 기본 설정에서 최대 메시지 크기 제한적 → 대용량 데이터 전송시 값을 변경해야 함
- (해결) gRPC 스트리밍 기능 사용 → 데이터 분할
- 클라이언트-서버 강한 결합
- 동일한 프로토콜 정의(.proto 파일) 사용해야 함
- 표준적인 인증 및 보안 모델 부족
- (해결) TLS(전송 계층 보안) ~> 보안 설정 or OAuth 같은 기존 인증 방식 추가로 적용
사용하는 기업

출처
[NBP 기술&경험] 시대의 흐름, gRPC 깊게 파고들기 #1
안녕하세요, 네이버 클라우드 플랫폼입니다.
medium.com
'BE' 카테고리의 다른 글
Saga & 2PC (0) | 2025.02.23 |
---|---|
MyBatis VS. JPA (0) | 2025.02.23 |