rRpc vs Rest 비교


gRPC vs REST 비교

gRPC는 구글에서 개발한 RPC 통신 프로토콜을 말합니다. RPC(Remote Procedure Call) 통신 프로토콜은 원격지의 프로시저를 호출 하는 통신 기술입니다.
오늘은 내부적으로 RestAPI를 활용한 개발을 많이 하고 있으나 gRPC 를 활용 해보면 어떨까? 하는 궁금증을 해소 하기 위해서 성능을 비교해 보고 장단점을 도출 하여 실무에 어떻게 적용 하면 될지 고민 해보도록 하겠습니다.

RestAPI

가장 쉽고 보편적으로 개발 하기 편한 방식 입니다. 오래된 인터페이스이고 Http 1.1 을 사용 하고 있으나 모든 브라우저가 지원을 하고 있고 클라이언트와 서버를 완전 분리하여 개발할 수 있습니다.

  • 장점
    • http 를 활용하여 대부분의 시스템과 통합이 가능
    • 빠르고 쉬운 생산성
    • 직관적인 인터페이스
  • 단점
    • Http1.1 을 사용하여 성능 및 처리에 한계가 있음(실시간, 상태처리…)
    • API 버전 관리

gRPC

gRPC는 고성능, 높은 효율성을 자랑 하지만 사용하기 위해 존재 하는 러닝 커브 및 제약 사항 들이 존재 하기 때문에 잘 판단 하고 사용 해야 합니다.

  • 장점
    • HTTP/2 를 사용하는 고성능 프로토콜 (멀티플랙싱, 헤더압축…)
    • 낮은 네트워크 사용 비용(ProtoBuf)
    • 양방향 스트리밍 지원
    • .proto 파일을 이용하여 인터페이스의 명확한 정의
  • 단점
    • 러닝 커브
    • 브라우저 지원 불가 (내부 통신 처리에만 활용)
    • http2를 지원하는 네트워크 환경 구성 필요

테스트 환경

gRpc Setting

gRpc 를 사용하기 위해서는 Gradle 세팅을 해야 합니다. 관련된 라이브러리를 추가하고 Proto 파일을 빌드 하기 위한 환경을 구성합니다. 자세한 소스는 gRpc 테스트 소스 에서 확인 하시면 됩니다.


buildscript {
    ext {
        protobufVersion = '3.25.1'
        protobufPluginVersion = '0.8.14'
        grpcVersion = '1.58.1'
    }
}
plugins {
    id 'java'
    id 'org.springframework.boot' version '3.3.0'
    id 'io.spring.dependency-management' version '1.1.5'
    id 'com.google.protobuf' version '0.9.4'
}

protobuf {
    protoc {
        artifact = "com.google.protobuf:protoc:${protobufVersion}"
    }
    clean {
        delete generatedFilesBaseDir
    }
    plugins {
        grpc {
            artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}"
        }
    }
    generateProtoTasks {
        all()*.plugins {
            grpc{}
        }
    }
}

// jdk17 javax -> jakarta 로 변경되어 빌드된 rpc 파일의 정보를 변경 해준다. 
task replaceAnnotations {
    description = 'Replace javax.annotation.Generated with jakarta.annotation.Generated'
    group = 'build'

    doLast {
        fileTree(layout.buildDirectory.dir("generated/source/proto/main")).matching {
            include '**/*.java'
        }.each { File file ->
            def text = file.text
            text = text.replace('javax.annotation.Generated', 'jakarta.annotation.Generated')
            file.text = text
        }
    }
}

성능 비교 gRPC VS Rest

  • 테스트 환경
    • 테스트 도구 : jMeter
    • 테스트 방법 : 5000byte 이상의 데이터를 각 구간별로 발송하여 발송 속도, 네트워크 사용량 등을 비교한다.

테스트 결과

테스트 차수 프로토콜 구분 테스트 건수 결과
1차 gRpc 1건 Rpc Test Case1
1차 Rest 1건 Rest Test Case1
2차 gRpc 100건 Rpc Test Case1
2차 Rest 100건 Rest Test Case1
3차 gRpc 1,000건 Rpc Test Case1
3차 Rest 1,000건 Rest Test Case1
4차 gRpc 10,000건 Rpc Test Case1
4차 Rest 10,000건 Rest Test Case1
5차 gRpc 100,000건 Rpc Test Case1
5차 Rest 100,000건 Rest Test Case1
6차 gRpc 500,000건 Rpc Test Case1
6차 Rest 500,000건 Rest Test Case1
7차 gRpc 1,000,000건 Rpc Test Case1
7차 Rest 1,000,000건 Rest Test Case1

결과 분석

  • 성능
    • 전송 용량이 높지 않는 경우 10만건 이상을 발송하여 비교 해도 성능에 이점은 없음. 하지만 용량이 커질수록 성능에 이점이 발생함.
    • 10만건 까지는 유의 미한 성능 차이는 아니 라고 판단됨. 하지만 10만건 이후 부터는 약 20%정도의 성능 향상을 확인. 일 천만건이상 처리 하는 시스템 에서는 굉장한 차이를 볼수 있을 것으로 판단됨.
  • 네트워크 사용량
    • 바이너리 프로토콜을 사용하는 gRpc 에서 엄청난 차이가 발생함. 이는 클라우드 환경 에서의 비용 절감으로 큰 효과를 기대 해볼 수 있음.

고민

  • 아직 까진 저용량의 단발성 이벤트를 처리하는 내부 시스템에서 gRPC 로 어떤 기대를 볼 수 있을까?
    • 하지만 클라우드 환경에서의 네트워크 사용량의 비용 절감은 높음.
  • .proto 파일을 배포 하는 환경을 별도로 구성해야 한다
    • Rest의 경우 클라이언트와 별개로 수정 변경이 가능 하지만 gRpc는 다르다. 동기화 할 수 잇는 환경을 구성 해야 한다.
    • 하지만 .proto 에 데이터가 정의 되어있기 때문에 클라이언트 측에서는 개발이 편리 할 수 있다.
  • 동기 처리를 필요로 하는 대용량 서비스에서는 훌륭한 방법이 될것으로 보임
  • HTTP/2 통신을 하기 위해서는 TLS가 필요한 케이스가 많은데 환경 제약이 있을 수 있다

Back to blog