VERTX运行多个事件循环

发布于 2025-02-03 07:45:51 字数 2394 浏览 3 评论 0原文

我有一个需要垂直扩展的情况,因此我最终使用了20核5GB的虚拟机。

问题是,当我制作大量数据时,我看不到CPU不仅使用一个核心。我期望的是,在并行中看到20核

我尝试使用100线程的工作者创建Vertx

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

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

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

拥有此代码如何在没有bindaddress例外的情况下部署多个垂直,

@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);

获得绑定地址异常

解决方案

我设法部署了多个垂直,但是即使部署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));
});

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

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

任何想法为什么?

问候

I have a situation where I need to scale up vertically, so I end up with a Virtual machine with 20 cores and 5GB.

The problem is that when I make a very big load of data, I cannot see the CPU used more than just one core. And what I would expect is see running the 20 cores in parallel.

I've tried to create my Vertx with a Worker of 100 threads.

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

But still my service is not using all cores.

What else can I configure to allow my server run more request in parallel?

Having this code how can I deploy multiple Verticle without bindaddress exceptions

@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());
        }
    });
}

If I try

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

I get bind address exception

SOLUTION

I manage to deploy multiple verticles, but even deploying 20, I can only see in my logs run two event loops threads

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));
});

My Verticle need some dependencies in the constructor, and If I try to create multiple Verticle like this

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);

I got this error

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

Any idea why?

Regards

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不离久伴 2025-02-10 07:45:51

垂直默认值的实例是让事件循环池,其螺纹数= 2 *机器上的内核数。为了参数的缘故,让我们假设有x物理内核具有超线程;这意味着有2x虚拟内核。

这并不意味着垂直的一个实例将立即创建最大数量的线程数,该线程将相应地利用所有虚拟内核,而这些虚拟内核会导致所有x物理内核。这是由操作系统管理的。这将更接近多线程行为,而不是诸如Vert.x之类的框架的反应性事件驱动的行为。

在Vert.x中,实际创建的线程数是由框架动态管理的。 在这里 是一个很好的分析。遵守Vert.x的设计原理,例如编写非阻滞代码,利用工作池将是优化性能的方法。专门用于数量的实例,我找到了 this 这表明从一个实例开始物理核心并扩展到测试。

这是我用来测试您的示例的完整代码,在该示例中,我能够通过多个实例部署垂直。

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());
            }
        });
    }
}

An instance of a verticle defaults to having an event loop pool with number of threads = 2 * number of cores on the machine. For argument's sake, let us assume that there are x physical cores with hyperthreading; this means that there are 2x virtual cores.

This does not mean that a single instance of the verticle will immediately create the maximum number of threads, that will correspondingly utilize all of the virtual cores, which with hyperthreading would cause all x physical cores to be utilized (this is managed by the OS). This would be closer to multithreading behaviour as opposed to reactive, event-driven behaviour of a framework like Vert.x.

In Vert.x, the number of threads actually created are dynamically managed by the framework. Here is a nice analysis of the same. Adherence to the design principles of Vert.x such as writing non-blocking code, utilizing worker pools would be the way to optimize performance. Specifically for number of instances, I found this that suggests starting with one instance per physical core and scaling up to test.

Here is the complete code I used to test your example, where I was able to deploy the verticle with multiple instances.

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());
            }
        });
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文