vertx如何创建eventloop线程



我尝试了DeploymentOptions.setEventLoopPoolSize(even number x),但它实际上创建了x/2个线程,奇数可以。

代码很简单,如下所示:

public final class Bootstrap {
private static final VertxOptions VERTX_OPTIONS;
private static final Vertx VERTX;
private static final DeploymentOptions HTTP_SERVER_DEPLOYMENT_OPTIONS;
static {
VERTX_OPTIONS = new VertxOptions();
VERTX_OPTIONS.setEventLoopPoolSize(22);
System.out.println("Event Loop Pool Size: " + VERTX_OPTIONS.getEventLoopPoolSize());
VERTX = Vertx.vertx(VERTX_OPTIONS);
HTTP_SERVER_DEPLOYMENT_OPTIONS = new DeploymentOptions();
HTTP_SERVER_DEPLOYMENT_OPTIONS.setInstances(24);
HTTP_SERVER_DEPLOYMENT_OPTIONS.setWorkerPoolName("http-server-worker");//remove this line you can create the right number of thread
}
public static void main(String[] args) {
VERTX.deployVerticle(MyHttpServer.class, HTTP_SERVER_DEPLOYMENT_OPTIONS, ar -> {
System.out.println("success");
System.out.println("is Worker? " + HTTP_SERVER_DEPLOYMENT_OPTIONS.isWorker());
});
}
}
public class MyHttpServer extends AbstractVerticle {
@Override
public void start(Promise<Void> startPromise) throws Exception {
Router router = Router.router(vertx);
String content = "I'm " + this + " thread: " + Thread.currentThread() + " router: " + router;
router.get("/").handler(context -> {
context.response().end(content);
});
vertx.createHttpServer().requestHandler(router).listen(80, ar -> {
if(ar.succeeded()) {
System.out.println("server start " + this);
startPromise.complete();
} else {
ar.cause().printStackTrace();
}
});
}
}

wertx web 3.9.2

打开JavaVisualVM时,您可以看到设置和不设置WorkerPoolName之间的区别。Java visualVM映像如果设置了它,并且EventLoopPoolSize是偶数,则实际创建的线程数将减半。setWorkerPoolName()怎么了?

我阅读了源代码,发现方法

private static EventLoop getEventLoop(VertxInternal vertx) in io.vertx.core.impl.ContextImpl

有一个有趣的行为:无论谁调用这个方法,它都会一个接一个地从数组中为您提供一个EventLoop对象。它实际上在io.netty.util.concurrent.DefaultEventExecutiorChooserFactory中实现。GenericEventExecutorChooser,一个内部类,它有一个方法next((

@Override
public EventExecutor next() {
return executors[Math.abs(idx.getAndIncrement() % executors.length)];
}

因此,当您为EventLoop创建一个线程,并精确地获取所有与偶数(或奇数(索引相对应的EventLoop时,EventLoop数组的一半将丢失。

并且,当vertx部署verticals时,它将查看您是否设置WorkerPoolName:

for (Verticle verticle: verticles) {
WorkerExecutorInternal workerExec = poolName != null ? vertx.createSharedWorkerExecutor(poolName, options.getWorkerPoolSize(), options.getMaxWorkerExecuteTime(), options.getMaxWorkerExecuteTimeUnit()) : null;
WorkerPool pool = workerExec != null ? workerExec.getPool() : null;
ContextImpl context = (ContextImpl) (options.isWorker() ? vertx.createWorkerContext(options.isMultiThreaded(), deploymentID, pool, conf, tccl) :
vertx.createEventLoopContext(deploymentID, pool, conf, tccl));

如果你这样做了,它将为这一步创建2个上下文。这意味着它将调用getEventLoop((方法两次,以获得每个Context的EventLoop。总之,如果设置poolName,则每个Verticle在部署时将获得两次EventLoop,但只会创建一个线程。

我不知道这是否是一个bug,因为我刚刚与vertx联系了两天,我不知道是否这是一个故意的设计。我只想通过setEventLoopPoolSize((方法来控制我的线程数。

相关内容

  • 没有找到相关文章

最新更新