
데이터 직렬화와 효율적인 통신을 고민하는 개발자라면 한 번쯤 들어봤을 기술이 바로 Protobuf와 gRPC입니다. 고성능 마이크로서비스 아키텍처(MSA)를 구축할 때 필수적인 이 두 개념을 핵심 위주로 정리해 드립니다.
1. Protocol Buffers (Protobuf)란?
Protobuf는 구글에서 개발한 오픈소스 직렬화 데이터 구조입니다. 쉽게 말해, 데이터를 컴퓨터가 이해하기 쉬운 이진(Binary) 형태로 변환하여 전송하는 방식입니다.
주요 특징
- 효율성: XML이나 JSON에 비해 데이터 크기가 훨씬 작고 파싱 속도가 매우 빠릅니다.
- IDL 기반: .proto 파일을 통해 데이터 구조를 정의하며, 이를 바탕으로 다양한 언어(Java, Python, Go 등)의 코드를 생성할 수 있습니다.
- 강력한 타입 체크: 엄격한 데이터 타입을 강제하므로 런타임 오류를 줄일 수 있습니다.
2. gRPC란?
gRPC는 Google Remote Procedure Call의 약자로, 구글에서 개발한 고성능 RPC 프레임워크입니다. 클라이언트가 서버의 함수를 마치 자신의 로컬 함수처럼 직접 호출할 수 있게 해줍니다.
주요 특징
- HTTP/2 활용: 최신 네트워크 표준인 HTTP/2를 기반으로 하여 양방향 스트리밍, 헤더 압축, 멀티플렉싱 등을 지원합니다.
- Protobuf 사용: 기본 인터페이스 정의 언어(IDL)로 Protobuf를 사용하여 성능을 극대화합니다.
- 다양한 통신 패턴: 단순한 요청/응답 구조를 넘어 서버 스트리밍, 클라이언트 스트리밍, 양방향 스트리밍을 모두 지원합니다.
3. 왜 함께 사용하나요?
Protobuf가 '데이터를 어떻게 포장할 것인가'를 담당한다면, gRPC는 '포장된 데이터를 어떻게 효율적으로 주고받을 것인가'를 담당합니다. 이 둘의 조합은 현대적인 백엔드 시스템에서 다음과 같은 이점을 제공합니다.
- 성능: 텍스트 기반의 REST API보다 훨씬 빠른 통신 속도를 자랑합니다.
- 생산성: 다양한 언어를 지원하는 코드 생성 기능을 통해 클라이언트와 서버 간의 계약(Contract)을 명확히 관리할 수 있습니다.
- 확장성: 마이크로서비스 간의 복잡한 통신을 효율적으로 제어할 수 있습니다.

가장 기초적인 서비스 정의와 메시지 구조를 담은 .proto 파일 예시와 이를 어떻게 활용하는지 설명해 드릴게요.
1. 간단한 인사 서비스 정의 (hello.proto)
아래 코드는 사용자 이름을 보내면 인사말을 돌려주는 아주 기본적인 서비스의 정의입니다.
syntax = "proto3";
package hello;
// 요청 메시지 정의
message HelloRequest {
string name = 1;
}
// 응답 메시지 정의
message HelloResponse {
string message = 1;
}
// 서비스 인터페이스 정의
service Greeter {
// 단일 요청, 단일 응답 (Unary RPC)
rpc SayHello (HelloRequest) returns (HelloResponse);
}
2. 코드 설명 및 필드 번호의 의미
- syntax = "proto3": Protobuf의 최신 버전인 3버전 문법을 사용하겠다는 선언입니다.
- message: 데이터의 구조체라고 생각하면 됩니다. 여기서 각 필드 뒤에 붙는 숫자(예: = 1)는 데이터의 순서를 식별하는 고유 번호로, 이진 데이터로 변환할 때 위치를 나타내는 아주 중요한 역할을 합니다.
- service: 실제로 통신할 때 사용할 API 함수들을 정의합니다.
3. 이 파일로 무엇을 하나요?
작성된 .proto 파일은 protoc라는 컴파일러를 통해 각 언어에 맞는 실제 소스 코드로 변환됩니다.
- 코드 생성: protoc를 실행하면 Java, Python, Go 등 원하는 언어로 클라이언트와 서버용 클래스 파일들이 자동 생성됩니다.
- 서버 구현: 생성된 인터페이스를 상속받아 SayHello 함수 안에 실제 비즈니스 로직(예: "Hello, " + name 반환)을 작성합니다.
- 클라이언트 호출: 클라이언트는 복잡한 네트워크 설정 없이 생성된 Stub 객체의 SayHello 메서드를 호출하기만 하면 됩니다.
이번에는 현대적인 웹 개발 스택인 NestJS(서버)와 NuxtJS(클라이언트)를 사용하여 gRPC 통신을 구현하는 구조를 살펴보겠습니다.
1. 서버 구현 (NestJS)
NestJS는 마이크로서비스 패키지를 통해 gRPC를 기본적으로 지원합니다.
메인 설정 (main.ts)
서버가 HTTP가 아닌 gRPC 프로토콜로 동작하도록 설정합니다.
import { NestFactory } from '@nestjs/core';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
import { join } from 'path';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
transport: Transport.GRPC,
options: {
package: 'hello',
protoPath: join(__dirname, './hello.proto'),
url: 'localhost:50051',
},
});
await app.listen();
}
bootstrap();
컨트롤러 (app.controller.ts)
.proto에 정의된 SayHello 서비스를 구현합니다.
import { Controller } from '@nestjs/common';
import { GrpcMethod } from '@nestjs/microservices';
@Controller()
export class AppController {
@GrpcMethod('Greeter', 'SayHello')
sayHello(data: { name: string }) {
return { message: `반갑습니다, ${data.name}님! NestJS 서버입니다.` };
}
}
2. 클라이언트 구현 (NuxtJS)
NuxtJS(Frontend)에서 gRPC 서버와 직접 통신하려면 grpc-web 라이브러리나 서버 사이드 엔진(Nitro)을 거쳐야 합니다. 여기서는 Nuxt 서버 엔진(Nitro)에서 NestJS gRPC 서버로 요청을 보내는 방식을 예로 듭니다.
Nuxt 서버 API (server/api/hello.ts)
클라이언트의 요청을 받아 gRPC 서버로 전달하는 프록시 역할을 수행합니다.
import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';
import { join } from 'path';
const packageDefinition = protoLoader.loadSync(join(process.cwd(), 'hello.proto'));
const helloProto: any = grpc.loadPackageDefinition(packageDefinition).hello;
export default defineEventHandler(async (event) => {
const query = getQuery(event);
const client = new helloProto.Greeter('localhost:50051', grpc.credentials.createInsecure());
// gRPC 호출을 Promise로 변환하여 처리
return new Promise((resolve, reject) => {
client.sayHello({ name: query.name }, (err, response) => {
if (err) reject(err);
else resolve(response);
});
});
});
3. 왜 이렇게 구성하나요?
- 타입 안전성: NestJS와 NuxtJS 모두 TypeScript를 사용하므로, Protobuf로 정의된 타입을 양쪽에서 공유하여 개발 생산성을 높일 수 있습니다.
- 고성능 내부 통신: 사용자에게 보여지는 화면은 NuxtJS가 처리하고, 백엔드 서비스들(MSA) 간의 통신은 gRPC를 통해 오버헤드를 최소화합니다.
- 확장성: 새로운 마이크로서비스가 추가되어도 동일한 .proto 파일만 공유하면 즉시 통신이 가능합니다.
'IT 개발,관리,연동,자동화' 카테고리의 다른 글
| 보험의 탄생부터 결산까지 : ERP (0) | 2026.01.03 |
|---|---|
| 스프링 부트 환경에서 JWT(JSON Web Token)를 사용한 인증 및 인가 시스템을 구축 (0) | 2025.12.27 |
| 영업용 보세화물 관리 시스템 (0) | 2025.12.26 |
| 푸드 빌딩 프로젝트: 스마트 수직픽업 배달 클러스터 기획안 (1) | 2025.12.24 |
| 5성급 호텔을 위한 차세대 ERP 구축 가이드: 혁신과 품격의 완성 (1) | 2025.12.22 |