RestAPI는 단순하고 직관적입니다.

하지만 미들웨어 고성능통신 또는 미들웨어 분산 마이크로 서비스 구축시

RestAPI 로만은 분명, 고성능 Push메시지를 처리하기에 성능적으로 한계가 있습니다.

선택가능한 전송모델 몇개를 간략하게 소개합니다.

연결 방식에의한 분류



RestFul(폴링방식)



 일반적으로 웹서비스에 많이 사용하는 Rest방식입니다. 어떠한 웹브라우져또는 외부 고객에게

Rest-API를 통해 서비스를 제공하는것은 가장 무난하고 일반적입니다.  

하지만 실시간통신및, 내부서비스의 상태를 고성능으로 처리하기위해서는 REST는 성능적으로 한계가 있습니다.

HTTP 프로토콜을 사용하는 REST는 일반적으로 매 요청마다 새로운 커넥션을 요구하고 끊어버리기 때문에

단순하게 초당 천개의 메시지를 전송하는 시나리오에서, 다수의 커넥션을 맺는데 값비싼 리소스를사용하게 됩니다.


WebSocket(Push방식)

Rest vs Websocket 수행시간

 

Rest의 수행속도가 메시지가 증가함에 따라, 기울기가 급격해지는 성능저하를

볼수가 있습니다. 이것은 Rest의 수행속도에 한계가 있음을 의미합니다.

일반적으로 API호출당 중앙DB SP를 꼭 한번 호출해야하는 경우이고

커넥션 비용보다 SP호출 비용이 더 크다고하면 이 부분은 프로토콜 변경문제로

해결할수가 없으며 추후 설명하게될 영속성있는 액터를통해 부분 해결가능합니다. 

단순하게 노드당 초당 1000개의 메시지를 처리해야되는 어떠한 내부기능이

필요하다고 했을때, Rest는 적당하지 않다는 의미입니다.


TCP스트리머중에 웹소켓도 사실 안정적이고 성능이 좋은 통신모델은 아닙니다.

웹소켓 VS 일반스트림 :  http://blog.lightstreamer.com/2013/05/benchmarking-socketio-vs-lightstreamer.html


Server/Client VS PeerToPeer

Client/Sever방식은 Client가 중앙관리를 해주는 서버에 항상 연결을 유지하여 중앙 서버의 통제를받습니다.

대부부분의  요청 트래픽은 중앙 서버에 집중이됩니다.

PeerToPeer방식은 각 노드의 요소들이 서로연결하여 필요한 데이터를 룰에의해 주고 받습니다.

분산처리가 되지만, 중앙서버 방식보다 구현방법이 더 복잡해집니다. AKKA가 기본으로 채택한

메시지 처리 모델이며 AKKA의 목표는 이 사용을 단순화하는데 있습니다.


채널에의한 분류


Point To Point

송신자의 메시지가 특정 수신자에게 전달되는것으로 대부분 메시지전송은 이 채널로 충분하며 

필요하면 채널을 복수개로 생성하여 분리처리도 가능합니다.

하지만 애플리케이션이 수행되는 동안,  채널이 다양화되고 수신자들이 자유롭게 채널을 바꾸고자할때는

PUS/SUB을 활용할수가 있습니다. 


PUB/SUB

In this rails tutorial, publish-subscribe design pattern is laid out in this diagram.

신문의 발행/구독모델과 유사하며 실제로 활용도가 높기때문에  여러 통신가능한 라이브러리 혹은 툴킷에서 기본으로 도입되었습니다.

사용자 A는 동아일보를 구독하기로 계약을 맺는다.

사용자 B는 조선일보를 구독하기로 계약을 맺는다.

각 신문사는 발행만하고 배달소에(EventBus) 신문 공급만 합니다.

신문 공급사(EventBus)는 구독한 사용자에게 각각 받고자하는 신문을 분류(채널)하여 배달을 한다.

구독자는 자신이 원하는 신문을 볼수가 있습니다.

대표적으로 고성능 Read기능을 수행하려는  메모리 DB인 Redis에도 채택된 모델이며

브라우져 지원 Websocket 라이브러리인 Socket.io / Atmosphere / SignalR 에서도 기본으로 지원하는 메시지 전송모델입니다.

간단하게 설명하면 메시지 공급자는, 채널만을 분류하여 메시지를 발송합니다. 

메시지를 받으려고 하는측에서, 특정 채널에 가입을 하면 메시지공급자의 메시지를 공급받을수 있습니다.


PUB/SUB 모델은 심플하기때문에, 직접 구현도 가능합니다.

아래는 TopicEventBus 라는 객체를 자바모델 참고하여 실제로 작성하고 사용해본 샘플입니다. (이개념을 쉽게 설명하기위해 직접 개발)



다양한 언어의 시청자가 존재하는 다국어 방송 메시지 모듈

//Create Act Act System for Testing
ActorSystem system = TopicEventBus.inItSystem("TestTopic"); //ActorSystem Init
 
//Create user
TopicEventBus.CreateActor("A");
TopicEventBus.CreateActor("B");
TopicEventBus.CreateActor("C");
 
//A user wants to receive News A in English
TopicEventBus.Subscribe("A", "newsA", "en").Wait();
 
//User B wants to receive news A in Korean
TopicEventBus.Subscribe("B", "newsA", "kr").Wait();
 
//Users of c want to receive News B in English
TopicEventBus.Subscribe("C", "newsB", "en").Wait();
 
 
//Server real-time messages (server sprays news regardless of user)
TopicEventBus.Publish("newsA", "Hi...here news A", "en");
TopicEventBus.Publish("newsA", "여기에 새로운 뉴스가 있습니다.", "kr");
TopicEventBus.Publish("newsB", "Hi...here news B", "en");

Result:
create actor name:A
create actor name:B
create actor name:C
Subscribe actor name:A to newsA
Subscribe actor name:B to newsA
A FirstSet LangCode en from newsA
B FirstSet LangCode kr from newsA
Subscribe actor name:C to newsB
C FirstSet LangCode en from newsB
Publish Topic:newsA msg:Hi...here news A
Publish Topic:newsA msg:여기에 새로운 뉴스가 있습니다.
A가 뉴스를 받음 Hi...here news A from newsA
Publish Topic:newsB msg:Hi...here news B
C가 뉴스를 받음 Hi...here news B from newsB
B가 뉴스를 받음 여기에 새로운 뉴스가 있습니다. from newsA


저장소위치

http://git.webnori.com/projects/AKKA/repos/topiceventbus/browse


메시지 처리및 전송 최종목표

우리의 응답이 좋은 메시지의 목표는 출발한 메시지 type상관없이 ( rest / websocket ) 출발하여

미들웨어에서 가장 효율적인 처리를 위해 어떠한 라우터및 클러스터 방식을 선택할것이며 ( client to server ,peertopeer , pubsub)

중앙 Db의 호출을 최소화 하여 응답을 할것입니다.




2 Comments

  1. Anonymous

    BS low - ralitnaoity high! Really good answer!
  2. Anonymous

    Arlcites like this make life so much simpler.