2016-10-22 2 views
0

Vertx를 사용하여 TCP 서버를 구현하고 들어오는 연결을 수락 한 다음 다른 소켓을 처리하려고합니다. 각 소켓은 독립적으로 처리 할 수 ​​있으므로 다른 소켓에 속한 핸들러는 서로 다른 이벤트 루프 스레드에서 동시에 실행됩니다. 만들어 질 때 Vert.x document 따르면 들어오는 NetSocket 처리기를 다른 이벤트 루프 스레드로 보내려면 어떻게해야합니까?

,

표준 verticles는 이벤트 루프 스레드 할당 및 시작 메소드는 그 이벤트 루프로 불린다. 이벤트 루프에서 핵심 API에 대한 핸들러를 사용하는 다른 메소드를 호출하면 Vert.x는 호출시 해당 핸들러가 동일한 이벤트 루프에서 실행되도록 보장합니다.

나는이 코드가 다른 스레드의 이름을 인쇄 할 수 있습니다, 생각 :

Vertx vertx = Vertx.vertx(); // The number of event loop threads is 2*core. 
vertx.createNetServer().connectHandler(socket -> { 
    vertx.deployVerticle(new AbstractVerticle() { 
     @Override 
     public void start() throws Exception { 
      socket.handler(buffer -> { 
       log.trace(socket.toString() + ": Socket Message"); 
       socket.close(); 
      }); 
     } 
    }); 
}).listen(port); 

그러나 불행하게도, 모든 처리기가 동일한 스레드에 위치하고 있었다.

23:59:42.359 [vert.x-eventloop-thread-1] TRACE Server - io[email protected]: Socket Message 
23:59:42.364 [vert.x-eventloop-thread-1] TRACE Server - [email protected]: Socket Message 
23:59:42.365 [vert.x-eventloop-thread-1] TRACE Server - [email protected]: Socket Message 
23:59:42.366 [vert.x-eventloop-thread-1] TRACE Server - [email protected]: Socket Message 
23:59:42.367 [vert.x-eventloop-thread-1] TRACE Server - [email protected]: Socket Message 
23:59:42.368 [vert.x-eventloop-thread-1] TRACE Server - [email protected]: Socket Message 
23:59:42.369 [vert.x-eventloop-thread-1] TRACE Server - [email protected]: Socket Message 
23:59:42.370 [vert.x-eventloop-thread-1] TRACE Server - [email protected]: Socket Message 
... more than 100+ lines ... 

반대의 예는 this echo server written in BOOST.ASIO과 유사합니다. 스레드 풀이 io_service::run()을 실행하는 데 사용되는 경우 다른 이벤트 루프 스레드에서 핸들러가 실행됩니다.

그럼, 내 질문은 이러한 핸들러를 동시에 실행하는 방법입니까?

답변

0

실제로 당신은 의도 한 것과 완전히 다른 것을합니다.

당신이 당신의 소켓에 연결을받을 때마다

, 당신은 새로운 배우를 시작,

가장 간단한 방법은 그것을 증명 :

Vertx vertx = Vertx.vertx(); // The number of event loop threads is 2*core. 
vertx.createHttpServer().requestHandler(request -> { 

    vertx.deployVerticle(new AbstractVerticle() { 

     String uuid = UUID.randomUUID().toString(); // Some random unique number 

     @Override 
     public void start() throws Exception { 
      request.response().end(uuid + " " + Thread.currentThread().getName()); 
     } 

    }); 
}).listen(8888); 



vertx.setPeriodic(1000, r -> { 
    System.out.println(vertx.deploymentIDs().size()); // Print verticles count every second 
}); 

을 나는 그것이 브라우저에서 확인 쉽게해서 HTTP 서버를 사용하고 있습니다. 당신이 그것을 할 방법을 이제

fe931b18-89cc-4c6a-9d6a-8565bb1f1c12 vert.x-eventloop-thread-9 
277330da-4df8-4e91-bd8f-82c0f62156d0 vert.x-eventloop-thread-11 
bbd3207c-80a4-41d8-9be5-b40727badc84 vert.x-eventloop-thread-13 

: 그것은있을 수만큼 잘못된
, 당신은 아직도 당신이 다른 스레드 받아야 것을 볼 수 있습니다 그것은 결정하는 것은 불가능

// We create 10 workers 
for (int i = 0; i < 10; i++) { 
    vertx.deployVerticle(new AbstractVerticle() { 

     @Override 
     public void start() { 

      vertx.eventBus().consumer("processMessage", (request) -> { 
       // Do something smart 

       // Reply 
       request.reply("I'm on thread " + Thread.currentThread().getName()); 
      }); 
     } 
    }); 
} 

// This is your handler 
vertx.createHttpServer().requestHandler(request -> { 
    // Only one server, that should dispatch events to workers as quickly as possible 
    vertx.eventBus().send("processMessage", null, (response) -> { 
     if (response.succeeded()) { 
      request.response().end("Request :" + response.result().body().toString()); 
     } 
     // Handle errors 
    }); 
}).listen(8888); 

vertx.setPeriodic(1000, r -> { 
    System.out.println(vertx.deploymentIDs().size()); // Notice that number of workers doesn't change 
}); 
+0

아직 이해하지 못했습니다. 코드와 광산의 차이점은 작업자 verticle을 배치하는 위치입니다. 핸들러에 배포하는 동안 외부에 배포합니다. 일부 처리기에 배포 된 verticle이 처리기를 배포하는 스레드를 상속한다는 의미입니까? 그렇다면 실제로 의도 된 것은 무엇입니까? –

+0

각 요청에 대해 verticle을 만듭니다. 너는 그렇게해서는 안된다. verticles는 스레드를 상속하지 않습니다. 당신이 나의 예제를 실행한다면 당신이하는 것처럼 똑같은 방법으로 verticle을 만들지 만 매번 다른 쓰레드를 얻는다는 것을 알 수있을 것이다. 동일한 스레드에 있다고 생각하는 이유는 아마도 Net 클라이언트를 처리하는 방법 일 것입니다. 그러나 그것은 또 다른 주제입니다. –

+0

왜 그렇게해서는 안됩니까? 차이점이 뭐야? 내가 vert.x 문서에서 그것을 찾지 못하거나 어쩌면 그 구현을 읽어야한다. :) –

0

을하는 이벤트 루프 Vert.x는 더 자세한 정보 (예 : 테스트 머신의 코어 수)없이 각 버텍스에 할당합니다.

어쨌든 들어오는 연결마다 버티 클을 배치하는 것은 좋지 않습니다. 세로 막 대형은 Vert.x에서 배포 단위입니다. 일반적으로 "기능"당 하나씩 만듭니다.

사용 사례로 돌아가서 이벤트 구동 프로그래밍의 목적은 연결 당 스레드를 사용하지 않는 것입니다. 동시 처리로 단일 이벤트 루프를 처리 할 수 ​​있습니다. 컴퓨터에 여러 개의 코어가있는 경우에는 해당 버텍스의 여러 인스턴스를 배포하여 모두 사용할 수 있습니다 (코어 당 이벤트 루프 1 개).

int processors = Runtime.getRuntime().availableProcessors(); 
Vertx vertx = Vertx.vertx(); 
vertx.deployVerticle(TCPServerVerticle.class.getName(), new DeploymentOptions().setInstances(processors)); 

public class TCPServerVerticle extends AbstractVerticle { 

    @Override 
    public void start(Future<Void> startFuture) throws Exception { 
    vertx.createNetServer().connectHandler(socket -> { 
     socket.handler(buffer -> { 
     log.trace(socket.toString() + ": Socket Message"); 
     socket.close(); 
     }); 
    }).listen(port, ar -> { 
     if (ar.succeeded()) { 
     startFuture.complete(); 
     } else { 
     startFuture.fail(ar.cause()); 
     } 
    }); 
    } 
} 

Vertx TCP server sharing으로 연결 핸들러는 라운드 로빈 방식으로 호출됩니다.

관련 문제