본문 바로가기
개발정리 (nodeJS)

[nodeJS] Node.js와 gRPC를 사용한 고성능 서비스 구축하기

by 할리갈리0 2024. 8. 26.

gRPC는 RPC(Remote Procedure Call) 프레임워크로, 다양한 프로그래밍 언어에서 서비스 간의 통신을 지원합니다. gRPC는 HTTP/2를 기반으로 하여 효율적인 데이터 전송과 스트리밍을 제공하며, 프로토콜 버퍼(Protocol Buffers)를 사용하여 직렬화된 데이터를 전송합니다.

 

gRPC의 주요 특징

  • 다양한 언어 지원: gRPC는 여러 프로그래밍 언어에서 사용할 수 있어, 다중 언어 환경에서도 통합이 용이
  • 효율적인 데이터 전송: HTTP/2 기반으로 멀티플렉싱과 헤더 압축을 통해 효율적인 데이터 전송을 지원
  • 스트리밍 지원: 클라이언트와 서버 간의 양방향 스트리밍을 지원하여 실시간 데이터 전송이 가능
  • 프로토콜 버퍼: 프로토콜 버퍼를 사용하여 빠르고 효율적인 데이터 직렬화가 가능

1. gRPC의 장점 및 사용 이유

gRPC의 장점

  • 고성능: HTTP/2와 프로토콜 버퍼를 통해 낮은 대기 시간과 높은 처리량을 제공하여 고성능 서비스 구축 가능
  • 타입 안전성: 프로토콜 버퍼는 엄격한 스키마를 정의하여 타입 안전성 보장
  • 확장성: gRPC는 서비스의 확장성과 유연성을 제공하여, 대규모 시스템에서도 효과적으로 사용 가능

gRPC 사용 이유

  • 비동기 통신: 비동기식 메시지 전송을 통해 응답성을 높이고, 시스템의 부하를 효과적으로 관리 가능
  • 서비스 간 통신 표준화: 다양한 서비스 간의 통신을 표준화하여 유지보수성을 높일 수 있음
  • 복잡한 API 설계: 다양한 API 유형을 지원하여 복잡한 애플리케이션 아키텍처 구현 가능

2. Node.js 프로젝트에 gRPC 설정하기

프로젝트 초기화 및 패키지 설치

Node.js 프로젝트를 초기화하고, gRPC와 프로토콜 버퍼를 사용하기 위한 패키지 설치

  • @grpc/grpc-js: Node.js에서 gRPC를 사용하기 위한 패키지
  • @grpc/proto-loader: 프로토콜 버퍼 파일을 로드하기 위한 패키지
mkdir grpc-nodejs
cd grpc-nodejs
npm init -y
npm install @grpc/grpc-js @grpc/proto-loader

 

디렉터리 구조

디렉터리 구조 설정

  • server.js: gRPC 서버 구현 파일
  • client.js: gRPC 클라이언트 구현 파일
  • protos/helloworld.proto: gRPC 서비스 정의를 위한 프로토콜 버퍼 파일
grpc-nodejs
├── server.js
├── client.js
├── protos
│   └── helloworld.proto
├── package.json
└── node_modules

 

3. gRPC 프로토콜 버퍼 정의 및 서버 구현

프로토콜 버퍼 정의

protos/helloworld.proto 파일을 생성 후 서비스와 메시지를 정의.

Greeter라는 서비스를 정의하고, SayHello라는 RPC 메서드를 제공
SayHello 메서드는 HelloRequest 메시지를 받아 HelloReply 메시지를 반환

// protos/helloworld.proto
syntax = "proto3";

package helloworld;

// 서비스 정의
service Greeter {
  // 단일 RPC
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// 메시지 정의
message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

 

gRPC 서버 구현

server.js 파일에서 gRPC 서버 구현

  • protoLoader.loadSync: 프로토콜 버퍼 파일을 로드하여 서비스 정의 가져오기
  • grpc.Server: gRPC 서버 인스턴스 생성
  • server.addService: gRPC 서비스와 메서드를 서버에 추가
  • SayHello 메서드: 클라이언트 요청을 받아 Hello, <name>! 메시지 반환
// server.js
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const path = require('path');

// 프로토콜 버퍼 파일 경로
const PROTO_PATH = path.join(__dirname, 'protos', 'helloworld.proto');

// 프로토콜 버퍼 파일 로드
const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
  keepCase: true,
  longs: String,
  enums: String,
  defaults: true,
  oneofs: true,
});

const helloProto = grpc.loadPackageDefinition(packageDefinition).helloworld;

// gRPC 서버 설정
const server = new grpc.Server();

// SayHello 메서드 구현
server.addService(helloProto.Greeter.service, {
  SayHello: (call, callback) => {
    const replyMessage = `Hello, ${call.request.name}!`;
    callback(null, { message: replyMessage });
  },
});

// 서버 시작
const port = '50051';
server.bindAsync(`0.0.0.0:${port}`, grpc.ServerCredentials.createInsecure(), () => {
  console.log(`Server running at <http://localhost>:${port}`);
  server.start();
});

 

4. gRPC 클라이언트 구현 및 호출

gRPC 클라이언트 구현

client.js 파일에서 gRPC 클라이언트를 구현하여 서버에 요청 보내기

  • helloProto.Greeter: gRPC 클라이언트를 생성하여 서버에 연결
  • client.SayHello: 서버의 SayHello 메서드를 호출하여 응답 받기
// client.js
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const path = require('path');

// 프로토콜 버퍼 파일 경로
const PROTO_PATH = path.join(__dirname, 'protos', 'helloworld.proto');

// 프로토콜 버퍼 파일 로드
const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
  keepCase: true,
  longs: String,
  enums: String,
  defaults: true,
  oneofs: true,
});

const helloProto = grpc.loadPackageDefinition(packageDefinition).helloworld;

// gRPC 클라이언트 설정
const client = new helloProto.Greeter('localhost:50051', grpc.credentials.createInsecure());

// SayHello 메서드 호출
client.SayHello({ name: 'World' }, (error, response) => {
  if (error) {
    console.error('Error:', error);
    return;
  }
  console.log('Greeting:', response.message);
});

 

클라이언트 실행

node client.js

 

 

5. gRPC를 통한 성능 최적화

HTTP/2와 효율적인 데이터 전송

  • gRPC는 HTTP/2를 기반으로 하여 멀티플렉싱과 헤더 압축 지원
  • 효율적인 데이터 전송과 낮은 대기 시간을 제공

프로토콜 버퍼와 데이터 직렬화

  • gRPC는 프로토콜 버퍼를 사용하여 데이터 직렬화
  • 프로토콜 버퍼는 바이너리 형식으로 데이터를 인코딩하여, 빠르고 효율적인 데이터 전송 가능

스트리밍 지원

  • gRPC는 클라이언트-서버 간의 양방향 스트리밍을 지원하여 실시간 데이터 전송 가능
  • 스트리밍을 통해 대용량 데이터를 효율적으로 처리 가능

로드 밸런싱과 확장성

  • 클라이언트와 서버 간의 통신을 분산하여 로드 밸런싱을 지원
  • 로드 밸런싱을 통해 서비스의 확장성을 높이고, 대규모 애플리케이션에서 효율적으로 부하 관리 가능
  • 여러 서버 인스턴스를 통해 요청을 균등하게 분산시켜 시스템의 가용성 보장

 

이번 포스팅에서는 Node.js와 gRPC를 사용하여 고성능 서비스를 구축하는 방법을 살펴보았습니다. gRPC는 HTTP/2와 프로토콜 버퍼를 활용하여 빠르고 효율적인 RPC 서비스를 제공합니다. 또한, 다양한 언어와 플랫폼을 지원하여 서비스 간의 통합을 쉽게 하고, 높은 성능과 확장성을 제공합니다. gRPC는 특히 마이크로서비스 아키텍처에서 서비스 간의 통신을 표준화하고, 빠르고 안정적인 데이터 전송을 제공하는 데 유리합니다.

반응형