本文介绍了Vertx 网络服务器仅使用一个事件循环线程,而 16 个可用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I use Vert.x v3.5.1.There is the simplest sample of code:

vertx.createHttpServer()
                    .requestHandler(anyRouter::accept)
                    .listen(8080);

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

In my case the event loop group size is 16 so I expect that my requests will affect 16 threads. Server is started succesfully but it works only in one thread. (I sent request using different tcp-connections so keep-alive is not a reason here.)
Class HttpServerImpl contains httpHandlerMgr and this manager handles a pool of event loops (named availableWorkers). And during debug I saw that this pool contains only one worker.

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

Using of Verticle model doesn't resolve the issue, still not all of threads are used.

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

If I create server many times in loop, it helps. As a result I have many affected threads and one shared server. But it looks like workaround.

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

The question is how to create web server that uses all available event-loop threads?

下面使用 Verticle 实现

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

As a result this implementation uses half of available threads (8 threads). But I want it to use 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);
}
}

推荐答案

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

There's a single thread involved, that's precisely the event loop model. I recommend watching Philip Roberts: What the heck is the event loop anyway? | JSConf EU 2014. Examples are for the browser but the concepts are the same for server-side event loop systems like Vert.x or Node.

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

However, with Vert.x you usually organize your code in verticles (think small services). Each verticle is assigned an event loop but you can deploy multiple instances. This is how you get to use all the cores of your CPUs. If you're a Java programmer and writing a Vert.x application for the first time I recommend reading this guide.

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

As for scaling your verticle to all the cores, the problem is that when you instantiate the verticle yourself you actually create separate deployments and have no guarantee with respect to using different event loops.

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

As explained in Specifying number of verticle instances, you must use the verticle name:

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

DeploymentOptions options = new DeploymentOptions().setInstances(16);
vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle", options);

这对于跨多个内核轻松扩展非常有用.例如你可能有一个网络服务器垂直部署和多个核心你的机器,所以你想部署多个实例来利用所有核心.

This is useful for scaling easily across multiple cores. For example you might have a web-server verticle to deploy and multiple cores on your machine, so you want to deploy multiple instances to utilise all the cores.

这篇关于Vertx 网络服务器仅使用一个事件循环线程,而 16 个可用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-05 10:15