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_handler가 url_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)
'클라우드 컴퓨팅 & NoSQL > Vert.x & Node.js' 카테고리의 다른 글
Vert.x transport layer security (0) | 2014.02.03 |
---|---|
요 몇일 Vert.x를 분석해보고.. (메모) (0) | 2014.02.03 |
Vertx 개념 잡기 (instance,thread,classloader,standard verticle,worker verticle) (0) | 2014.02.03 |
Vert.x Note - Verticle & instance and Thread (0) | 2014.01.25 |
Vert.x 노트 (0) | 2014.01.24 |