[gRPC 시작에서 운영까지] 4장_gRPC 동작 원리

RPC 흐름

클라이언트가 ProductID 를 제공해서 제품 세부 사항을 조회하는 getProduct 를 호출할 때의 처리 흐름은 아래와 같다.

  1. 클라이언트 프로세스는, 생성된 스텁에 있는 getProduct 함수를 호출
  2. 클라이언트 스텁은, 인코딩 메세지로 HTTP POST 요청을 생성
  3. HTTP 요청 메세지는 네트워크를 통해 서버 머신으로 전송
  4. 서버는, 메세지 헤더를 검사해서 어떤 서비스 함수를 호출해야하는지 확인하고 메세지를 서비스 스텁에 전달
  5. 서비스 스텁은, 메세지 바이트를 언어별 데이터 구조로 파싱
  6. 파싱된 메세지를 사용해 서비스는, getProduct 함수를 로컬로 호출
  7. 서비스 함수의 응답이 인코딩되어 클라이언트로 다시 전송
  8. 메세지가 복원되어 해당 값이, 대기중인 클라이언트 프로세스로 반환

특히 위 2번의 경우, gRPC 에서는 모든 요청이 application/grpc 접두가 붙는 content-type 을 가진 HTTP POST 요청이다.
호출하는 원격 함수 (/ProductInfo/getProduct) 는 별도의 HTTP 헤더로 전송된다.


gRPC 시작에서 운영까지 <카순 인드라시리, 다네쉬 쿠루푸>

Read more

[gRPC 시작에서 운영까지] 3장_gRPC 통신 패턴

gRPC 기반 애플리케이션에서 사용되는 네 가지 통신 패턴을 정리한다.

  1. Unary RPC
  2. Server Streaming RPC
  3. Client Streaming RPC
  4. Bidirectional Streaming RPC

Unary RPC

위 방식이 Unary RPC 패턴을 따른 것이다.
클라이언트는 orderId 로 단일 요청을 보내고, 서비스는 주문 정보가 포함된 단일 응답을 돌려준다.
이 패턴을 구현해보자.

Service

우선, 프로토콜 버퍼를 사용해 아래와 같이 서비스를 정의한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
syntax = "proto3";

import "google/protobuf/wrappers.proto";

package ecommerce;

service OrderManagement {
rpc getOrder(google.protobuf.StringValue) returns (Order);
}

message Order {
string id = 1;
repeated string items = 2; // 한 번 이상 반복되는 필드를 나타냄. 즉, 하나의 주문 메세지는 여러 아이템이 있을 수 있음.
string description = 3;
float price = 4;
string destination = 5;
}

Server

gRPC 서비스 정의 프로토 파일을 사용해서 서버 스켈레톤 코드를 생성한 뒤에, 아래와 같이 getOrder 메서드의 로직을 구현할 수 있다.

Read more

[gRPC 시작에서 운영까지] 2장_gRPC 시작

위와 같은 온라인 판매 시스템을 만들어보자.

서비스 정의 작성

gRPC 애플리케이션을 개발할 때, 가장 먼저 할 일은 클라이언트가 원격으로 호출할 수 있는 메서드와 메서드의 파라미터, 사용자 메시지 포맷 등을 포함하는 서비스 인터페이스를 정의하는 것이다.
서비스 정의는 gRPC 에서 사용되는 인터페이스 정의 언어 (==IDL) 인 프로토콜 버퍼 정의로 작성된다.

메세지 정의

1
2
3
4
5
6
7
8
9
10
message Product {
string id = 1;
string name = 2;
string description = 3;
float price = 4;
}

message ProductID {
string value = 1;
}

위에서, 각 메세지 필드에 정의된 번호는 메세지에서 필드를 고유하게 식별하는데 사용된다.

서비스 정의

서비스는 클라이언트에게 제공되는 원격 메서드의 모임이다.
위에서 작성한 Product message, ProductID message 와 같이 작성하자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package ecommerce;

service ProductInfo {
rpc addProduct(Product) returns (ProductID);
rpc getProduct(ProductID) returns (Product);
}

message Product {
string id = 1;
string name = 2;
string description = 3;
float price = 4;
}

message ProductID {
string value = 1;
}
Read more

[gRPC 시작에서 운영까지] 1장_gRPC 소개

gRPC

gRPC 는 로컬 함수를 호출하는 것 만큼 쉽게 분산된 이기종 애플리케이션을 연결, 호출, 운영, 디버깅할 수 있는 프로세스 간 통신 기술이다.
gRPC 애플리케이션을 개발할 때 가장 먼저 해야할 일은, 서비스 인터페이스를 정의하는 것이다.
이 때, 인터페이스 정의 언어 (==IDL) 을 사용한다.
서비스 정의를 사용해 Server Skeleton 이라는 server side code 를 생성할 수 있고, Stub 이라는 client side code 도 생성할 수 있다.

위 예시를 통해 살펴보자.
서비스 정의는 ProductInfo.proto 파일에 정의하고, 서버 측과 클라이언트 측 코드를 생성하는데 사용된다.
서비스 정의부터 자세히 보자.

서비스 정의

gRPC 는 프로토콜 버퍼를 IDL 로 사용해서 서비스 인터페이스를 정의한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package ecommerce;

service ProductInfo {
rpc addProduct(Product) returns (ProductID);
rpc getProduct(ProductID) returns (Product);
}

message Product {
string id = 1;
string name = 2;
string description = 3;
float price = 4;
}

message ProductID {
string value = 1;
}

gRPC Server

위와 같이 서비스 정의가 완료되면, 이를 사용해 프로토콜 버퍼 컴파일러인 protoc 를 사용해 서버 측이나 클라이언트 측 코드를 생성할 수 있다.
그리고, 서버는 아래 처리가 필요하다.

  1. 상위 서비스 클래스를 overriding 함으로써 생성된 서버 스켈레톤의 서비스 로직을 구현
  2. gRPC 서버를 실행해 클라이언트 요청을 수신하고 응답
Read more