gRPC란 Google이 개발한 오픈 소스 원격 프로시저 호출(RPC, Remote Procedure Call) 프레임워크입니다. 이 프레임워크는 서버와 클라이언트 애플리케이션 간의 통신을 간소화하고 효율적이게 만들 수 있습니다. HTTP/2 프로토콜을 사용하며, 언어 중립적인 인터페이스를 갖췄고, 양방향 스트리밍을 지원하고, 인터셉터 지원하는 특징이 있습니다. 이러한 특징으로 마이크로서비스 아키텍처와 모바일 애플리케이션 그리고 실시간 통신이 필요한 애플리케이션에 쓰이기 적합합니다.
gRPC에서는 효율적인 데이터 교환 포맷으로 프로토콜 버퍼를 사용하며, 프로토콜 버퍼 언어로 작성합니다.
프로토콜 버퍼 컴파일러인 'protoc'는 '.proto' 파일에서 정의된 메시지와 서비스 인터페이스를 대상 프로그래밍 언어의 소스 코드로 변환합니다. 이 소스 코드는 gRPC API를 통해 서비스를 구현하고 사용하는 데 필요한 기반을 제공합니다.
윈도우에 설치하기 위해서는 Protocol Buffers Github 페이지에서 바이너리를 다운로드하여 환경 변수에 추가해야 합니다.
protoc는 기본적으로 C++, Java, Python 등의 코드를 생성할 수 있지만, gRPC 서비스를 위해서는 각 언어에 맞는 플러그인이 필요합니다. 이 플러그인들은 protoc와 함께 작동하여 gRPC 메서드에 대한 클라이언트 스텁과 서버 스텁을 생성합니다.
Go에서 사용하기 위해서는 'protoc-gen-go'와 'protoc-gen-go-grpc'플러그인을 설치해야 합니다.
gRPC API의 구현체로, 클라이언트와 서버 애플리케이션에서 네트워크 통신, 데이터 직렬화, 오류 처리 등을 관리합니다.
설치(Go)
go get -u google.golang.org/grpc
// 문법 버전 지정
syntax = "proto3";
// 패키지 이름 (생성될 Go 패키지 등에 영향을 줍니다)
package example;
// 다른 프로토 파일로부터 메시지 타입 임포트
import "other.proto";
// 간단한 메시지 정의, 필드의 이름은 반드시 모두 소문자여야하며, snake_case를 사용합니다.
message Person {
string name = 1; // 필드: 타입, 이름, 태그 순서
int32 id = 2; // 각 필드에는 고유한 태그 번호가 지정됩니다.
string email = 3;
}
// 서비스 정의
service PeopleService {
// RPC 메서드 정의
rpc GetPerson(PersonRequest) returns (PersonResponse);
}
// 요청과 응답 메시지 타입
message PersonRequest {
int32 person_id = 1;
}
message PersonResponse {
Person person = 1;
}
syntax : .proto 파일의 첫 줄에는 사용할 protobuf의 문법 버전을 지정합니다. proto3은 현재 널리 사용되는 버전입니다.
package : 패키지 선언은 이름 충돌을 방지하고, 언어에 따라 네임스페이스나 모듈 등으로 변환됩니다.
import : 다른 프로토콜 버퍼 파일에서 정의된 메시지를 현재 파일에서 사용하기 위해 필요합니다.
message : 데이터 구조를 정의합니다. 각 필드는 타입, 이름, 그리고 태그 번호를 가집니다. 태그 번호는 각 필드를 고유하게 식별하며, 이진 형식에서 필드를 인식하는 데 사용됩니다.
service : 하나 이상의 RPC(원격 프로시저 호출) 메서드를 정의하는 데 사용됩니다. 각 메서드는 입력 타입과 반환 타입을 지정합니다.
.proto 파일 작성 후에 다음과 같은 명령어로 컴파일링할 수 있습니다.
protoc [option] file.proto
Go 코드 생성에 대한 추가 옵션을 사용한 경우 다음 옵션을 사용할 수 있습니다.
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative
test_protoc.proto
명령어 구성
protoc : Protocol Buffers 컴파일러의 실행 파일명입니다. 이 컴파일러는 .proto 파일을 다양한 프로그래밍 언어의 소스 코드로 변환합니다.
--go_out=. : 이 옵션은 프로토콜 버퍼의 메시지 타입을 일반 Go 코드로 변환하여 출력하는 위치를 지정합니다. .은 현재 디렉토리를 의미하므로, 생성된 파일은 현재 작업 중인 디렉토리에 저장됩니다.
--go_opt=paths=source_relative : 이 옵션은 생성된 Go 파일의 import 경로를 설정하는 방법을 지정합니다. source_relative는 소스 파일(.proto)이 위치한 디렉토리를 기준으로 상대 경로를 사용하라는 의미입니다. 이 설정은 모듈 내에서 패키지가 어디에 위치하는지에 대한 구조를 명확하게 유지하는 데 도움이 됩니다.
--go-grpc_out=. : 이 옵션은 gRPC 서비스 정의를 Go 코드로 변환하여 출력하는 위치를 지정합니다. 이 역시 현재 디렉토리에 결과 파일을 저장합니다.
--go-grpc_opt=paths=source_relative : gRPC 서비스를 위해 생성된 Go 파일의 import 경로를 소스 파일이 위치한 디렉토리를 기준으로 상대 경로로 설정하라는 지시입니다. 이는 일관된 디렉토리 구조를 유지하고 프로젝트의 이해를 돕습니다.
test_protoc.proto : 입력 파일로, 이 파일에는 정의된 프로토콜 버퍼 메시지와 gRPC 서비스가 포함되어 있습니다. 컴파일러는 이 파일을 읽어 Go 코드로 변환합니다.
이 파일은 주로 .proto 파일에서 정의된 메시지 구조를 Go 언어의 구조체로 변환한 것을 포함합니다. protoc 컴파일러가 프로토콜 버퍼의 메시지 정의를 해석하여 각 메시지 타입별로 하나의 Go 구조체를 생성합니다.
이 파일에는 다음과 같은 내용이 포함됩니다:
이 파일은 .proto 파일에서 정의된 gRPC 서비스에 대한 Go 코드를 포함합니다. 이 코드는 gRPC 프레임워크를 사용하여 클라이언트와 서버 어플리케이션을 구현할 때 필요한 기반을 제공합니다. _grpc.pb.go 파일에는 다음과 같은 내용이 포함됩니다:
gRPC의 개념부터 시작하기 위한 방법에 대해 간략히 설명해보았습니다.
이후, 서비스 작성부터 서버와 클라이언트 작성, 서버와 클라이언트 테스트를 진행하면 gRPC 애플리케이션이 개발되는 과정은 github에서 마무리 짓겠습니다.
그림 출저 : https://techdozo.dev/grpc-for-microservices-communication