코기판

gRPC란 무엇인가? (gRPC 시리즈 #1) 본문

Infra

gRPC란 무엇인가? (gRPC 시리즈 #1)

신코기 2019. 4. 21. 22:12

최근 회사와는 별개로 구현해보려고 하는 개인 프로젝트가 있습니다.
머신 러닝을 이용한 챗봇 형태의 프로젝트이고, backend 서버는 golang,
그리고 각각의 모듈은 python 으로 구성하려고 합니다. 

그림으로 표현해보면 간략하게나마 다음과 같이 표현할 수 있겠네요 .


그러다보니 자연스럽게 golang server와 python client가 어떻게 통신할 것인지에 대해 고민하게 되었습니다. 
또한 다른 언어로 된 클라이언트들이 생길 수 있으므로 확장성을 고려한 연결이었으면 좋겠다고 생각했습니다.
가급적 빠르고, 구현도 쉽다면 더 좋겠죠 ??
개발자들은 해야 할 일이 아주 많으니까요 ㅠㅠ

여러 가지 요구사항을 대강 생각만 해 두고 검색을 해 보니, gRPC를 쓰라는 답변을 발견했습니다.

마침 회사에서 진행하는 프로젝트에서도 grpc를 이용해 backend 서비스들을 엮었다고 주워들어서, grpc를 활용하면 
아주 가까이서 도움을 받을 수 있을 것 같기도 합니다! 
게다가 얼마 전 참석한 AWS Summit Seoul 2019에서도 best practice 세션에서 gRPC이야기가 심심치 않게 들리는 것을 보니 이제 gRPC connection이 거의 스탠다드가 된 것이 아닌가, 하는 생각이 들더군요.
사용해보지 않을 이유가 없네요.

일단 직접 사용해본 후기는, 구현도 굉장히 쉬운 편이고 빨랐습니다. 
찝찝할 정도로 편하더군요 !! 
구글이 이런 것 까지 쉽고 빠르게 만들어두다니,

이제는 정말 고오급 개발자가 아니면 살아남기 쉽지 않을 것 같다는 생각도 들었습니다 ㅠㅠ

다만 다행인 것은 연결 상에서 error handling에 대한 부분은 조금 더 개발자의 노력이 들어가야 할 것 같습니다 ^^

앞으로 제가 구현하는 프로젝트 진행과 함께 몇 차례에 걸쳐 grpc에 대한 내용을 다루려고 합니다. 
1. grpc overview
2. protobuffer overview
3. grpc (golang) 구현 및 k8s에 적용
4. grpc error handling

정도로 목차를 구성하고 있어요. 

필요한 것이 있을 때 더 추가하려고 합니다. 
그리고 저는 golang을 사용할 예정이기 때문에, 아무래도 예제는 golang 위주로 작성될 것 같습니다.

gRPC를 마스터해서 줄줄 소개한다기 보다는,

스스로 공부하며 잊지 않게 기록해두는 메모 정도로 봐주시면 감사하겠습니다. 
토론할 만한 주제나, 보완이 필요한 부분에 대해서는 언제든지 댓글 남겨주세요 !



그래서 도대체 gRPC는 뭘까요 ??


아마 gRPC가 아닌 RPC에 대해서는 들어본 분들이 있을 겁니다. 

네트워크 디테일에 대해서 몰라도, 마치 local 함수를 호출하는 수준 정도로 
다른 컴퓨터에 존재하는 프로그램 내의 함수, 혹은 프로시저를 호출할 수 있도록 하는 프로세스 간 통신 기술입니다.

여기서, 그럼 소켓과 RPC가 어떻게 다른지 궁금하신 분들이 있을 것 같은데요,
요 링크에서 그 차이점을 잘 설명해주고 있네요.

말하자면 소켓은 아파트의 주소와 같은 유니크한 값을 가지고 있고,

RPC는 이런 종류의 택배를 배달해주세요 ~ 와 같이 상황에 대한 정의라고 할 수 있습니다. 

소켓이 특정한 주소를 가지고 있기 때문에, RPC가 택배를 배송할 때 소켓 연결을 이용할 수 있겠지요.


사실 HTTP가 들어오며, REST API를 많이 사용하게 되다보니 RPC의 인기가 훅 식었다고 합니다. 
하지만 HTTP를 이용한 REST API에서 몇몇 고질적인 문제가 있어서 (너무 느리다거나,, 오류가 많다거나,,) 
이를 보완하기 위해 Google에서 HTTP2를 붙여, RPC형태로 릴리즈한 것이 바로 gRPC입니다. 
Google에서는 원래 stubby라는 internal RPC를 사용하고 있었는데, 그것이 진화해서 gRPC로 릴리즈 되었다 합니다. 

 

gRPC의 request와 response는 gRPC서버와 gRPC클라이언트 사이를 오갑니다.

gRPC req/res

주목할만한 것은, 서버와 클라이언트로 나뉘어 있고, 

서버와 클라이언트는 어떤 language인지에 구애받지 않고, 자유롭게 통신할 수 있다는 것입니다. 

이것이 가능힌 이유는, 서비스로 IDL을 명시하고 그 IDL을 기반으로 자동 생성된 코드로 서로 통신이 이루어지기 때문입니다.

 

서비스나 오고 가는 메세지에 대한 IDL은 protobuffer라는 포맷으로 정의합니다.

이 때 type체크를 하게 되어 오류의 여지가 줄어듭니다.
protobuffer(PB)는 structured datad를 serialize하는 일종의 프로토콜입니다.

말하자면 XML 같은 녀석인데, XML보다 빠르다는 특징을 가지고 있습니다. 

생긴 모양은 다음 코드와 같은데요, 확실히 보기에도 간단해 보이죠?

message Person {
  string name = 1;
  int32 id = 2;
}

PB에 대한 이야기는 다음 포스팅에서 더 자세히 다루도록 하고,

일단 이번 포스팅에서는 저런 모양으로 생겼구나~ 정도로 봐 주세요.

 

서비스에 대해서 정의를 하고 나면,

google에서 제공하는 오픈 소스 툴중 하나인 protoc를 이용해 data access 클래스 코드들을 빌드합니다.

아래 예제는 golang으로 class data acess 코드가 생성된 예제입니다.

type Customer struct {
        Name            	 string   `protobuf:"bytes,2,opt,name=name,json=Name,proto3" json:"name,omitempty"`
        Id                   int32    `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
        XXX_NoUnkeyedLiteral struct{} `json:"-"`
        XXX_unrecognized     []byte   `json:"-"`
        XXX_sizecache        int32    `json:"-"`
}

func (m *Customer) GetId() int32 { ... }

func (m *Customer) GetName() string { ... }

 

protoc를 거쳐서 빌드를 하게 되면, server code 뿐 아니라 client stub 코드도 생성되게 됩니다. 

golang의 경우 grpc를 호출할 수 있는 모듈을 별도로 제공하고 있어서, 

server에서 client stub을 호출할 때, 간단히 grpc 모듈의 Dial함수를 이용하면 됩니다. 

 


요약하자면, gRPC사용하는 순서는 다음과 같습니다. 
1. go를 사용하신다면, 필요한 module들을 go get으로 내려받습니다.

(go가 아니라, 다른 언어를 사용할 때도, 필요한 모듈들을 확인해 내려받습니다.)

2. 필요한 service에 대해 정의를 해줍니다.  (요때 이용되는 것이 protobuffer입니다.)
3. protoc 툴을 이용해 정의한 서비스에 대해 server/client코드를 생성합니다. 
4 서버에서 부분에서 grpc.Dial API로 서비스를 호출해 줍니다.

gRPC를 사용해 본 느낌은, 구현도 실행에서도 상당히 빠른 느낌입니다.

다양한 언어에서 사용할 수 있는 것도 상당히 큰 장점인 것 같구요. 

다만 gRPC 클라이언트가 죽어버린다거나 하면, 서비스를 다시 살리는데 시간이 걸려서 그 부분은 조금 더 공부를 해봐야 할 것 같습니다.

 

gRPC 구현 상세에 대해서는 세번째 포스팅 정도에서 다루게 될 것 같아요!

혹시 제가 놓치고 있는 부분이나, 보완이 필요한 부분은 언제든 댓글 환영입니다 !

 

 


refences : 
https://grpc.io/docs/quickstart/go.html
https://grpc.io/docs/tutorials/basic/go.html
https://en.wikipedia.org/wiki/Remote_procedure_call
https://bcho.tistory.com/1011
https://www.quora.com/What-is-the-difference-between-socket-and-rpc

Comments