티스토리 뷰
개요
개념부터 정리하려니 지루한 느낌에 코드부터 바로 들여다보기로 한다.
gRPC 는 원격의 Client 가 Server 단의 함수를 마치 로컬 함수를 호출하듯 부를 수 있게 해주며
이때 보내고 받는 메시지와 서비스를 정의하기 위해 protocol buffers 를 (주로) 사용하며, HTTP/2 위에서 동작한다.
공식 웹페이지의 튜토리얼을 따라하며 golang 으로 간단히 gRPC 를 맛본다.
링크: https://grpc.io/docs/quickstart/go/
설치 사항
1. golang 1.6 이상
2. grpc 설치 go get -u google.golang.org/grpc
3. Protocol Buffers v3 설치
- https://github.com/protocolbuffers/protobuf/releases 에서 자신에 맞는 최신 버전 다운로드 (내 경우는 protoc-3.8.0-win64.zip)
- 그리고, 압축을 푼 다음 어디서든 부를 수 있게 PATH 에 추가 (내 경우는 GOPATH 의 bin, include 에 풀어둠)
4. golang 을 위한 protoc plugin 설치
- go get -u github.com/golang/protobuf/protoc-gen-go
- protoc (compiler) 가 golang 용 코드는 생성해주지 않기에 별도 plugin 설치하는 것으로 보임
만져볼 코드
go get -u google.golang.org/grpc 를 설치하면 example code 까지 있음.
- 우리는 이걸 따라해보고, 이해한 다음 좀 더 개선해볼 것임
일단 닭치고 server 를 실행한 다음, client 를 실행했더니 둘 사이에 뭔가 통신이 이루어진거 같음
- Greeting: Hello world 가 양쪽에 모두 찍힘
기존 코드 따라해보기
기본적으로 제공되는 코드를 - 거의 똑같이 - 따라해보았다.
GitHub: https://github.com/nicewook/grpc-go-quick-start
일단 폴더 구조를 똑같이 만들었다.
mock_helloworld 는 어디쓰는건지 모르겠길래 일단 패쓰
.proto 파일을 만들자.
|
1) proto3 버전을 쓰겠다고 해두고
2) 패키지 명은 higrpc 를 쓰겠다고 해둠
3) grpc 는 결국 원격으로 호출할 수 있는 함수를 만들겠다는 거라고 보면 - SayHi() 라는 함수는 - HiRequest 라는 구조의 메시지를 입력 파라미터로 받아서 - HiReply 라는 구조의 메시지를 리턴해준다는 것
4) HiRequest 메시지는 문자열 name 하나를 가지고 있고, 5) HiReply 메시지는 문자열 message 하나를 가지고 있다.
* name = 1, message = 1 같은건 하나하나의 필드를 구분해주는 태그이며 나중에 인코딩할때에 필드 구분을 위해 쓰인다. 용량 최적화에 좋겠지? |
컴파일
protoc hi.proto --go_out=plugins=grpc:.
- hi.proto 를 컴파일하라는 것 - --go_out 은 golang 코드를 생성하겠다 - --go_out=plugins=grpc 는 grpc 호환코드를 생성한다는 것 - :. 는 현재 폴더(.) 에 생성 하겠다는 것 |
위와같이 hi.proto 를 protoc 로 컴파일하면 hi.pb.go 라는 golang 파일이 생성된다.
서버코드를 만들자
|
우선은 .proto 를 compile 하여 생성한 package 를 import 해야 한다.
pb "github.com/nicewook/grpc-go-quick-start/hi_pb"
main() 함수를 순서대로 따라가보자
1) net.Listen() 함수로 tcp server 하나가 특정 포트를 listen 하게 한다.
2) grpc.NewServer() 를 생성한다음에
3) pb.RegisterHiServer() 함수로 - 생성한 grpc Server 인 s 와 - SayHi() 라는 receiver 를 가지는 type 을 등록해준다. → 이 부분은 아래에 별도 분석
4) s.Serve() 로 tcp listener 인 (l) 로 들어오는 녀석들에게 써비스를 써빙 해주게 한다.
|
자동 생성된 hi.pb.go 파일을 좀 더 들여다보자.
RegisterHiServer()
Hi 라는 네이밍이 어떻게 자동 생성된 건지 모르겠지만 HiRequest, HiReply 에서 자동으로 알아서 유추해낸게 아닌가 싶다.
Hi 는 .proto 에서 service Hi 라는 네이밍에서 비롯되었다.
HiServer 라는 인터페이스가 정의되고, 이건 SayHi 라는 함수가 구현되어 있어야 한다.
RegisterHiServer 라는 함수는
- s 라는 grpc.Server 와 server 와
- srv 라는 HiServer 인터페이스 (= SayHi 라는 receiver 를 가지는 타입) 을 받아서 등록해준다.
여기까지 어지러운 머리속을 정리해보자
1) .proto 를 작성하고 compile 하여 .pb.go 를 생성한다.
- 특정 구조의 메시지를 받아서 처리한 다음, 특정 구조의 메시지를 리턴해주는 함수에 대한 정의라고 보면 된다.
2) Server 프로그램은 우선 net.Listen() 을 통해 tcp 의 특정 port 로 들어오는 놈들을 챙겨들을 수 있게 하고
3) grpc.NewServer() 로 grpc server 를 생성하고
4) RegisterHiServer() 를 통해 grpc server 와 그 server 가 다룰 수 있는 인터페이스 타입을 등록해준다.
5) grpc server 는 net.Listen 으로 들어오는 것을 처리 (=serve) 해준다.
이제 tcp 를 통해 들어오는 놈들 중에서 SayHi() 라는 receiver 를 호출하는 경우
grpc server 가 등록된 SayHi() receiver 를 실행하고 리턴해준다.
참고. context 는 뭐하는 놈인가?
- 링크: https://jaehue.github.io/post/how-to-use-golang-context/
클라이언트 코드를 짜보자
|
1) grpc.Dial() 함수로 server 에게 전화를 걸어 연결한다. - WithInsecure() 로 전송 보안을 disable 해버린다.
2) pb.NewHiClient() 로 그 연결을 담당할 client 를 만든다. - .pb.go 파일에서 New, Client 를 키워드로 찾아보면 있다.
3) context 를 만든다. - context.Background() 를 실행해서 암꺼도 없는 context.Context를 만든 다음에 - 그넘을 부모로 하고, timeout 이 있는 context.Context 를 만든 것이다. - 리턴값은 - context.Context 인 ctx 와 - 언제든 ctx 를 cancel 할 수 있는 cancel() 함수이다.
4) pb.Client 인 c 를 이용해 c.SayHi() 를 실행해준다. - pb.HiRequest 메시지를 파라미터로 넣어 보내고 - ctx 를 넣어줘서 timeout 을 걸어준다
5) r 이 grpc server 로 부터 돌아온 리턴값이다. - 마치 로컬의 함수처럼 호출하고 리턴하는 것이다.
|
함수 하나를 추가해보자.
기존 튜토리얼을 조금 변경해서
client 가 name 을 보내면, 문자열의 길이를 리턴하도록 해보자.
.proto 에 서비스 하나 추가
아래와 같이 입력과 리턴 형식은 똑같은 CountHi() 라는 service 를 하나 추가해 주었다.
그리고 compile
protoc hi.proto --go_out=plugins=grpc:.
Server 는 CountHi() 처리하는 부분을 추가
Client 는 호출하는 부분 추가
실행 결과
서버 먼저 실행 후 아래 클라이언트 실행에 대한 처리
클라이언트 실행
'golang' 카테고리의 다른 글
Maximum Subarray Problem (0) | 2019.06.19 |
---|---|
Concurrent Logging - in Golang (0) | 2019.06.17 |
Protocol Buffers - Golang Tutorial (0) | 2019.06.07 |
Protocol Buffers - overview (1) | 2019.06.06 |
justforfunc #30: The Basics of Protocol Buffers (0) | 2019.06.04 |
- Total
- Today
- Yesterday
- golang
- 인텔리제이
- JIRA
- github
- Gin
- bun
- go
- websocket
- pool
- ChatGPT
- strange
- 독서후기
- 클린 애자일
- 2023
- 노션
- intellij
- 제이펍
- notion
- OpenAI
- 잡학툰
- solid
- postgres
- API
- 영화
- 체호프
- Shortcut
- folklore
- agile
- 독서
- Bug
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |