블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


 
 


Envoyproxy

조대협 (http://bcho.tistory.com)

배경

마이크로 서비스 아키텍쳐가 발전하면서 서비스간의 통신을 라우팅하는 요건이 많아지면서 이를 소프트웨어 단이 아리나 인프라 단에서 처리할 수 있는 기술로 프록시 서버가 매우 유용하다. 기존의 대표적인 프록시 솔루션으로는 nginx, haproxy, apache 서버등이 있는데, 이러한 프록시들은 보통 TCP/IP 레이어에서 L4 로 작동을 하였다. 그러나 마이크로 서비스에서는 조금더 복잡한 라우팅 요건이 필요한데 예를 들어서 HTTP URL에 따른 라우팅에서 부터, HTTP Header를 이용한 라우팅등 다양한 요건이 필요해지면서 L4보다는 애플리케이션 레이어인 L7 기능이 필요해지게 되었다.

마이크로 서비스 아키텍처

특히 마이크로 서비스 아키텍쳐 (이하 MSA) 가 유행하면서 서비스간 라우팅이나 인증등 여러 기능들이 소프트웨어 레이어에서 구현이 되었는데, (넷플릭스 OSS가 대표적인 사례) 이 경우 서비스를 개발하는 각팀의 능력에 따라서 아키텍쳐의 성숙도의 편차가 크게 되었고, 소프트웨어가 특정 기술에 종속성을 가질 수 있는 문제점이 있었다.

특히 서비스간 라우팅, 헬스체크등 서비스간의 통제 기능은 궂이 애플리케이션 코드단에서 구현을 하지 않더라도 프록시 서버와 같은 인프라 서버를 이용해서 구현이 가능하다


아래 그림과 같이 서비스 사이에 프록시를 위치 시키게 되면, 이 프록시가 서비스간의 부하 분산, 로그 수집, Circuit breaker와 같은 다양한 기능을 수행할 수 있다.


Envoy Proxy

이런 배경에 맞춰서 마이크로 서비스 아키텍쳐에 적절한 프록시로 envoy 라는 프록시가 2016년에 소개되었다. Lyft사에서 개발되었으면 오픈소스로 공개되었다.

기존 프록시 L4기능 뿐 아니라 L7 기능도 지원하면서 HTTP 뿐아니라 HTTP 2.0,TCP,gRPC까지 다양한 프로토콜을 지원한다.


성능 지표를 보면 아래 Twillo에서 2017년에 테스트 한 자료를 참고할만 한데, (원본 https://www.twilio.com/blog/2017/10/http2-issues.html) HAProxy 보다 약간 느린것을 확인할 수 있다. 아무래도 L4가 아닌 L7단의 로드밸런서이다 보니 다소 성능 감소는 부담해야 한다.




(참고. 위의 문서를 보면 Envoy HTTP2 의 성능이 낮게 나오는데, 이는 Envory 자체 문제라가 보다는 HTTP/2가 Connection을 reuse하는 특성에서 온다고 볼 수 있는데, 성능에 대한 이슈가 있는 만큼 HTTP/2를 사용할 경우에는 별도의 검증 등이 필요하리라 본다.)


주요 기능적인 특성을 보면 다음과 같다.


  • HTTP, TCP, gRPC 프로토콜을 지원

  • TLS client certification 지원

  • HTTP L7 라우팅 지원을 통한 URL 기반 라우팅, 버퍼링, 서버간 부하 분산량 조절등

  • HTTP2 지원

  • Auto retry, circuit breaker, 부하량 제한등 다양한 로드밸런싱 기능 제공

  • 다양한 통계 추적 기능 제공 및 Zipkin 통합을 통한 MSA 서비스간의 분산 트렌젝션 성능 측정 제공함으로써 서비스에 대한 다양한 가시성 (visibility)을 제공

  • Dynamic configuration 지원을 통해서, 중앙 레파지토리에 설정 정보를 동적으로 읽어와서 서버 재시작없이 라우팅 설정 변경이 가능함

  • MongoDB 및 AWS Dynamo 에 대한 L7 라우팅 기능 제공


등 매우 다양한 기능을 제공한다.


Envoy 배포 아키텍처

Envoy 프록시는 배포 위치에 따라서 다양한 기능을 수행할 수 있는데, 크게 다음과 같이 4가지 구조에 배포가 가능하다.



Front envoy proxy

특정 서비스가 아니라, 전체 시스템 앞의 위치하는 프록시로, 클라이언트에서 들어오는 호출을 받아서 각각의 서비스로 라우팅을 한다. URL 기반으로 라우팅을 하는 기능 이외에도, TLS(SSL) 처리를 하는 역할들을 할 수 있다. 통상적으로 nginx나 apache httpd가 리버스프록시로 이 용도로 많이 사용되었다.

Service to service ingress listener

특정 서비스 앞에 위치하는 배포 방식으로 서비스로 들어오는 트래픽에 대한 처리를 하는데, 트래픽에 대한 버퍼링이나 Circuit breaker 와 같은 역할을 수행한다.

Service to service egress listener

특정 서비스 뒤에서 서비스로부터 나가는 트래픽을 통제 하는데, 서비스로 부터 호출 대상이 되는 서비스에 대한 로드 밸런싱, 호출 횟수 통제 (Rate limiting)와 같은 기능을 수행한다.

External service egress listener

내부서비스에서 외부 서비스로 나가는 트래픽을 관리하는 역할인데, 외부 서비스에 대한 일종의 대행자(Delegator)와 같은 역할을 한다.


시스템 앞 부분이나 또는 시스템을 구성하는 서비스의 앞뒤에 배치할 수 있는 구조지만, 서비스 앞뒤로 붙는다고 실제로 배포를 할때 하나의 서비스 앞뒤로 두개의 envoy proxy를 배치하지는 않는다.

다음과 같이 하나의 서비스에 하나의 Envoy를 배치 한후, ingress/egress 두 가지 용도로 겸용해서 사용한다.



Envoy 설정 구조

다음은 Envoy 설정 파일을 살펴 보자

Envoy의 설정은 크게 아래 그림과 같이 크게 Listener, Filter, Cluster 세가지 파트로 구성된다.



  • Listener
    Listener는 클라이언트로 부터 프로토콜을 받는 부분으로, TCP Listener, HTTP Listener 등이 있다.

  • Filter
    Filter는 Listener 로 부터 많은 메시지를 중간 처리하는 부분으로, 압축이나 들어오는 Traffic 에 대한 제한 작업등을 한후, Router를 통해서 적절한 클러스터로 메시지를 라우팅 하는 역할을 한다.

  • Cluster
    Cluster는 실제로 라우팅이 될 대상 서버(서비스)를 지정한다.


이렇게 Listener를 통해서 메시지를 받고, Filter를 이용하여 받은 메시지를 처리한 후에, 라우팅 규칙에 따라서 적절한 Cluster로 라우팅을 해서 적절한 서비스로 메시지를 보내는 형식이다.


Envoy 설치

Envoyproxy를 빌드하고 설치하는 방법은 여러가지가 있다. 소스코드로 부터 빌드를 하는 방법이나 이미 빌드된 바이너리를 사용해서 설치하는 방법 그리고 이미 빌딩된 도커 이미지를 사용하는 방법이 있다.

소스코드로 빌드하는 방법의 경우에는 bazel (make와 같은 빌드 도구) 빌드를 이용해서 빌드해야 하고, 빌드된 바이너리는 특정 플랫폼에 대해서만 미리 빌드가 되어 있기 때문에, 모든 플랫폼에 사용하기가 어렵다.

마지막으로는 도커 이미지 방식이 있는데, 이 방식이 배포면에서 여러모로 편리하기 때문에 도커 이미지를 이용한 배포 방식을 설명하도록 하겠다.


다음 명령어 처럼

docker pull을 이용하여 envoyproxy 도커 이미지 최신 버전을 가지고 오고, 다음 docker run 명령을 이용하여, 해당 이미지  (envoyproxy/envoy:latest)를 기동한다. 이때 -p 10000:10000 포트를 도커의 10000번 포트를 VM의 10000포트로 포워딩하도록 설정한다.


$ docker pull envoyproxy/envoy:latest
$ docker run --rm -d -p 10000:10000 envoyproxy/envoy:latest
$ curl -v localhost:10000


배포가 끝났으면, curl을 이용하여 localhost:10000번에 호출 하는 테스트를 하도록 한다.

설정에는 디폴트로, 10000 번 포트로 들어오는 모든 트래픽을 *.google.com으로 라우팅 하도록 설정되어 있다.


원본 설정 파일은 https://github.com/envoyproxy/envoy/blob/master/configs/google_com_proxy.v2.yaml 에 있고,  상세 내용을 보면 아래와 같다.


  • admin:
    이 부분은 envoyproxy의 admin 서버를 기동하는 부분으로, envoy 서버의 각종 설정이나 상태 정보를 127.0.0.1:9901로 들어오는 요청은 admin 기능으로 라우팅하도록 한다.

  • static_resources:
    Listener와 Filter 설정에 해당하는 부분으로, 아래 부면, listeners로 정의가 되어 있고 socket_address 부분에 0.0.0.0에 포트 10000 으로 들어오는 요청을 처리하도록 하였다.

    다음 filter_chain 부분에 filter들을 연속해서 정의하는데, http_connection_manager를 이용하여 모든 트래픽을 service_google이라는 클러스터로 라우팅 하도록 설정하였다.

  • clusters:
    마지막으로 clusters 부분에는 “service_google”이라는 클러스터를 정의했으며, 이 호스트의 URL은 google.com 443 포트로 정의하였다.


admin:

access_log_path: /tmp/admin_access.log

address:

  socket_address: { address: 127.0.0.1, port_value: 9901 }


static_resources:

listeners:

- name: listener_0

  address:

    socket_address: { address: 0.0.0.0, port_value: 10000 }

  filter_chains:

  - filters:

    - name: envoy.http_connection_manager

      config:

        stat_prefix: ingress_http

        route_config:

          name: local_route

          virtual_hosts:

          - name: local_service

            domains: ["*"]

            routes:

            - match: { prefix: "/" }

              route: { host_rewrite: www.google.com, cluster: service_google }

        http_filters:

        - name: envoy.router

clusters:

- name: service_google

  connect_timeout: 0.25s

  type: LOGICAL_DNS

  # Comment out the following line to test on v6 networks

  dns_lookup_family: V4_ONLY

  lb_policy: ROUND_ROBIN

  hosts: [{ socket_address: { address: google.com, port_value: 443 }}]

  tls_context: { sni: www.google.com }


참고 자료


구글 프로토콜 버퍼 (Protocol buffer)

프로그래밍 | 2017.06.25 19:30 | Posted by 조대협


구글 프로토콜 버퍼

조대협 (http://bcho.tistory.com)


텐서 플로우로 모델을 개발하다가 학습이 끝난 모델을 저장하여, 예측하는 데 사용하려고 하니, 모델을 저장하는 부분이 꽤나 복잡하여 찾아보니, 텐서플로우는 파일 저장 포맷을 프로토콜 버퍼를 사용한다는 것을 알았다.


그래서, 오래전에 살펴보았던 프로토콜 버퍼를 다시 살펴보았다.

개요 및 특징

프로토토콜 버퍼는 구글에서 개발하고 오픈소스로 공개한, 직렬화 데이타 구조 (Serialized Data Structure)이다. C++,C#, Go, Java, Python, Object C, Javascript, Ruby 등 다양한 언어를 지원하며 특히 직렬화 속도가 빠르고 직렬화된 파일의 크기도 작아서 Apache Avro 파일 포맷과 함께 많이 사용된다.

(직렬화란 데이타를 파일로 저장하거나 또는 네트워크로 전송하기 위하여 바이너리 스트림 형태로 저장하는 행위이다.)


특히 GRPC 라는 네트워크 프로토콜의 경우 HTTP 2.0 을 기반으로 하면서, 메세지를 이 프로토콜 버퍼를 이용하여 직렬화하기 때문에, 프로토콜 버퍼를 이해해놓으면 GRPC를 습득하는 것이 상대적으로 쉽다.


프로토콜 버퍼는 하나의 파일에 최대 64M까지 지원할 수 있으며, 재미있는 기능중 하나는 JSON 파일을 프로토콜 버퍼 파일 포맷으로 전환이 가능하고, 반대로 프로토콜 버퍼 파일도 JSON으로 전환이 가능하다.

설치 및 구성

프로토콜 버퍼 개발툴킷은 크게 두가지 부분이 있다. 데이타 포맷 파일을 컴파일 해주는 protoc 와 각 프로그래밍 언어에서 프로토콜 버퍼를 사용하게 해주는 라이브러리 SDK가 있다.


protoc 컴파일러와, 각 프로그래밍 언어별 SDK는 https://github.com/google/protobuf/releases  에서 다운 받으면 된다.


protoc 는 C++ 소스 코드를 직접 다운 받아서 컴파일하여 설치할 수 도 있고, 아니면 OS 별로 미리 컴파일된 바이너리를 다운받아서 설치할 수 도 있다.  


각 프로그래밍 언어용 프로토콜 버퍼 SDK는 맞는 버전을 다운 받아서 사용하면 된다. 파이썬 버전 설치 방법은  https://github.com/google/protobuf/tree/master/python 를 참고한다.

이 글에서는 파이썬 SDK 버전을 기준으로 설명하도록 한다.

구조 및 사용 방법

프로토콜 버퍼를 사용하기 위해서는 저장하기 위한 데이타형을 proto file 이라는 형태로 정의한다. 프로토콜 버퍼는 하나의 프로그래밍 언어가 아니라 여러 프로그래밍 언어를 지원하기 때문에, 특정 언어에 종속성이 없는 형태로 데이타 타입을 정의하게 되는데, 이 파일을 proto file이라고 한다.

이렇게 정의된 데이타 타입을 프로그래밍 언어에서 사용하려면, 해당 언어에 맞는 형태의 데이타 클래스로 생성을 해야 하는데, protoc 컴파일러로 proto file을 컴파일하면, 각 언어에 맞는 형태의 데이타 클래스 파일을 생성해준다.


다음은 생성된 데이타 파일을 프로그래밍 언어에서 불러서, 데이타 클래스를 사용하면 된다.

예제

간단한 파이썬 예제를 통해서 사용법을 익혀보자. 저장하고자 하는 데이타 포맷은 Person 이라는 클래스형으로, 이름,나이,이메일을 순차적으로 가지고 있는 데이타 포맷을 정의하여, Person 객체를 생성하여 데이타를 저장하고 이 객체를 파일에 저장했다가 읽어 들이는 예제이다.


이름과 이메일은 문자열, 나이는 숫자로 저장된다. 이 데이타형을 proto 형으로 정의하면 다음과 같다.

address.proto

syntax = "proto3";

package com.terry.proto;


message Person{

 string name = 1;

 int32 age=2;

 string email=3;

}


이 파일을 address.proto 라는 이름으로 저장한다. 다음 proto 파일을 파이썬용 코드로 컴파일한다. protoc 명령을 이용하면 되는데,


protoc -I=./ --python_out=./ ./address.proto


  • -I에는 이 protofile이 있는 소스 디렉토리

  • --python_out에는 생성된 파이썬 파일이 저장될 디렉토리

  • 그리고 마지막으로 proto 파일을 정의한다.


이렇게 컴파일을 하면 --python_out으로 지정된 디렉토리에 address_pb2.py 라는 이름으로 파이썬 파일이 생성된다. (pb2는 protocol buffer2를 의미하는 확장자이다.)


다음은 생성된 Person 클래스를 이용하여 객체를 만들고, 값을 지정한 후 이를 파일로 저장하는 예제이다.

write.py

import address_pb2


person = address_pb2.Person()


person.name = 'Terry'

person.age = 42

person.email = 'terry@mycompany.com'


try:

f = open('myaddress','wb')

f.write(person.SerializeToString())

f.close()

print 'file is wriiten'

except IOError:

print 'file creation error'


protoc에 의해 컴파일된 address_pb2 모듈을 import 한후에, address_pb2.Person()으로 person 객체를 생성한다. 다음에 person.name, person.age, person.email에 값을 넣은 후 파일을 열어서 파일에 person 객체의 내용을 넣는데, 이때 SerializeToString() 메서드를 이용하여 문자열로 직렬화 한다.


다음 코드는 이렇게 파일로 저장된 person 객체를 다시 파일로 부터 읽는 코드이다.

read.py

import address_pb2


person = address_pb2.Person()


try:

f = open('myaddress','rb')

person.ParseFromString(f.read())

f.close()

print person.name

print person.age

print person.email

except IOError:

print 'file read error'


앞의 코드와 같이 빈 person 객체를 만든 후에, 파일에서 문자열을 읽어서 ParseFromString() 메서드를 이용하여 문자열을 person 객체로 파싱한후에, 그 내용을 출력한다.

데이타 구조

위의 예제에서는 간단하게 name,age,email 정도의 구조만 간단하게 정의했지만, JSON과 같이 계층을 가지거나 배열형의 데이타 구조도 같이 정의할 수 있고, enum과 같은 타입 정의도 가능하다.

자세한 설명은 https://developers.google.com/protocol-buffers/docs/proto 를 참고하기 바란다.

간단한 팁 - JSON 변환

앞서 설명했듯이, 프로토콜 버퍼의 다른 장점중의 하나는 프로토콜 버퍼로 저장된 데이타 구조를 JSON으로 변환하는 것도 가능하고 역으로 JSON 구조를 프로토콜 버퍼 객체로 만들 수 도 있다.

아래 코드는 프로토콜 버퍼 객체인 person을 JSON으로 변환하여 출력하는 부분이다. MessageToJson 메서드를 사용하면 된다.


print person.name

print person.age

print person.email


from google.protobuf.json_format import MessageToJson

jsonObj = MessageToJson(person)

print jsonObj


다음은 실행 결과이다.


Terry

42

terry@mycompany.com

{

 "age": 42,

 "name": "Terry",

 "email": "terry@mycompany.com"

}



이 기능을 사용하면, 클라이언트(모바일)에서 서버로 HTTP/JSON 과 같은 REST API를 구현할때, 전송전에, JSON을 프로토콜 버퍼 포맷으로 직렬화 해서, 전체적인 패킷양을 줄여서 전송하고, 서버에서는 받은 후에, 다시 JSON으로 풀어서 사용하는 구조를 취할 수 있다. 사실 이게 바로 GRPC 구조이다.

API 게이트웨이를 백앤드 서버 전면에 배치 해놓고, 프로토콜 버퍼로 들어온 메세지 바디를 JSON으로 변환해서 백앤드 API 서버에 넘겨주는 식의 구현이 가능하다.


grpc 설치하기

프로그래밍 | 2015.04.02 02:11 | Posted by 조대협

Google RPC 설치하기

(조대협 http://bcho.tistory.com)


지난 GRPC 소개에 이어서 오늘은 JAVA에서 GRPC를 사용하기 위한 설치 방법을 설명한다.


  • https://github.com/grpc/grpc-common/tree/master/java
  • https://github.com/grpc/grpc-common
  • https://github.com/grpc/grpc-common/blob/master/java/javatutorial.md
  • https://github.com/grpc/grpc-java


글들을 참고하였으며, 컴파일 환경 설정등을 위해서 생각보다 시간이 많이 소요된다. (삽질,Visual Studio 설치 포함 한 2~3시간 걸린듯)


grpc hello world / java





grpc-java 설치하기

https://github.com/grpc/grpc-java#how-to-build 를 참고


준비 : java 8, maven 3.2.x,gradle 2.3 필요


1. 코드 받기

 C:\dev\libs> git clone https://github.com/grpc/grpc-java


2. 관련 라이브러리 설치


1) Netty 4.1 설치

grpc-java는 Netty 4.1에 기반함. 아래절차에 따라서 설치한다.

cd C:\dev\libs\grpc-java>

$ git submodule update --init

$ cd lib/netty

$ mvn install -pl codec-http2 -am -DskipTests=true


2) Protocolbuf 3.0.0-alhpa-2 설치 (windows)

안타깝게도 알파버전이라 윈도우즈용 인스톨 바이너리가 없다. 소스 받아서 직접 컴파일해야 한다.

윈도우 환경에서는 C/C++ 컴파일러가 필요하니까는 간단하게 Visual Studio 무료 버전을 깔자 https://www.visualstudio.com/en-us/products/free-developer-offers-vs.aspx

(무료 버전 제공)

다음은 c:\dev\lib\protobuf에 설치 하는 순서이다.


C:\dev\libs>git clone https://github.com/google/protobuf.git


다음으로, C:\dev\libs\protobuf\vsprojects 에 들어가면 visual studio 프로젝트 파일이 있음

VC로 Release 빌드하면 됨. (이때 반드시, Release 모드로 빌드할것, Debug 모드로 빌드하면 나중에 grpc-java 빌드할때 링크에러남). Test 코드 빌드하다가 에러가 나는데 무시하자. 테스트 코드가 안들어가 있다.


빌드 후, C:\dev\libs\protobuf\vsprojects 아래에 readme.txt를 보고 따라할것


C:\dev\libs\protobuf\vsprojects\Release 에 빌드 결과가 생김

안에 protoc.exe가 생김



3. grpc-java 설치


위에서 만든 protoc.exe를 path가 있는 디렉토리에 복사하거나.

본인의 경우에는 위의 디렉토리 자체를 다 PATH에 걸어버렸다. (연관 라이브러리들이 있어서리)

다음으로 grpc-java를 설치하자


앞에서 받은 grpc-java 디렉토리로 가서

$ gradlew install -Pprotobuf.include=C:\dev\libs\protobuf\src  -Pprotobuf.libs=C:\dev\libs\protobuf\vsprojects\Release


여기까지 했으면 grpc 설치가 완료되었다. 실제로 동작하는지 확인하려면, 예제 코드를 돌려보면 되는데, 실행 방법은 다음과 같다. 


서버 실행

gradlew :grpc-examples:helloWorldServer -Pprotobuf.include=C:\dev\libs\protobuf\src  -Pprotobuf.libs=C:\dev\libs\protobuf\vsprojects\Release



클라이언트 실행

gradlew :grpc-examples:helloWorldClient -Pprotobuf.include=C:\dev\libs\protobuf\src  -Pprotobuf.libs=C:\dev\libs\protobuf\vsprojects\Release


실행시 위와 같이 protocol buf lib 위치와 소스 위치를 지정해야 하는데, 매번 지정하기 귀찮다면 다음과 같이 환경 변수로 넣어놓아도 된다.

Since specifying those properties every build is bothersome, you can instead create %HOMEDRIVE%%HOMEPATH%.gradle\gradle.properties with contents like:

protobuf.include=C:\\path\\to\\protobuf-3.0.0-alpha-2\\src

protobuf.libs=C:\\path\\to\\protobuf-3.0.0-alpha-2\\vsprojects\\Release


grpc (google rpc)에 대한 분석 #1

프로그래밍 | 2015.04.01 23:40 | Posted by 조대협

GRPC 분석 #1


앞글에서도 간단하게 GRPC에 대해서 소개했는데, 제법 괜찮은것 같아서 조금 더 분석해보기로 결정하였다.

주목할만한 특징 중의 크게 두가지가 있다.


모바일 지원 여부

먼저, 모바일이 지원된다. 안드로이드나, iOS (Object-C)를 지원하기 때문에, 모바일 클라이언트에서 호출이 가능하고, 바이너리 프로토콜을 사용하며, 하나의 Connection으로 RPC 호출을 처리하기 때문에, JSON/HTTP REST에 비해서 네트워크 대역폭 소모가 적고, 매번 커넥션을 열어야 하는 부담이 없기 때문에, 효율적이다. (속도는 당연히 빠를듯)


확인을 해봐야 겠지만, 양방향 스트리밍을 지원한다는 것을 봐서는 푸쉬같이 클라이언트쪽으로 메세지를 쏘는 기능도 가능할듯 하다.


Google Protocol Buffer 기반

안의 메세지는 구글의 PB를 기반으로 한다. PB는 Serialization 프레임웍으로, Message Q로 넘기거나, 또는 NoSQL등에 바로 저장할 수 있기 때문에, 내부 메세징 포맷으로도 바로 사용이 가능하다.


아쉬운 점은 아직까지 웹 브라우져 기반의 자바스크립트는 지원하지 않는다. (이것까지 되면, 웹 소켓까지 대체할 수 있을 듯한다. 약간 아쉬운듯)


구체적인 내용은 프로토타입핑을 해봐야 알 수 있을듯..

어쨌거나, 조금 지켜볼 필요가 있는 프레임웍인듯



구글의 HTTP 기반의 RPC 프로토콜 GRPC

프로그래밍 | 2015.03.31 01:42 | Posted by 조대협


간단한 GRPC 소개



어제 오늘 약간 커뮤니티를 달군 내용 중의 하나가 구글에서 새롭게 발표한 GRPC라는 개념이다.

GRPC는 한마디로 이야기하자면, 예전 자바 RMI나, CORBA의 웹 버전 정도?


RPC란, Remote Procedure Call의 약자로, 원격에 있는 함수를 호출해주는 기능을 이야기 한다.

RPC는 일반적으로, request parameter와 response parameter를 알아야 하기 때문에, 양쪽의 인터페이스 규약을 IDL 등의 언어로 정의한후, 해당 프로그래밍 언어가 부를 수 있는 형태의 코드로 생성을 해줘야 하는데, 이를 Skeleton과 Stub코드라고 한다.


HTTP 기반의 REST가 유행하면서 RPC는 많이 사라 졌는데, 반대로 REST의 경우, 호출 하는 parameter와 응답 값이 명시적이지 않기 때문에, 오류의 여지가 많고 (API 스펙만을 의존, 형 체크등을 안함) JSON을 HTTP를 통해서 쏘기 때문에, 다소 속도가 떨어진다는 단점을 가지고 있다.


그래서 근래에 RPC 개념이 다시 유행하기 시작했는데, 페이스북의 경우에는 Thrift라는 바이너리기반의 RPC 프레임웍을 발표했다. 구글은 RPC 자체는 지원하지 않고, 메세지(JSON등)을 Serialize할 수 있는 프레임웍으로 PB (Protocol Buffer)를 제공해왔는데, GRPC라는 개념으로, PB를 기본으로한 Serizlaizer에 HTTP2를 붙여서 RPC 프레임웍을 릴리즈 하였다.

http://www.grpc.io/


GRPC의 특징 중의 하나는 C/C++  뿐 아니라 자바나 Ruby,node.js,python과 같은 대부분의 모던 프로그래밍 언어를 지원하며, 또한, 요즘 유행하는 MSA (마이크로 서비스 아키텍쳐)와 물려서, RPC를 하나의 서비스로 하여 배포할 수 있는 개념을 가지고 왔다고 해야 할까? MSA와 모던 프로그래밍 언어의 조합은 상당히 매력적이다. 서비스의 개념을 가지고 있는 것만으로도, 잘 서비스화된 서버 시스템을 만들어 낼 수 있으니까는.

이러한 서비스 컨셉은 TP 모니터로 유명한 Tuxedo에 널리 사용되었는데, (그러고보면 10년이 훨 지난 이 제품이 아직도 현대의 많은 개념을 리드하는게 존경 스러울 뿐이다.) 잘 정의된 서비스 정의 프레임웍은 깔끔한 서비스 개발을 보장해주기 때문에, 훨씬 정리된 형태의 MSA 구현이 가능하지 않을까 싶다.


또한 서버 구현체 역시 자바의 경우 Netty를 이용하여, 몇줄 안되는 코드로 고 성능 서버에 서비스를 많지 않은 코딩양으로 구현이 가능하다. 


얼마나 확산이 될지는 지켜봐야 하겠지만, REST의 단방향의 한계를 극복하고, HTTP2 기반의 Streaming을 지원하며, REST대비 빠른 성능을 지원하기 때문에, 충분히 검토해볼만한 가치는 있는 것으로 보인다.

또한 코딩양 역시 Spring Boot 만큼이나 적고 간단해서 경쟁력이 있고, 무엇보다 여러 언어를 동시 지원함으로써 폴리그랏 형태의 개발이 가능하다는 장점은 있지만, 반대로, 네이티브 프로토콜의 한계상, 데이타 포맷 변환이 런타임시 자유롭지 못하고, 중간에 메세지를 열어서 라우팅이나 메디에이션을 하는 API GATEWAY 도입이 어려운 구조이기 때문에, 분명히 한계는 있다.


시간이 될때, 몇가지 샘플을 가지고 테스트 좀 해봐야 할듯

거의 예전 코바 + 턱시도와 컨셉이 같은듯... 장점만 따왔으니 괜찮지 않을까?

'프로그래밍' 카테고리의 다른 글

grpc 설치하기  (0) 2015.04.02
grpc (google rpc)에 대한 분석 #1  (0) 2015.04.01
구글의 HTTP 기반의 RPC 프로토콜 GRPC  (1) 2015.03.31
국내 자바 MVC 프레임웍 사용 현황  (5) 2009.11.11
UML Notation 설명  (0) 2009.04.09
Java Transaction Model  (0) 2009.04.09