IaC/Service Mesh

gRPC란 무엇인가 — 빠르고 신뢰성 있는 현대적 RPC 프레임워크

Somaz 2025. 7. 17. 09:29
728x90
반응형

Overview

서비스 간 통신은 현대 소프트웨어 아키텍처에서 매우 중요한 요소이다. RESTful API는 여전히 널리 쓰이고 있지만, 더 높은 성능과 명확한 인터페이스 정의가 필요한 마이크로서비스 환경에서는 gRPC가 점점 각광받고 있다.

 

이 글에서는 gRPC의 기본 개념부터 REST와의 차이, 실전 예제, Kubernetes 배포, gRPC-Web 활용, 실제 사용 사례와 장단점까지 정리해보며, gRPC가 어떤 상황에서 효과적인 선택이 될 수 있는지 살펴본다.

 

 

 

 

 


 

 

 

 

 

gRPC란 무엇인가?

gRPC는 Google에서 개발한 오픈소스 RPC (Remote Procedure Call) 프레임워크로, 다음 특징을 가진다.

  • HTTP/2 기반 통신
  • Protocol Buffers(protobuf)를 사용한 인터페이스 정의
  • 다양한 언어 지원 (Go, Java, Python, Node.js, C++, 등)
  • 양방향 스트리밍, unary/bidirectional 통신 지원

 

즉, gRPC는 마치 원격 함수를 호출하는 것처럼 클라이언트-서버 간 통신을 처리하게 해준다.

 

 

 

 

 

REST와의 차이점

항목 REST gRPC
전송 프로토콜 HTTP 1.1 HTTP/2
데이터 포맷 JSON Protocol Buffers
성능 느린 파싱 속도 빠르고 작음
스트리밍 기본적으로 불가능 양방향 스트리밍 지원
브라우저 호환성 좋음 낮음 (gRPC-web 필요)
언어 간 지원 제한적 (직접 작성) protobuf 기반 자동 생성

 

 

 

 

gRPC 구조 요약

gRPC의 기본 구성 요소는 다음과 같다.

  • .proto 파일: 서비스와 메시지 구조 정의
  • gRPC 서버: 정의된 서비스를 실제로 구현
  • gRPC 클라이언트: 자동 생성된 코드로 서버 호출
// hello.proto
service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply);
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

 

 

 

 

 

gRPC의 장점

  • 고성능: protobuf는 JSON보다 작고 빠르다. HTTP/2로 인해 멀티플렉싱과 헤더 압축도 지원
  • 엄격한 타입 시스템: API 계약이 명확하고 자동으로 코드 생성됨
  • 스트리밍: 서버 스트리밍, 클라이언트 스트리밍, 양방향 스트리밍 모두 가능
  • 다양한 언어 지원: 마이크로서비스를 여러 언어로 구현할 때 유용

 

 

 

gRPC의 단점 및 주의점

  • 브라우저 호환성이 낮음 → gRPC-Web 필요
  • 초기 러닝 커브 존재: protobuf, 코드 생성, HTTP/2 설정 등
  • 디버깅 불편: JSON이 아니기 때문에 디버깅과 로그 확인이 불편할 수 있음

 

 

 

도입에 적합한 환경은?

  • 내부 서비스 통신용 API (특히 마이크로서비스 간)
  • 고성능이 중요한 환경 (ML 서빙, 실시간 처리 등)
  • 양방향 통신이 필요한 경우 (채팅, 스트리밍, IoT)

 

반면, 외부 클라이언트(브라우저 포함)와의 API는 REST/GraphQL이 더 편리할 수 있다.

 

 

 

 

 

 

 


 

 

 

 

 

실전 예제: Node.js 기반 gRPC 서버와 클라이언트

 

 

 

 

1. proto 정의 (greet.proto)

syntax = "proto3";

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

 

 

 

2. 서버 코드 (Node.js)

const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const packageDef = protoLoader.loadSync("greet.proto");
const grpcObject = grpc.loadPackageDefinition(packageDef);
const greeter = grpcObject.Greeter;

function sayHello(call, callback) {
  callback(null, { message: `Hello, ${call.request.name}` });
}

const server = new grpc.Server();
server.addService(greeter.service, { SayHello: sayHello });
server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => {
  server.start();
});

 

 

 

 

3. 클라이언트 코드 (Node.js)

const client = new greeter('localhost:50051', grpc.credentials.createInsecure());

client.SayHello({ name: 'Somaz' }, (err, response) => {
  console.log(response.message);
});

 

 

 

 

 

gRPC + Kubernetes 배포

 

 

 

1. Dockerfile 작성

FROM node:18
WORKDIR /app
COPY . .
RUN npm install
CMD ["node", "server.js"]

 

 

 

2. Deployment & Service

apiVersion: apps/v1
kind: Deployment
metadata:
  name: grpc-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grpc
  template:
    metadata:
      labels:
        app: grpc
    spec:
      containers:
      - name: grpc-server
        image: your-registry/grpc-server:latest
        ports:
        - containerPort: 50051

---
apiVersion: v1
kind: Service
metadata:
  name: grpc-service
spec:
  selector:
    app: grpc
  ports:
  - name: grpc
    port: 50051
    targetPort: 50051
  • gRPC 클라이언트는 동일 네트워크에서 `grpc-service:50051` 로 접근 가능

 

 

 

 

gRPC-Web 사용법 (브라우저 클라이언트)

브라우저는 HTTP/2 기반의 바이너리 전송을 직접 지원하지 않기 때문에 gRPC-Web이라는 브리지가 필요하다.

 

 

 

 

1. `envoy.yaml` 설정

static_resources:
  listeners:
    - address:
        socket_address: { address: 0.0.0.0, port_value: 8080 }
      filter_chains:
        - filters:
            - name: envoy.filters.network.http_connection_manager
              typed_config:
                "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                codec_type: AUTO
                stat_prefix: ingress_http
                route_config:
                  name: local_route
                  virtual_hosts:
                    - name: grpc_service
                      domains: ["*"]
                      routes:
                        - match: { prefix: "/" }
                          route: { cluster: grpc_server }
                http_filters:
                  - name: envoy.filters.http.grpc_web
                  - name: envoy.filters.http.router
  clusters:
    - name: grpc_server
      connect_timeout: 0.25s
      type: LOGICAL_DNS
      http2_protocol_options: {}
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: grpc_server
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address: { address: grpc-service, port_value: 50051 }

 

 

 

2. 클라이언트 코드 (gRPC-Web + JavaScript)

import { GreeterClient } from './proto/GreetServiceClientPb';
import { HelloRequest } from './proto/greet_pb';

const client = new GreeterClient('http://localhost:8080');
const request = new HelloRequest();
request.setName("Somaz");

client.sayHello(request, {}, (err, response) => {
  console.log(response.getMessage());
});

 

 

 

 

 

 

 

 


 

 

 

마무리

gRPC는 단순히 “REST보다 빠르다”는 이유만으로 선택해야 하는 기술은 아니다.

명확한 API 정의, 멀티 언어 지원, 고성능 스트리밍 처리가 필요한 내부 마이크로서비스 통신에 특히 효과적인 도구이다.

조금의 학습 곡선을 넘는다면, gRPC는 당신의 분산 시스템을 더 효율적이고 안정적으로 만들어 줄 수 있는 강력한 무기가 될 수 있다.

 

  • gRPC는 REST보다 빠르고, 구조적으로 더 강력하다.
  • Kubernetes 환경에 적합하며, gRPC-Web을 통해 프론트엔드와도 연결 가능하다.
  • 다만 디버깅, 브라우저 호환성 등 고려할 점도 존재한다.

 

 

 

 

 


Reference

 

 

728x90
반응형

'IaC > Service Mesh' 카테고리의 다른 글

Istio 설치 및 실습  (0) 2024.02.13
Istio란?  (0) 2023.04.15
Service Mesh vs Api Gateway  (0) 2023.03.08