问题描述
根据 Vert.x 文档 - 使用 Verticles 进行部署是 optional。如果是这种情况 - 如何将 HTTP 服务器部署到多个事件循环上?这是我尝试过的 - 还阅读了 api docs 并找不到任何内容:
Vertx vertx = Vertx.vertx(new VertxOptions().setEventLoopPoolSize(10));
HttpServerOptions options = new HttpServerOptions().setLogActivity(true);
for (int i = 0; i < 10; i++) {
vertx.createHttpServer(options).requestHandler(request -> {
request.response().end("Hello world");
}).listen(8081);
}
这似乎在第一个事件循环中创建了 10 个 HTTP 服务器,但我希望每个事件循环有 1 个服务器。
这是我在日志中看到的 - 所有 eventloop-thread-0:
08:42:46.667 [vert.x-eventloop-thread-0] 调试 io.netty.handler.logging.LoggingHandler - [id: 0x0c651def,L:/0:0:0:0:0:0:0:1:8081 - R:/0:0:0:0:0:0:0:1:50978] 阅读:78B
08:42:46.805 [vert.x-eventloop-thread-0] 调试 io.netty.handler.logging.LoggingHandler - [id: 0xe050d078,L:/0:0:0:0:0:0:0:1:8081 - R:/0:0:0:0:0:0:0:1:51000] 阅读:78B
08:42:47.400 [vert.x-eventloop-thread-0] 调试 io.netty.handler.logging.LoggingHandler - [id: 0x22b626b8,L:/0:0:0:0:0:0:0:1:8081 - R:/0:0:0:0:0:0:0:1:51002] 阅读:78B
解决方法
“可选”并不意味着“你可以,获得同样的好处”。 “可选”仅表示“您可以”。
Vert.x 有线程关联的概念。从同一个线程创建的 HTTP Server 将始终被分配到同一个事件循环。否则你会遇到令人讨厌的线程安全问题。
您可以将上面的示例代码与以下代码进行比较:
Vertx vertx = Vertx.vertx();
HttpServerOptions options = new HttpServerOptions().setLogActivity(true);
// Spawn multiple threads,so EventLoops won't be bound to main
ExecutorService tp = Executors.newWorkStealingPool(10);
CountDownLatch l = new CountDownLatch(1);
for (int i = 0; i < 10; i++) {
tp.execute(() -> {
vertx.createHttpServer(options).requestHandler(request -> {
System.out.println(Thread.currentThread().getName());
// Slow the response somewhat
vertx.setTimer(1000,(h) -> {
request.response().end("Hello world");
});
}).listen(8081);
});
}
// Just wait here
l.await();
输出类似于:
vert.x-eventloop-thread-0
vert.x-eventloop-thread-1
vert.x-eventloop-thread-2
vert.x-eventloop-thread-0
那是因为现在每个事件循环线程都绑定到一个单独的执行线程。