docs: split MANUSCRIPT.md into distinct JSON, HTTP, and GRPC documents
This commit is contained in:
+131
@@ -0,0 +1,131 @@
|
||||
# gRPC & Protocol Buffers 심화 학습
|
||||
|
||||
이 문서는 `grpccanary` 프로젝트의 **3단계: gRPC 통신 구현**에 대한 이론적 배경, 스키마 명세, 컴파일 기법 및 구체적인 소스코드 분석을 설명합니다.
|
||||
|
||||
gRPC는 HTTP/2를 기반으로 구축된 구글의 고성능 오픈소스 원격 프로시저 호출(RPC) 시스템입니다. 사물인터넷(IoT) 장비나 에이전트 간의 데이터 통신 시 가볍고 구조화된 데이터 통신을 유지하는 데에 가장 적합한 프레임워크입니다.
|
||||
|
||||
---
|
||||
|
||||
## 1. gRPC 개요 및 기술 배경
|
||||
|
||||
### 1.1 gRPC의 핵심 차별점
|
||||
* **강력한 스키마 계약**: `.proto` 파일 하나로 서비스 통신 규약을 명확히 선언하고, 컴파일 단계에서 이를 바탕으로 여러 언어의 클라이언트/서버 코드를 자동 생성합니다. 따라서 런타임 단계에서의 통신 필드 누락이나 타입 불일치 버그를 완벽하게 방지합니다.
|
||||
* **이진 프로토콜 (바이너리 포맷)**: 텍스트가 아닌 컴팩트한 이진 형식을 사용하므로 데이터 크기가 매우 작고 네트워크 대역폭 리소스 효율이 뛰어납니다.
|
||||
* **HTTP/2 기반**: 하나의 네트워크 커넥션을 재사용해 다중화(Multiplexing) 전송이 가능하고, 실시간 스트리밍(양방향 스트리밍 포함) 서비스에 탁월한 환경을 제공합니다.
|
||||
|
||||
### 1.2 Protobuf (프로토콜 버퍼)의 장단점
|
||||
|
||||
* **장점**
|
||||
* **높은 전송 효율성**: 데이터 교환 시 텍스트가 아닌 바이너리 인코딩 형식을 사용하므로 JSON에 비해 직렬화/역직렬화 속도가 매우 빠르고 크기도 가볍습니다.
|
||||
* **일관성 있는 코드 생성 (Stub)**: 동일한 정의서로부터 다국어 API 클라이언트를 빌드하여 중복 작성 오버헤드를 획득합니다.
|
||||
* **하위 호환성**: 고유 필드 번호 매핑 방식을 사용하므로 스키마가 개정되어도 이전 시스템과의 통신 호환을 보장합니다.
|
||||
|
||||
* **단점**
|
||||
* **가독성 부재**: 패킷이 암호화는 아니지만 바이너리로 전달되므로 사람이 브라우저 개발자 도구 등으로 바로 읽어 디버깅하기 곤란합니다.
|
||||
* **빌드 종속성**: 명세 변경 시마다 Stub 코드를 컴파일하여 빌드에 바인딩하는 과정이 요구됩니다.
|
||||
|
||||
---
|
||||
|
||||
## 2. 인터페이스 명세서 (`protoapi.proto`)
|
||||
|
||||
저장소 루트의 [protoapi.proto](file:///home/godopu16/PuKi/lab/canary_projects/grpccanary/protoapi.proto) 파일은 의사 난수, 비밀번호, 날짜 데이터를 교환하는 `Random` 서비스를 제공하기 위해 아래와 같이 사양을 선언해 둡니다.
|
||||
|
||||
```proto
|
||||
syntax = "proto3";
|
||||
|
||||
option go_package = "./protoapi/;protoapi";
|
||||
|
||||
service Random {
|
||||
rpc GetDate (RequestDateTime) returns (DateTime);
|
||||
rpc GetRandom (RandomParams) returns (RandomInt);
|
||||
rpc GetRandomPass (RequestPass) returns (RandomPass);
|
||||
}
|
||||
|
||||
message RandomParams {
|
||||
int64 Seed = 1;
|
||||
int64 Place = 2;
|
||||
}
|
||||
|
||||
message RandomInt {
|
||||
int64 Value = 1;
|
||||
}
|
||||
|
||||
message DateTime {
|
||||
string Value = 1;
|
||||
}
|
||||
|
||||
message RequestDateTime {
|
||||
string Value = 2;
|
||||
}
|
||||
|
||||
message RequestPass {
|
||||
int64 Seed = 1;
|
||||
int64 Length = 8;
|
||||
}
|
||||
|
||||
message RandomPass {
|
||||
string Password = 1;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Go Stub 컴파일 및 도구 체인
|
||||
|
||||
`.proto` 파일을 Go 파일로 출력하기 위해 프로토콜 버퍼 컴파일러(`protoc`)와 플러그인이 로컬에 갖추어져야 합니다.
|
||||
|
||||
### 3.1 OS별 설치 가이드
|
||||
* **macOS**:
|
||||
```bash
|
||||
brew install protobuf
|
||||
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
|
||||
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
|
||||
```
|
||||
* **Linux**:
|
||||
```bash
|
||||
sudo apt install -y protobuf-compiler
|
||||
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
|
||||
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
|
||||
```
|
||||
|
||||
### 3.2 컴파일 실행 명령어
|
||||
```bash
|
||||
protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. \
|
||||
--go-grpc_opt=paths=source_relative protoapi.proto
|
||||
```
|
||||
실행 결과로 `protoapi/` 아래에 `protoapi.pb.go`(메시지 정의)와 `protoapi_grpc.pb.go`(인터페이스 및 원격 호출)가 자동 생성됩니다.
|
||||
|
||||
---
|
||||
|
||||
## 4. 실습 코드 구현 상세 분석
|
||||
|
||||
### 4.1 gRPC 서버 구현 ([server.go](file:///home/godopu16/PuKi/lab/canary_projects/grpccanary/examples/grpcentity/server.go))
|
||||
|
||||
* **구조체 정의**:
|
||||
```go
|
||||
type RandomServer struct {
|
||||
protoapi.UnimplementedRandomServer
|
||||
}
|
||||
```
|
||||
`UnimplementedRandomServer`를 임베딩하여, 향후 메서드가 새로 추가되더라도 기존 서버가 빌드 에러 없이 최소한의 호환( unimplemented 에러 응답 )을 가지게 강제합니다.
|
||||
* **서버 기동 흐름**:
|
||||
```go
|
||||
server := grpc.NewServer()
|
||||
var randomServer RandomServer
|
||||
protoapi.RegisterRandomServer(server, randomServer)
|
||||
reflection.Register(server) // grpcurl 등 외부 디버깅 목적
|
||||
listen, _ := net.Listen("tcp", port)
|
||||
server.Serve(listen)
|
||||
```
|
||||
|
||||
### 4.2 gRPC 클라이언트 구현 ([client.go](file:///home/godopu16/PuKi/lab/canary_projects/grpccanary/examples/grpcentity/client.go))
|
||||
|
||||
* **연결 수립**:
|
||||
```go
|
||||
conn, _ := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
defer conn.Close()
|
||||
client := protoapi.NewRandomClient(conn)
|
||||
```
|
||||
`insecure.NewCredentials()`를 전달하여 TLS를 건너뛴 채 평문으로 빠르고 간단한 로컬 테스트 환경을 구축합니다.
|
||||
* **원격 호출**:
|
||||
`client.GetDate()`, `client.GetRandom()`, `client.GetRandomPass()`를 차례로 호출하여 매개변수와 결과를 콘솔로 확인합니다.
|
||||
Reference in New Issue
Block a user