클라우드 컴퓨팅 & NoSQL/Vert.x & Node.js

Vert.x Worker Concept

Terry Cho 2014. 1. 28. 23:01

Worker 대한 개념 설명

[개인 공부 노트이기 때문에 설명이 매우 어렵습니다. 나중에 이해하면 다시 개념 정리해서 올리도록 하겠습니다.]

관련 코드 : https://github.com/bwcho75/vertx_study/tree/master/worker_sample




앞단의 Network 핸들러 (TCP,HTTP)등에서 request 읽은 후에, Event Bus 통해서 Backend Worker 보낸다. 개념은 JMS MQ등을 이용해서 뒷단에서 Message Consumer 들이 처리하는 Q 기반의 Async 기반의 개념과 매우 유사하다.

그럼 Vert.x에서 차이점은 Worker 작업을 처리한 후에, 작업을 끝내면 작업 완료 메시지가 Message Producer ( Network Handler)에게 Call back 형태로 전달 된다.

Async – Call back Pattern. 일반적인 메시지 기반의 시스템이 Async-Fire & Forget 패턴을 사용하는 것에 비하면 상당히 메리트가 많다.

Network Handler입장에서는 Connection 물고 있기는 하지만, 작업은 하지 않고 뒷단의 Worker에서 처리하기 때문에, 많은 request 받아드릴 있고, 아주 많은 작업이 온다하더라도 뒷단의 Queue 통해서 비동기 처리되기 때문에, Timeout 제약이 없는 , 많은 양의 request 처리할 있다.

Call back패턴이기 때문에, Async 메시지를 보낼 , Callback function 바인딩 해야 한다.

EventBus.send('call_bus',key,reply_handler)

// reply_handler call back이다.

만약에 http 경우 reply handler에서 해당 connection reply 메시지를 보내고 싶을때는 http handler request 객체를 reply_hanlder pass해야 하는데, reply_handler 인터페이스 규격에는 message parameter 되어 있지, request response 객체와 같은 다른 parameter 추가적으로 넘길 수가 없다. 이를 해결 하는 방법은 inner function 사용하는 방법이 있다.

def url_handler(req):

  # read parameter from URI

  key = req.params['key']

  def reply_handler(message):

          reply_handler_logic(req,message) 

  print 'Im url handler. I just sent message to event bus '

EventBus.send('call_bus',key,reply_handler)

 

위의 코드를 보면, reply_handler 함수 내에서 reply_handler_logic이라는 함수를 호출할 때, “req” 객체를 넘기는 것을 볼 수 있다. reply_handlerurl_handler안에 있는 inner function이기 때문에, url_handler 범위 안의 변수를 모두 사용할 수 있는 것이고, 결과적으로 request 객체를 넘길 수 있는 것이 되낟.

Vertx에서는 앞단의 Message Handler 경우 하나의 Thread 독립된 Class Loader에서 실행된다. 이를 instance라고 하고, 하나의 JVM에서는 여러 개의 instance 수행할 있으나, Thread 수를 CPU Core 수보다 많이 경우 Thread Context Switchin 대한 부하가 생기기 때문에 일반적으로 core 보다 작게 설정한다. Network Handler Verticle 반드시 같은 쓰레드에서 수행된다.

그러나 Worker 경우에는 특정 Thread에서 같은 Veticle 생성되는 것이 아니라 WAS 같은 Thread Pool 형식을 사용한다. 하나의 Worker Verticle 여러 개의 Thread에서 동시에 수행될 있다.  

http://purplefox.github.io/vert.x/manual.html#worker-verticles 보면, worker 동시에 하나의 thread에서만 수행된다고 나와 있는데, “Worker verticles are never executed concurrently by more than one thread. Worker verticles are also not allowed to use TCP or HTTP clients or servers. Worker verticles normally communicate with other verticles using the vert.x event bus, e.g. receiving work to process.

실제 테스트해보면 instance 수만큼 동시 수행되는 듯하다.

앞단의 NetworkHandler에서 Worker로의 메시지는 Eventbus(일종의큐) 통해서 전달되낟. EventBus 내부적으로 DataGrid Hazle Cast 사용한다.

vertx.deploy_verticle('http_server.py') 통해서 기동하고 worker 경우
vertx.deploy_worker_verticle('worker.py')
이용해서 기동한다.

만약에 worker verticle 수를 조정하고 싶으면

vertx.deploy_worker_verticle('worker.py','{"dummy":"dummy"}',10)

같이 한다.(Vertx 내부적으로 Worker thread pool 설정하는 코드는 https://github.com/eclipse/vert.x/blob/master/vertx-core/src/main/java/org/vertx/java/core/impl/VertxExecutorFactory.java)