docs: integrate grpcentity README into unified docs/MANUSCRIPT.md

This commit is contained in:
2026-07-17 13:08:59 +09:00
parent daf90f07d9
commit ab594e4391
2 changed files with 137 additions and 216 deletions
+120 -3
View File
@@ -63,12 +63,129 @@ gRPC의 주요 장점은 다음과 같습니다:
> 이 장점 목록만 보고 gRPC가 모든 문제의 완벽한 해결책이라고 오해해서는 안 됩니다. 항상 현재 작업에 가장 적합한 도구나 기술을 선택하는 것이 중요합니다.
### 4.2 프로토콜 버퍼 (Protobuf)
프로토콜 버퍼(Protobuf)는 구조화된 데이터를 효율적으로 직렬화하는 방법입니다. Protobuf는 IDL(인터페이스 정의 언어)의 일부로, 데이터 교환 시 바이너리 형식을 사용하기 때문에 일반 텍스트 기반 직렬화 형식보다 훨씬 적은 공간을 차지합니다. 하지만 데이터를 기계가 사용하고 사람이 읽을 수 있도록 하려면 각각 인코딩과 디코딩 과정이 필요합니다. Protobuf는 각 프로그래밍 언어에서 기본적으로 지원하는 데이터 타입으로 변환되는 자체 데이터 타입을 제공합니다.
프로토콜 버퍼(Protobuf)는 구조화된 데이터를 효율적으로 직렬화하는 방법입니다. IDL(인터페이스 정의 언어) 역할을 하는 `.proto` 파일을 사용해 통신 규약을 명확히 정의합니다.
일반적으로 IDL 파일은 모든 gRPC 서비스의 핵심입니다. 이는 데이터 교환 형식과 서비스 인터페이스를 정의하기 때문입니다. Protobuf 파일 없이는 gRPC 서비스를 구축할 수 없습니다. 더 정확히 말하면, Protobuf 파일에는 서비스 정의, 서비스 메서드, 그리고 교환될 메시지 형식이 모두 포함됩니다.
#### Protobuf의 주요 장단점
* **장점**
* **높은 전송 효율성**: 데이터 교환 시 텍스트 기반이 아닌 바이너리 형식을 사용하므로 JSON에 비해 데이터 크기가 매우 작고 직렬화/역직렬화 속도가 빠릅니다.
* **강력한 스키마 계약**: 하나의 정의 파일(`.proto`)로부터 다국어 클라이언트/서버 코드를 자동 생성(Stub 코드)하므로 컴파일 단계에서 타입 불일치 에러를 방지할 수 있습니다.
* **하위 호환성 유지**: 필드 번호를 기반으로 직렬화하므로 데이터 스키마가 업데이트되더라도 기존 시스템과의 호환성을 유연하게 보존합니다.
* **단점**
* **사람이 읽기 어려운 가독성 (Binary Format)**: 바이너리 형태로 데이터가 전송되므로, JSON처럼 네트워크 패킷을 사람이 직접 눈으로 확인하거나 텍스트 편집기로 디버깅하기 어렵습니다.
* **빌드 복잡성**: 스펙이 바뀔 때마다 `protoc` 컴파일러와 관련 플러그인을 활용하여 코드를 재생성(Stub 컴파일)해야 하는 추가적인 개발 파이프라인 단계가 필요합니다.
---
## 5. 참고 자료
## 5. 실습: gRPC 기반 서비스 구현 및 컴파일
이 저장소에 기동되어 실행되는 gRPC 예제(`Random` 서비스)의 구체적인 IDL 명세와 컴파일, 그리고 구현 코드를 상세히 분석합니다.
### 5.1 인터페이스 정의 언어(IDL) `protoapi.proto` 분석
우리가 개발할 gRPC 서비스는 다음 기능을 제공합니다:
* 서버는 클라이언트에게 현재 날짜와 시간을 반환해야 합니다.
* 서버는 클라이언트에게 주어진 길이의 무작위 비밀번호를 반환해야 합니다.
* 서버는 클라이언트에게 무작위 정수를 반환해야 합니다.
이 통신 규약은 루트 디렉토리의 [protoapi.proto](file:///home/godopu16/PuKi/lab/canary_projects/grpccanary/protoapi.proto) 파일에 다음과 같이 기술되어 있습니다.
```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;
}
```
* **`syntax = "proto3"`**: 프로토콜 버퍼 언어의 proto3 버전을 활용합니다. 명시하지 않으면 구버전인 proto2로 인식되므로 파일 최상단에 반드시 기술해야 합니다.
* **`option go_package`**: 컴파일 시 Go 코드로 출력될 패키지의 이름을 `protoapi`로 지정하며, 출력 디렉토리를 `./protoapi/`로 명시합니다.
* **`service Random`**: 서버와 클라이언트가 사용할 3가지 RPC 메서드명(`GetDate`, `GetRandom`, `GetRandomPass`)과 해당 메서드들이 수용/반환할 메시지 포맷을 상호 정의합니다.
* **`message` 필드 및 태그**: 각 메시지 필드마다 데이터 타입(예: `int64`, `string`)과 바이너리 인코딩 시 키값 역할을 하는 고유 태그 번호(예: `= 1`, `= 2`)를 부여합니다.
### 5.2 Go에서 IDL 파일 컴파일 및 Stub 생성
`.proto` 정의를 실제 Go 소스 코드로 컴파일하려면 프로토콜 버퍼 컴파일러(`protoc`)와 Go용 플러그인(`protoc-gen-go`, `protoc-gen-go-grpc`)이 로컬 시스템에 설치되어 있어야 합니다.
#### 도구 설치 방법
* **macOS (Homebrew)**:
```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 (Ubuntu/Debian)**:
```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
```
#### 컴파일 실행 명령어
설치 완료 후 리포지토리 루트에서 다음 컴파일 명령어를 수행합니다:
```bash
protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. \
--go-grpc_opt=paths=source_relative protoapi.proto
```
* 이 실행을 통해 `protoapi/` 디렉토리 밑에 메시지 포맷 정의가 담긴 `protoapi.pb.go`와 gRPC 클라이언트/서버 인터페이스 및 메서드 껍데기가 들어있는 `protoapi_grpc.pb.go` 파일이 자동 생성됩니다.
### 5.3 gRPC 서버 구현 ([server.go](file:///home/godopu16/PuKi/lab/canary_projects/grpccanary/examples/grpcentity/server.go))
IDL을 통해 생성된 Go 패키지(`protoapi`)를 가져와 실제 비즈니스 로직을 수행할 gRPC 서버를 구현합니다.
* **구조체 정의**: `RandomServer` 구조체 타입을 선언하고 `protoapi.UnimplementedRandomServer`를 임베딩하여 gRPC 인터페이스 호환을 확보합니다.
* **비즈니스 메서드 구현**:
* **`GetDate`**: 현재 시간 문자열을 반환합니다.
* **`GetRandom`**: 시드값을 기반으로 지정된 위치에 있는 의사 난수를 반환합니다.
* **`GetRandomPass`**: 요청된 시드와 길이 매개변수를 활용해 무작위 비밀번호 문자열을 조립해 반환합니다.
* **서버 기동 (`ServerRun`)**:
* `grpc.NewServer()`로 서버 인스턴스를 확보하고 서비스를 등록합니다.
* 외부 디버깅 도구(예: `grpcurl` 등)가 인터페이스 사양을 동적으로 검색할 수 있도록 `reflection.Register(server)`를 호출해 리플렉션을 활성화합니다.
* `net.Listen("tcp", port)`를 통해 네트워크 채널을 열고 대기 상태(`server.Serve`)를 개시합니다.
### 5.4 gRPC 클라이언트 구현 ([client.go](file:///home/godopu16/PuKi/lab/canary_projects/grpccanary/examples/grpcentity/client.go))
서버에 원격 호출을 요청하고 응답 데이터를 가공해 출력하는 클라이언트 흐름입니다.
* **채널 접속**: `grpc.Dial` 함수를 통해 주소로의 연결 통로를 엽니다. 로컬 테스트 및 통신 단순화를 위해 평문(TLS 미적용) 커넥션(`insecure.NewCredentials()`)을 수립합니다.
* **클라이언트 인스턴스 생성**: `protoapi.NewRandomClient(conn)`를 통해 원격 서비스 호출 인터페이스 객체를 생성합니다.
* **호출 래퍼**: `AskingDateTime`, `AskPass`, `AskRandom` 등의 헬퍼 함수를 통해 실제 RPC 메서드에 요청 파라미터(시드, 길이 등)를 태워 호출합니다.
* **콘솔 출력 (`ClientRun`)**: 최종 수신한 시간, 생성된 무작위 비밀번호, 임의의 난수를 받아 콘솔 표준 출력에 정상 표시해 줍니다.
---
## 6. 참고 자료
* [gRPC와 REST의 차이점 (AWS)](https://aws.amazon.com/ko/compare/the-difference-between-grpc-and-rest/)