[네트워크] gRPC
세미나에서 했던 내용을 정리해보고자 합니다. 어쨋든 공부를 했으면 정리를 해야 하니 간단히 필요한 내용만 정리해보겠습니다.
gRPC 란?
RPC는 어디서 많이 들어본 얘긴데, g가 붙었습니다. 그렇습니다. google에서 만든 RPC 프레임워크 입니다. 그럼 왜 google에서 RPC 프레임 워크를 만들었을 까요? 이건 이제 프로세스 통신으로 거슬러 올라갑니다.
생각해보면, 프로세스는 서로 통신하기 위해서 IPC 통신을 합니다. 그 중 소켓을 이용한 방법이 있는데 Session Layer에 위치한 이 소켓은 L7에서 L4로 이동하며 TCP/UDP를 이용해 일종에 창구 역할을 수행하며 네트워크 통신을 하도록 도와주게 됩니다.
즉, 목적이와 통신이 로컬 호스트가 아니라 온라인 범위에서 이루어지기 때문에 네트워크간 통신이라고 구분합니다.
그런데 소켓 통신은 해보신분은 알겠지만 대학생때 참 많은 이슈를 가져다 주었습니다. 네,, 직접 Socket API를 구성하고 짜야됩니다. 통신을 하기 위한 인터페이스를 직접 구성해야 합니다.
echo system 으로 한 로컬 컴퓨터에서 client와 server를 통신하는 연습 많이 해보셨을 겁니다.. (눈물나..)
아무튼 그래서 RPC라는 개념이 등장하게 됩니다.
RPC는 별게 아니고 일종에 통신을 하기 위한 규약을 하나 지정해놓고 그걸 인터페이스로 구성해 통신을 하는 방법입니다. 이게 무슨 말이냐면,
일단 RPC라는 의미가 Remote Procedure Call의 약자입니다. 원격의 프로시저를 호출하겠다 의미인데요 사실 프로시저는 함수, 메서드 등을 의미하는 것입니다.
그래서 내가 통신을 하면서 원격에 있는 (보통 이것이 서버가 되겠죠?) 함수, 메서드같은 것들을 불러와 사용하겠다는 겁니다. (RPC runtime을 통해서요)
구체적으로 얘기해보면 IDL 파일을 IDL 컴파일러가 컴파일 해서 stub을 각각 client 와 server에 빌드해줘서 서로 통신을 할 수 있도록 도와주는것입니다.
그래서 이 멋진 RPC를 쓸려고 했는데!
구현이 어려웠습니다. 실제로 이를 구현체인 CORBA, RMI 같은것들이 있었음에도 불구하고 구현하기 어려웠기 때문에 널리 사용되지 못했다고 하네요.
그럼 이제 gRPC 얘기로 돌아와서
gRPC ?? 다시 생각해보자!
gRPC를 이해해 볼려면 사실 웹 통신 방법에 대해 이해하고 있으면 완벽하게 어떤 동작을 구현하고 있는지 살펴볼 수 있습니다.
자자, 우리는 많은 언어와 프레임워크를 다룰 수 있는 사람입니다.
그런데 웹앱 서비스를 구현하고자 했을 때 추천 서비스, 동영상 서비스, 광고 플랫폼 서비스, 유저 랭킹 서비스 등 다양한 서비스들을 성능에 맞추어 언어와 프레임워크를 선택해줄 가능성이 굉장히 농후합니다.
그럼 이게 각 서버가 되고 이 서버들 끼리는 서로 통신을 수행해야 합니다. 이럴 때 gRPC를 사용하게 됩니다.(물론, REST 나 Gql 이 안된다는 건 아닙니다. 여기서 gRPC를 공부하려고 하는것이기 때문에 메인으로 지정한것이죠!!)
어디서 많이 보지 않았나요? 네 이게 바로 MSA, 마이크로 서비스 아키텍처가 되는것 입니다.
대강 그림으로 그려보면 이런 구조겠습니다!
Netflix
영화만 볼줄 알았지 서비스에 대해 관심이 없었던 저는 넷플릭스가 gRPC를 이용하고 있는 기업이라는거에 두번 놀랐습니다.
무튼 굉장히 유명한 IT 회사들이 이러한 아키텍처와 통신 방법을 도입하고 있다고 하네요.
gRPC 통신방법
gRPC 는 기본적으로 통신을 할 때 proto file 안에 protocol buffer를 지정해서 시리얼라이제이션을 하여 바이트 스트림으로 내보내게 됩니다. 이때문에 JSON으로 보내는 text 형식하고는 차원이 다르게 압축되어 빠른 성능을 보여주고 있습니다.
이게 무슨 말이냐면,
proto file을 만들어 줍니다. (proto file의 역할은 client와 server가 서로 통신을 하기 위한 인터페이스다 라고 이해해주시면 될것 같습니다.)
앗 그전에 여기 예제는 기본적인 Unary를 염두하고 작성한 것입니다. Unary 는 Single Request에 Single Response 입니다!
아래 보면 response는 빠졌지만
그냥 단순하게 요청을 보내고 응답을 받는 구조 입니다(service로 지정한 부분에 구현)
그리고 testRequest 부분에서 보면 이게 이제 protocol buffer가 되는 것이지요! (protocol buffer, **protobuf 이라고 많이 쓰더라구요 밑에서는 좀 줄여서 사용하겠습니다. )
message testRequest{
string message = 1; //#1 정의된 Request Protocol Buffer
}
service testService{
rpc getTest(testRequest) returns (testResponse); //#2 testRequest에 따라 testResponse 메시지를 보내줍니다.
}
어쨋든, Protocol Buffer로 정의된 데이터를 시리얼라이제이션을 해서 이처럼 Proto Request, Proto Response로 데이터가 Client단에서 Server단, Server단에서 Client단으로 오고 가게 됩니다.
그리고 이는 모두 Proto file에 정의되게 됩니다.
결과적으로 보면 우리는 아래 그림을 만들어주고 싶은 겁니다.
어머나 C++ 서버와 Python Client가 서로 통신을 할 수 있다.
이게 단순히 서버 하나라서 그렇지 서버2개, 3개 멀티 서버일 때 언어와 프레임워크 서로 다른 상태에서 통신한다는것은 정말 멋진일입니다!
아래 그림을 조금 해석해보면 proto file로 *.cpp, *.h / *.py를 만들어서 각 서버와 클라이언트에 이를 import 해서 사용한다! 이렇게 이해해주시면 될것 같습니다.
설마 Go.. 도 지원되나!?
한번 슥 보니 Go도 있네요 ㅎㅎ
gRPC가 Official 하게 support 하는 언어들 입니다.
실습
아래 링크 따라 들어가셔서 한번 해보면 어떤 느낌인지 팍 감을 잡을 수 있습니다.
Spring Boot + gRPC : https://medium.com/swlh/google-cloud-run-service-with-grpc-using-spring-boot-e43daf155752?source=search_post---------2
그리고 질문에 대한 Q&A
기존 REST API 로 구현하고 있던 기업이 gRPC로 옮겨올때 한꺼번에 옮길 수는 없고, 신규 서비스를 gRPC로 도입하는 등의 절차를 밞을 것 같은데요. 기존 REST API와 gRPC간 호환은 어떻게 구축하면 좋을지 궁금합니다.
안녕하세요. 좋은 질문 남겨주셔서 감사드립니다.
이 부분에 대한 구체적인 내용은 https://grpc.io/blog/yikyak/ 문서상에 있는 내용을 가지고 왔습니다. 우선은 질문 주신 것처럼 한번에 gRPC로 옮겨갈 수 없는 것으로 보입니다. 여기에 grpc-gateway를 사용하여 기존의 RESTful, JSON API를 gRPC로 변환하는 reverse-proxy를 생성한다고 합니다. 결국에는 HTTP+JSON 인터페이스를 gRPC 서비스에 제공하는것을 의미합니다.
(출처 : https://github.com/grpc-ecosystem/grpc-gateway)
이를 처리하기 위해서는 protobuf의 gRPC 정의에 사용자 지정 옵션을 추가(stub을 생성하는데 generate_unbound_methods 옵션을 제공해줘야 한다고 합니다.)해야 하고 reverse-proxy를 실행하는 컨테이너를 추가해야 합니다. (github -- readme에 포함된 내용입니다.)
그래서 정리해보면 gRPC로 마이그레이션하는 과정은 다음과 같습니다.
- 작업을 수행하는데 build & deployment pipeline은 수정하지 않습니다.
- 점진적으로 gRPC 로 모든 통신을 migration을 수행합니다. 이 과정에서 기존에 client는 REST를 통해서 서버와 통신을 주고 받습니다. (migration이 끝날 때까지)
- 만일 REST 마이크로 서비스가 존재하는 경우에 default endpoint를 상속받습니다. (왜냐하면, REST 마이크로 서비스와 마찬가지로 gRPC로 migration을 수행한다 하더라도 기본이 되는 플랫폼은 변경되지 않기 때문입니다.)
최종적으로는 위와 같은 아키텍처를 가질 수가 있습니다. (REST 프레임워크를 사용하는 애플리케이션에서 gRPC 서버로 스레드가 실행됩니다.)
또, gRPC로 migration을 수행하는데 주의해야 될것이 있으니 참고부탁드립니다.
- 브라우저 지원이 되는지 확인
- 최근까지 gRPC는 브라우저를 지원하지 않았습니다. 이와 관련해 grpc-web 을 이용하는 방법이 있습니다.
- protobuf 제한
- 존재하지 않는 필드 이거나 null값이 있을 경우 proto3 을 사용하게 되면 이러한 차이를 쉽게 식별할 수 있습니다. 이 경우 Google Wrapper 를 사용하여 확인합니다.
- gRPC 및 HTTP 프레임워크
- REST 프레임워크를 사용하여 작성된 마이크로 서비스는 request handler가 HTTP stack의 일부이며 auth, request/response logging, trace metric 등과 같은 Middleware를 실행할 수 있는 기능이 존재해야 합니다.
- 비슷하지만 서로 다른 protobuf 버전 확인
- Proto2 와 Proto3 의 버전은 비슷하지만 서로 다른 차이가 있으니 확인하여야 합니다.
(참고 : https://wecode.wepay.com/posts/migrating-apis-from-rest-to-grpc-at-wepay )
gRPC는 두고두고 계속 봐야할것 같다. 다음에 이스티오랑 gRPC 연동에 대해 공부해 보고 싶다..
읽었던 문서들
(1) gRPC 에도 Contract API를 구성하기 위한 방법이 있을까?(Swagger/OpenAPI 처럼) https://medium.com/@ivangsa/consumer-driven-contract-testing-for-grpc-pact-io-d60155d21c4c
(2) 기존 서버가 REST를 사용하고 있는 gRPC로 Migration 할 수 있는 방법은!?
https://wecode.wepay.com/posts/migrating-apis-from-rest-to-grpc-at-wepay
https://docs.microsoft.com/ko-kr/aspnet/core/grpc/comparison?view=aspnetcore-5.0
(.Net 한정)
(3) gRPC-Gateway를 이용해 reverse-proxy를 만들어주면 API Client에서 gRPC로 Migration 할수 있다
https://github.com/grpc-ecosystem/grpc-gateway
(4) gRPC vs REST 누가 더 좋아?!
https://www.vinsguru.com/grpc-vs-rest-performance-comparison/
(4) goLang으로 gRPC 구현해보자!
https://devjin-blog.com/golang-grpc-server-1/
(5) 시리얼라이제이션 된 코드를 어떻게 읽을 수 있지? (리플렉스, gRPC 명령줄)
https://github.com/grpc/grpc/blob/master/doc/server-reflection.md
https://github.com/grpc/grpc/blob/master/doc/command_line_tool.md
(6) gRPC-web 사용하는 방법 (브라우저가 지원을 안해줘...)
https://github.com/grpc/grpc-web
(7) gRPC Concept
https://vrushaliraut1234.medium.com/grpc-concepts-with-example-b37a028470dd
https://grpc.io/docs/what-is-grpc/core-concepts/
(8) gRPC Proxy model
https://github.com/grpc/grpc/blob/master/doc/load-balancing.md
(9) gRPC
https://chacha95.github.io/2020-06-15-gRPC1/
'IT' 카테고리의 다른 글
AWS 게임대회 후기 (0) | 2021.10.07 |
---|---|
CORS 해결하기 (0) | 2021.09.01 |
코드 리뷰 하기 (0) | 2021.06.01 |
프로그래머스 : JOIN (0) | 2020.10.07 |
IT10 :: 프로젝트 유지보수 (0) | 2020.10.02 |
댓글
이 글 공유하기
다른 글
-
AWS 게임대회 후기
AWS 게임대회 후기
2021.10.07 -
CORS 해결하기
CORS 해결하기
2021.09.01 -
코드 리뷰 하기
코드 리뷰 하기
2021.06.01 -
프로그래머스 : JOIN
프로그래머스 : JOIN
2020.10.07