함수 호출 방법
정적 링킹 (Static Linking)
- 실행 파일 생성 시 필요한 라이브러리를 포함해서 생성한다.
- 컴파일러에 의해 컴파일링 과정을 거친 후 생성된 목적 파일에서 필요한 라이브러리나 다른 목적 파일과 연결하여 하나의 실행 파일을 만드는 과정이다.
- 기계어 파일들(목적 파일)의 크기의 합이 실행 파일의 크기가 된다.
![](https://velog.velcdn.com/images/eunna/post/9dcf7b36-4bcc-4229-aae3-5cf07c4b080e/image.png)
동적 링킹 (Dynamic Linking)
- 실행 파일 안에 라이브러리 코드를 포함하지 않고, 하나의 메모리 공간에 매핑한 후, 여러 프로그램에서 공유하여 사용한다. (디스크 안에 존재하다가 라이브러리를 사용하는 순간에 메모리에 올려서 연결하는 작업을 거침. 사용하고 나면 다시 연결을 해제함.)
- 정적 링킹 방식 대비, 실행 파일 크기가 훨씬 작고, 실행시에도 상 대적으로 적은 메모리를 차지한다.
- 필요한 동적 라이브러리가 없으면 실행할 수 없다.
![](https://velog.velcdn.com/images/eunna/post/e130db50-1c39-4c81-8d51-aec4dffefbf5/image.png)
원격 함수 호출 (RPC; Remote Procedure Call)
- 분산 네트워크 환경에서 원격지 컴퓨터의 함수를 호출한다.
- 컴퓨터를 연결하는 RPC protocol이 필요하다. (사용하는 입장에서는 어떤 원리로 호출되는 지까지 알 필요는 없다.)
- 어플리케이션이 자신의 컴퓨터에서 함수를 호출하도록 하는 경험을 제공하는 stub(속이 빈 함수로 더미 함수라고 생각하면 된다)과 이를 지원하는 IDL(Interface Definition Language)가 필요하다.
gRPC
gRPC Remote Procedure Call (gRPC)
- 개발자 : 구글
- 발표일 : 2016년 8월
- 저장소 : github.com/grpc/grpc
- 프로그래밍 언어 : C#, C++, Dart, Go, Java, Kotlin, Node, Objective-C, PHP, Python, Ruby
- 라이선스 : 아파치 라이선스 2.0
- 웹사이트 : grpc.io
- 특징: HTTP/2 기반(HTTP/2를 사용하면 REST보다는 gRPC를 따름), 프로토콜 버퍼 IDL, 단방향/양방향 스트리밍 지원, 흐름제어/차단/비차단/취소/타임아웃 등 부가 기능 제공
- 주용도 : Microservice architecture, Mobile app - Backend communication
![](https://velog.velcdn.com/images/eunna/post/588b9e38-dd58-47e5-bce4-52a414f6e348/image.png)
gRPC vs REST API (HTTP + JSON)
![](https://velog.velcdn.com/images/eunna/post/a1aef79b-334e-4556-bf39-b9e7f2a589c4/image.png)
gRPC 사용하기
Unary RPC
- 일반 함수 호출처럼 동작하는 간단한 gRPC
- .proto 파일에 선언되어 있는 요청을 서버에 전송하면 서버로부터 응답을 받을 수 있다
- .proto 파일 정의 예제 : rpc RPC함수 이름(요청) returns (응답)
- .proto 파일은 Protocol Buffers 언어 표준을 따른다. (Protocol Buffer에서 사용하는 언어가 존재함)
gRPC 순서
-
원격 호출 함수 작성
-
프로토콜 버퍼 구성 (.proto 파일 작성)
-
gRPC 클래스 자동 생성 - protoc(프로토콜 버퍼 컴파일러)를 사용해 클래스 파일들(메시지 클래스 파일, client/server 클래스 파일) 을 생성한다.
예시)
- hello_grpc_pb2.py : message class 파일
- hello_grpc_pb2.MyNumber : proto 파일의 MyNumber 메시지에 대응하는 코드
- hello_grpc_pb2_grpc.py : client/server class 파일
- hello_grpc_pb2_grpc.MyServiceServicer : proto 파일의 MyService를 제공할 서버용 코드
- hello_grpc_pb2_grpc.MyServiceStub : proto 파일의 MyService를 사용할 클라이언드용 코드
-
gRPC 서버 작성
-
gRPC 클라이언트 작성
참고 ) futures - 비동기적으로 동작하겠다는 것을 의미. gRPC는 thread 기반으로 동작
gRPC 개발 파일 예시
- hello_grpc.py : 원격 호출 대상 파일
- hello_grpc.proto : 프로토버퍼 정의 파일
- hello_grpc_pb2.py : (자동생성) 메시지 클래스 파일
- hello_grpc_pb2_grpc.py : (자동생성) C/S 클래스 파일
- server.py : Server 파일 (원격 호출 대상 파일 지원)
- client.py : Client 파일
Bidirectional Streaming gRPC
- gRPC 클라이언트와 서버 모두 read-write stream을 통해 메시지를 연속적으로 보낼 수 있다.
- 클라이언트가 서버로 보내는 것과 서버가 클라이언트로 보내는 것은 서로 독립적으로 작용한다. 따라서 클라이언트가 계속 서버로 메시지를 보내면서 서버도 계속 응답를 보낼 수 있고, 한 쪽에서 메시지를 계속 보낸 다음에 응답이 쭉 오도록 기다릴 수 있다.
- .proto 파일 정의 예제 : rpc RPC함수 이름(stream request) returns (stream response)
Client Streaming gRPC
- gRPC 클라이언트가 write stream을 통해 연속적으로 메시지를 서버에 보낼 수 있다.
- 모든 메시지들이 서버에 전달되면, 클라이언트는 서버가 메시지를 읽고 응답을 전송해주기를 기다린다. (응답은 하나가 오게 된다)
- .proto 파일 정의 예제 : rpc RPC함수 이름(stream request) returns (response)
Server Streaming gRPC
- gRPC 클라이언트가 .proto 파일에 정의된 메시지를 보내면 서버는 그에 대한 응답으로 메시지를 연속적으로 보낸다.
- 클라이언트는 메시지가 끝날 때까지 계속 연속적으로 메시지들을 읽는다.
- .proto 파일 정의 예제 : rpc RPC함수 이름(request) returns (stream response)
Protocol Buffer (protobuf)
- 데이터를 streaming 방식으로 전송하기 위해서 구글이 개발한 소프트웨어
- 2001년에 개발되어 2008년에 외부에 공개되었다.
- 개발 언어 : C++, C#, Java, Python, JavaScript, Ruby, Go, PHP, Dart // language-neutral
- 언어와 운영체제, 하드웨어에 상관 없이 독립적이고 구조화된 데이터를 위한 메커니즘이다.
- serialization(메모리를 디스크에 저장하거나 네트워크 통신에 사용하기 위한 형식으로 변환하는 것) format, library, IDL(Interface Definition Language) compiler로 사용한다.
- 라이선스 : BSD
- 웹사이트: developers.google.com/protocol-buffers/
Protocol Buffer 기능
- Proto buffer는 구조화된 데이터를 serialize 하기 위해 사용되는 오픈 소스 cross-platform(운영체제의 종류와 무관한) 라이브러리이다.
- 네트워크를 통해 정보를 주고 받거나, 데이터를 저장할 때(운영체제, 개발 언어, 하드웨어와 무관하게 데이터를 열어서 사용할수 있음) 사용할 수 있다.
- Proto compiler는 proto로 개발된 파일을 미리 정해진 언어 규칙에 따라 해석하고 자동으로 파일을 생성해준다.
- Proto 파일과 proto compiler를 통해 운영체제와 개발 언어, 하드웨어와 무관한 데이터를 만들어 사용할 수 있다.
gRPC의 장단점
gRPC 장점
Protobuf (프로토콜 버퍼)
- gRPC 메시지는 binary 메시지 포맷인 Protobuf를 사용한다.
- 개발 언어, 운영체제, 하드웨어와 무관하게 서버와 클라이언트가 정보를 주고 받을 수 있다.
- Binary 형태로(bit 단위) 메시지를 전달하기 때문에 메시지의 크기가 작아서, 모바일과 같은 무선 통신의 환경에서 사용하기에 유리하다.
HTTP/2 기반
- gRPC는 HTTP/2 기반으로 개발되었다.
- HTTP/2는 HTTP 1.1 대비 다음과 같은 장점을 가진다.
- 데이터를 binary 형태로 바꾸고(bit 단위) 압축하는 과정을 거친다. 따라서 HTTP/2 프로토콜은 HTTP 1.1 대비 데이터의 크기가 작기 때문에 네트워크 상에서 부하가 줄어든다.(단, 형태 변형 + 압축 + 압축 해제의 단계가 추가된다)
- 한 개의 TCP 연결을 사용하며 HTTP request의 순서와 response 순서는 무관하다.(request들이 독립적이다)
- HTTP 1.1 : req가 1,2,3이면 res도 1,2,3 순서로 도착해야 한다. 따라서 앞선 요청에 대해 응답을 줘야하는 서버에 문제가 발생하면 뒤의 응답이 먼저 수행되어도 기다려야 한다.
- HTTP/2 : req가 1,2,3이라도 res의 순서는 1,2,3일 필요가 없다. 따라서 앞선 응답을 줘야하는 서버에 문제가 발생하더라도 뒤의 응답이 먼저 수행되면 전송할 수 있다.
- HTTP/2는 gRPC에서만 사용되는 것은 아니다.
(그러나 HTTP/2를 사용하여 서버들 간에 통신을 할 때에는 HTTP를 그대로 사용하기 보다는 gRPC를 사용하는 경우가 많아지고 있다.- HTTP/2에서의 서버간 통신 시 가장 활성화된 케이스)
일반적으로 많이 사용되는 HTTP api를 통해 JSON을 전달하는 등의 request들도 HTTP/2를 사용할 수 있으며, HTTP/2 사용 시 성능 면에서 이점을 가진다.(HTTP 1.1에서 지원하는 모든 request들을 지원)
Code generation
- Proto file : Proto buffer를 사용하기 위해서 gRPC의 service들과 message들을 정의하면, Proto compiler가 자동으로 service base class, message들, client 예제를 만들어 준다.
- .proto file를 서버와 클라이언트가 공유하면?
언어별로 클라이언트 코드와 메시지를 만들 수 있어, 자동으로 생성되는 코드를 활용하면 개발 효율을 높일 수 있다.(개발 생산성 향상)
Strict specification
- REST와 RESTful api에 대한 정확한 명세는 존재하지 않는다.(REST = 철학) 따라서 개발자들 사이에는 REST와 관련하여 의견 차이가 존재할 수 있다.
- gRPC를 사용하기 위해서는 gRPC specification을 따라야 한다.(gRPC는 문법이 존재) 따라서 gRPC 사용법과 관련하여 개발자들 사이 논쟁의 여지가 없다.
Streaming
- gRPC는 모든 streaming 조합을 지원한다
- Unary (no streaming)
- Server to client streaming
- Client to server streaming
- Bi-directional streaming
- 오래 지속되는 실시간 통신 서비스(스트리밍성 서비스)를 개발할 수 있다.
Deadline/timeout & cancellation
- gRPC는 서버에게 요청할 때 클라이언트가 RPC에 대한 대기 시간(클라이언트의 대기 시간)을 지정할 수 있다.
- Deadline 지정 가능 : 클라이언트는 deadline 이내에 응답을 보낼 것을 요청할 수 있다. 요청한 deadline이 지나면 할 액션은 서버가 결정할 수 있다.
참고) gRPC 권장 사용 시나리오
- Microservice : gRPC는 짧은 지연 시간과 높은 처리율을 필요로 하는 서비스를 위해 만들어졌다. 따라서 데이터센터 내 서버 간 통신에서 사용 시 유용하다.
- Point-to-point real-time communication : 일대일 실시간 통신 시 bi-directional streaming을 지원하는 gRPC가 유용하다.
- Polyglot environment : gRPC는 여러 언어들을 지원하기 때문에 multi-language를 사용하는 환경에 유용하다.
- Network constrained environment : gRPC 메시지는 protocol buffer를 사용하기 때문에 크기가 작다.(bit 단위) 따라서 모바일 등의 무선 환경에 유용하다.
- Inter-process communication(IPC) : 동일 컴퓨터 내 프로그램들 사이의 IPC 전송 시 gRPC를 사용할 수 있다.
gRPC의 단점
Limited browser support
- 웹 브라우저에서 gRPC 서비스를 직접 호출할 수는 없다. (사용자가 직접 HTTP 버전을 지정할 수 없으며, 서버 접속 시 우선순위에 따라 버전이 결정된다)
- gRPC를 브라우저에서 사용할 수 있도록 하기 위한 프로젝트들이 진행되고 있다.
Not human readable
- HTTP api request는 문자로 전송되어 사람이 데이터를 읽을 수 있다.
- gRPC는 bit 단위로 데이터가 전송되기 때문에 사람은 데이터를 읽을 수 없다. 따라서 사람이 읽기 위해서는 추가적인 도구가 필요하다.