본문 바로가기
Backend2024년 9월 25일5분 읽기

gRPC 입문 — Protocol Buffers와 양방향 스트리밍

YS
김영삼
조회 497

gRPC와 Protocol Buffers

gRPC는 Google이 개발한 고성능 RPC 프레임워크로, HTTP/2 기반의 바이너리 프로토콜을 사용합니다. REST API 대비 직렬화/역직렬화 속도가 빠르고, 양방향 스트리밍을 지원하여 실시간 통신에 유리합니다. 서비스 인터페이스는 Protocol Buffers(protobuf)로 정의합니다.

Proto 파일 정의

// chat.proto
syntax = "proto3";

package chat;

service ChatService {
  // 단항 RPC
  rpc SendMessage (ChatMessage) returns (ChatResponse);
  // 서버 스트리밍
  rpc GetHistory (HistoryRequest) returns (stream ChatMessage);
  // 클라이언트 스트리밍
  rpc UploadMessages (stream ChatMessage) returns (UploadSummary);
  // 양방향 스트리밍
  rpc LiveChat (stream ChatMessage) returns (stream ChatMessage);
}

message ChatMessage {
  string user = 1;
  string text = 2;
  int64 timestamp = 3;
  MessageType type = 4;
}

enum MessageType {
  TEXT = 0;
  IMAGE = 1;
  FILE = 2;
}

message ChatResponse {
  bool success = 1;
  string message_id = 2;
}

message HistoryRequest {
  string room_id = 1;
  int32 limit = 2;
}

message UploadSummary {
  int32 count = 1;
  bool success = 2;
}

Node.js 서버 구현

const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');

const packageDef = protoLoader.loadSync('chat.proto', {
  keepCase: true, longs: String, enums: String, defaults: true,
});
const proto = grpc.loadPackageDefinition(packageDef).chat;

const server = new grpc.Server();

server.addService(proto.ChatService.service, {
  SendMessage: (call, callback) => {
    const msg = call.request;
    console.log('[' + msg.user + ']: ' + msg.text);
    callback(null, { success: true, message_id: 'msg_' + Date.now() });
  },

  GetHistory: (call) => {
    const messages = getMessagesFromDB(call.request.room_id);
    messages.forEach(msg => call.write(msg));
    call.end();
  },

  LiveChat: (call) => {
    call.on('data', (msg) => {
      call.write({
        user: 'Server',
        text: 'Echo: ' + msg.text,
        timestamp: Date.now()
      });
    });
    call.on('end', () => call.end());
  }
});

server.bindAsync('0.0.0.0:50051',
  grpc.ServerCredentials.createInsecure(),
  () => server.start()
);

gRPC 통신 패턴 비교

패턴클라이언트서버사용 사례
단항(Unary)1 요청1 응답일반 CRUD
서버 스트리밍1 요청N 응답실시간 피드
클라이언트 스트리밍N 요청1 응답파일 업로드
양방향 스트리밍N 요청N 응답채팅, 게임

REST vs gRPC 성능 비교

  • 직렬화 속도: Protobuf는 JSON 대비 약 5-10배 빠릅니다
  • 페이로드 크기: Protobuf는 JSON 대비 약 30-50% 작습니다
  • HTTP/2 멀티플렉싱으로 하나의 TCP 연결에서 여러 RPC를 동시 처리합니다
  • 코드 생성을 통한 타입 안전성이 보장됩니다
  • 브라우저에서는 gRPC-Web 또는 Connect 프로토콜이 필요합니다

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록