我遇到了需要纵向扩展的情况,所以我最终得到了一个具有 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());
}
});
}
}
https://stackoverflow.com/questions/72454356/