티스토리 뷰

쓰레드랑 다르게 서로 다른 프로세스는 기본적으로는 겹치는 address space도 없고 완전히 독자적이다.

서로 다른 프로세스의 함수를 호출할 수 없고, 메모리에 접근할 수 없다. 

 

메모장 프로세스와 크롬 브라우저가 서로 완전 노터치 하듯이 심지어 fork로 생성한 부모-자식 프로세스 사이도 그러하다.

따라서 다른 프로세스가 협업을 하기 위해서는 IPC 구현체를 이용해야 한다.

(프로세스들 간에 데이터 및 정보를 주고받기 위한 메커니즘. 커널에서 시스템 콜의 형태로 프로세스에게 제공된다.)

 

IPC 부분 참고한 강의

 

IPC 두가지 모델

(1) 메모리 공유 (shared memory)

서로 다른 프로세스가 함께 접근할 수 있는 메모리 영역을 설정해 줌.

공유 메모리 설정 이후에는 커널이 관여하지 않음. 그 이후의 통신은 프로세스끼리 알아서..( 공유 메모리 설정은 시스템 콜을 통해서 )

read, write방식. 같은 address space를 접근하는 것을 전제로 함.

동기화에 대한 컨트롤 개발자가 직접 해야함. -> 보통 스레드에서 일어나는 동기화 이슈 발생 가능성. -> 세마포어, 뮤텍스, 락 도입.

tensorflow 같은 인공지능 라이브러리 내부를 까보면 이렇게 shared memory 방식의 IPC를 통해 여러 프로세스가 계산에 참여하도록 짜여 있다고 함.

DB, 빅데이터 처리에도 공유 메모리 방식을 많이 이용.

 

(2) 메세지 교환 (message passing)

프로토콜이 필요 ( 메세지 해석방식, 주고 받는 패턴에 대한 규약 )

메세지가 커널을 거쳐서 전달 됨. (송신자 - 시스템 콜을 통해 커널에 메세지 복사,  수신자 - 커널에 복사 된 메세지를 읽어들임)

send, receive방식. address space를 넘어가는 것을 전제로 함.

커널이 동기화 제공 -> recv가 send보다 먼저 들어오면 기다리게 해주고, send만 있고 recv가 아직 없으면 그 데이터를 가지고 있어줌.

하지만 컨텍스트 스위칭으로 인한 오버헤드 있음.

서로 다른 머신에 있는 (machine boundary를 넘어가는) 프로세스 간의 message passing은 이렇게

 

 

프로세스 A => 프로세스 B로 메세지 패싱하는 상황 가정.

B가 메세지 기다리느라 waiting 큐에 있을 때 커널에 A가 보낸 메세지가 복사 되면 1) 바로 B를 깨워서 B가 메세지를 읽게 하느냐? 2) 다음 B가 스케줄링 된 차례에 B가 메세지를 읽게 하느냐? => 답은 (2)

 

A가 메세지를 보내자 마자 B가 받는다는 보장이 없고, 스케줄러 상황 그리고 B가 recv 메소드를 언제 호출 했느냐에 달려있다.

(커널이 B한테 active하게 메세지 포워딩 해주는게 아니고 그냥 B의 recv액션이 있다면 A의 send 이후, 프로세스 B가 레디큐에 있다가 자기 차례가 됐을때, 읽게 해주는 것일 뿐이다. A가 send 했더라도 B 코드 상에서 읽는 부분이 없으면 그냥 무시 됨)

 

상대방 프로세스가 메세지를 받았는지 여부를 커널이 확인해주지 않는다.

 

IPC 구현 사례

메모리 공유

- shared memory

 

메세지 교환

- pipe

- signal 

- 메세지 큐 

- 소켓 => 요즘 대부분의 IPC는 거의 다 소켓 방식 (pipe 같은 것들도 사실 내부적으로는 다 소켓 프로그래밍으로 구현되어 있음)

소켓 = 프로세스가 포트를 보는 창

- rpc

 

RPC

다른 address space에 있는(주로 같은 네트워크 상에 있는 다른 컴퓨터일 경우가 많다) procedure(subroutine,함수)를 그냥 normal(같은 local에 있는) procedure call 인 것처럼 호출하는 것. IPC의 한 종류이다.

OOP진영에서는 RMI라는 용어로 불린다. (remote method invocation)

개발자는 네트워크 통신 구현 같은 것은 생각할 필요 없이 같은 local 컴퓨터에 있다고 생각하고 프로그램을 짤 수 있다.

 

 

gRPC

2015년에 (initial release 2016, 8월) 구글에서 개발한 오픈소스 RPC 시스템.

gRPC 공식 문서에 지원하는 각 언어 마다 basic tutorial이 잘 되어있으니 따라해보면 된다.

https://grpc.io/docs/languages/

 

 

 

REST vs gRPC

gRPC가 백엔드 내부에서의 작업 분산 처리를 위해 사용 될 수 도 있지만, API 호출 도구로써는 어떤가 REST와 비교해보자.

(언급되는 API 선택지로는 SOAP vs REST vs GraphQL vs gRPC 등이 있다..)

 

gRPC

- http2 (그렇기 때문에 bi-directional streaming 지원가능)를 사용하여 통신한다

(지원하는 RPC 메소드 타입으로 unary, server-side, client-side, and bi-directional streaming 이렇게 4가지가 있음. proto file에서 service 정의 시, rpc 메소드 request나 respone타입 앞에 stream 키워드 넣으면됨)

// .proto 파일에서 
service KeyValueStore {
  rpc GetValues (stream Request) returns (stream Response) {}
}

- 데이터 serialization에 protocol buffer format 사용. IDL(interface description language)로 사용됨.

binary로 압축해서 보내기 때문에 json, xml보다 속도가 훨씬 빠르다.

- 브라우저에서 gRPC로 백엔드에 api요청을 보내려면 gRPC-web

http/* (http1.1 또는 http2)를 http2로 변환하기 위해 proxy layer가 필요하다. 

 

 

REST

- http/*

- 주로 JSON, XML format을 이용

- 모든 브라우저에서 support. (별다른 plugin 같은 것 설치할 필요없이 그냥 브라우저 런타임에서 도는 자바스크립트로 RESTful한 HTTP api request를 보낼 수 있음)

출처 : microsoft Docs -  gRPC 서비스와 HTTP API 비교

 

* gRPC-web

gRPC with gRPC-Web (왼쪽) and gRPC with REST (오른쪽)

grpc-web은 improbable팀이랑 구글팀이 각자 독자적으로 개발한 2가지 구현체가 있는데, 아직 서로 간의 compatibility 이슈 같은게 있는 것 같다.

github repository도 각각 improbable-eng/grpc-web (npm패캐지로는 @imporabable-eng/grpc-web), grpc/grpc-web (npm 패키지명 grpc-web)으로 따로 있음.

 

proxy에 대한 config는 yaml file로 한다.

 

 

 

댓글
공지사항
최근에 올라온 글