Vertx 网络服务器仅使用一个事件循环线程,而 16 个可用

kat*_*rin 7 event-loop vert.x

我使用 Vert.x v3.5.1。有最简单的代码示例:

vertx.createHttpServer()
                    .requestHandler(anyRouter::accept)
                    .listen(8080);
Run Code Online (Sandbox Code Playgroud)

在我的例子中,事件循环组的大小是 16,所以我希望我的请求会影响 16 个线程。服务器已成功启动,但它仅在一个线程中工作。(我使用不同的 tcp-connections 发送请求,所以保持活动不是这里的原因。)
HttpServerImpl包含httpHandlerMgr并且这个管理器处理一个事件循环池(名为availableWorkers)。在调试期间,我看到这个池包含一个工人。

使用 Verticle 模型并不能解决问题,仍然没有使用所有线程。

如果我在循环中多次创建服务器,它会有所帮助。因此,我有许多受影响的线程和一台共享服务器。但它看起来像解决方法。

问题是如何创建使用所有可用事件循环线程的 Web 服务器?

下面使用 Verticle 实现

因此,该实现使用了一半的可用线程(8 个线程)。但我希望它使用 16 :)

public static void main(String[] args) throws Exception {
        int eventLoopSize = 16;
        Vertx vertx = new VertxOptions().setEventLoopPoolSize(eventLoopSize);
       for (int i=0;i<eventLoopSize; i++) {
           vertx.deployVerticle(new MyServer(vertx), deploymentOptions);
       }
    }

public class MyServer implements Verticle {
final Vertx vertx;
public MyServer(Vertx vertx) {
   this.vertx = vertx;
}

@Override
void init(Vertx vertx, Context context) {
vertx.createHttpServer()
                    .requestHandler(anyRouter::accept)
                    .listen(8080);
}
}
Run Code Online (Sandbox Code Playgroud)

tse*_*ont 6

只涉及一个线程,这正是事件循环模型。我推荐观看Philip Roberts:事件循环到底是什么?| JSConf 欧盟 2014 年。示例适用于浏览器,但概念与 Vert.x 或 Node 等服务器端事件循环系统相同。

但是,使用 Vert.x,您通常将代码组织在 Verticle 中(想想小型服务)。每个 Verticle 都分配了一个事件循环,但您可以部署多个实例。这就是您如何使用 CPU 的所有内核。如果您是 Java 程序员并且是第一次编写 Vert.x 应用程序,我建议您阅读本指南

至于将您的 Verticle 扩展到所有核心,问题在于当您自己实例化 Verticle 时,您实际上创建了单独的部署,并且无法保证使用不同的事件循环。

指定顶点实例数中所述,您必须使用顶点名称:

使用 Verticle 名称部署 Verticle 时,您可以指定要部署的 Verticle 实例数:

DeploymentOptions options = new DeploymentOptions().setInstances(16);
vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle", options);
Run Code Online (Sandbox Code Playgroud)

这对于跨多个内核轻松扩展非常有用。例如,您可能有一个 Web 服务器垂直要部署,并且您的机器上有多个核心,因此您希望部署多个实例以利用所有核心。