gpt4 book ai didi

java - Vertx 运行多个事件循环

转载 作者:行者123 更新时间:2023-12-05 04:28:59 27 4
gpt4 key购买 nike

我遇到了需要纵向扩展的情况,所以我最终得到了一个具有 20 核5GB 的虚拟机。

问题是,当我加载大量数据时,我看不到 CPU 只使用了一个内核。我希望看到 20 个内核并行 运行。

我尝试使用 100 线程的 Worker 创建我的 Vertx

VertxOptions options = new VertxOptions().setWorkerPoolSize(100);
this.asyncFlowVertx = Vertx.vertx(options);

但我的服务仍然没有使用所有内核。

我还可以配置什么以允许我的服务器并行运行更多请求?

有了这段代码,我如何在没有绑定(bind)地址异常的情况下部署多个 Verticle

@Override
public void start(Promise<Void> startPromise) {
logger.info("Preparing Async Flow Http proxy server....");
Router router = Router.router(asyncFlowVertx);
router.route().handler(BodyHandler.create());
router.route(GET, "/ready").respond(ctx -> Future.succeededFuture());
router.route(GET, "/health").respond(ctx -> Future.succeededFuture());
router.route(POST, "/request").respond(this::processRequest);
router.route(POST, "/response").respond(this::processResponse);

server = asyncFlowVertx.createHttpServer();
server.requestHandler(router).listen(port, http -> {
if (http.succeeded()) {
logger.info("Async-flow-http-proxy running......");
startPromise.complete();
} else {
startPromise.fail(http.cause());
}
});
}

如果我尝试

DeploymentOptions options = new DeploymentOptions().setInstances(20);
vertx.deployVerticle("com.bla.MyVerticle", options);

我得到绑定(bind)地址异常

解决方案

我设法部署了多个 Verticle,但即使部署了 20 个,我也只能在我的日志中看到运行两个事件循环线程

var vertx = Vertx.vertx();
Router router = Router.router(vertx);
IntStream.range(0,20).forEach(i -> {
logger.info("Creating Vertx Verticle {}", i);
vertx.deployVerticle(new AsyncFlowHttpProxy(router));
});

我的 Verticle 在构造函数中需要一些依赖项,如果我尝试像这样创建多个 Verticle

VertxOptions options = new VertxOptions();
options.setWorkerPoolSize(100);
var vertx = Vertx.vertx(options);
Router router = Router.router(vertx);
DeploymentOptions deploymentOptions = new DeploymentOptions().setInstances(20);
vertx.deployVerticle(new AsyncFlowHttpProxy(port, nextServicePort, nextServiceName, router), deploymentOptions);

我遇到了这个错误

java.lang.IllegalArgumentException: Can't specify > 1 instances for already created verticle

知道为什么吗?

问候

最佳答案

Verticle 的实例默认有一个事件循环池,线程数 = 2 * 机器上的核心数。为了便于讨论,让我们假设有 x 个具有超线程的物理内核;这意味着有 2x 个虚拟内核。

这并不意味着 Verticle 的单个实例将立即创建最大数量的线程,这将相应地利用所有虚拟核心,而超线程会导致所有 x 物理核心被利用(这是由操作系统管理的)。这将更接近于多线程行为,而不是像 Vert.x 这样的框架的响应式(Reactive)、事件驱动的行为。

在Vert.x中,实际创建的线程数是由框架动态管理的。 Here是对相同的很好的分析。坚持 Vert.x 的设计原则,例如编写非阻塞代码,利用工作池将是优化性能的方法。专门针对实例数量,我找到了 this这建议从每个物理核心一个实例开始,然后扩展到测试。

这是我用来测试您的示例的完整代码,我可以在其中部署具有多个实例的 Verticle。

public class TestVerticle extends AbstractVerticle {

private static final Logger LOGGER = LoggerFactory.getLogger(TestVerticle.class);

private static Vertx vertx;

public static void main(String[] args) {
VertxOptions options = new VertxOptions().setWorkerPoolSize(100);
DeploymentOptions deploymentOptions = new DeploymentOptions().setInstances(20);
vertx = Vertx.vertx(options);
vertx.deployVerticle(TestVerticle.class, deploymentOptions);
}

@Override
public void start(Promise<Void> startPromise) {
LOGGER.info("Preparing Async Flow Http proxy server....");
Router router = Router.router(vertx);
router.route().handler(BodyHandler.create());
router.route(GET, "/ready").respond(ctx -> Future.succeededFuture());
router.route(GET, "/health").respond(ctx -> Future.succeededFuture());
router.route(GET, "/request").respond(ctx -> Future.succeededFuture(new JsonObject().put("hello", "world")));

HttpServer server = vertx.createHttpServer();
server.requestHandler(router).listen(8080, http -> {
if (http.succeeded()) {
LOGGER.info("Async-flow-http-proxy running......");
startPromise.complete();
} else {
startPromise.fail(http.cause());
}
});
}
}

关于java - Vertx 运行多个事件循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72454356/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com