如何解决vertx如何创建事件循环线程
我尝试了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
打开Java VisualVM时,可以看到设置和不设置WorkerPoolName之间的区别。
Java visualVM image
设置它时,EventLoopPoolSize是偶数,则实际创建的线程数减半。
setWorkerPoolName()
怎么了?
解决方法
我阅读了源代码并发现了该方法
private static EventLoop getEventLoop(VertxInternal vertx) in io.vertx.core.impl.ContextImpl
有一个有趣的行为:无论是谁调用此方法,它都会一个接一个地从数组中给您一个EventLoop对象。它实际上是在io.netty.util.concurrent.DefaultEventExecutorChooserFactory.GenericEventExecutorChooser中实现的, 一个内部类,它具有next()
方法 @Override
public EventExecutor next() {
return executors[Math.abs(idx.getAndIncrement() % executors.length)];
}
因此,当您为EventLoop创建线程并准确获取所有与偶数(或奇数)索引相对应的所有EventLoop时,将错过EventLoop数组的一半。
并且,当顶点部署顶点时,它将查看您是否设置了WorkPoolName:
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,tccl));
如果您这样做了,它将为此步骤创建2个上下文。 这意味着它将调用getEventLoop()方法两次,以获取每个上下文的EventLoop。 总之,如果设置poolName,则每个Verticle在部署时将获得两次EventLoop,但只会创建一个线程。
我不知道这是否是一个bug,因为我刚接触vertx两天了,也不知道这是否是故意设计,我只想通过以下方式控制我的线程号setEventLoopPoolSize()方法。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。