VB_*_*VB_ 4 java high-load reactor vert.x
假设你需要写一个1000 rps的服务器.未来的负荷可能会增长.服务器只提供一种请求 - getGender(name)接受名称,并返回Male/ Female.性别的确定是最简单的操作,需要单个索引查找,其中索引是内存中的数据结构.
如果理解正确 - 您创建单个ServerVerticle,并运行Runtime.getRuntime().availableProcessors()委托作业的工作者Verticle(请参阅下面的代码).
问题:
NetServer可以处理3000 rps,但工人坚持处理它们.让Vert.x有任何队列来保持等待请求吗?怎么做?如果有 - 工人失败会发生什么?NetServer无法处理3000 rps - 只运行服务器的几个实例.没有陷阱,对吧?ServerVerticle与事件循环在同一个线程中运行,对吧?ServerVerticle.java
public class ServerVerticle extends AbstractVerticle {
public static void main(String[] args) {
Consumer<Vertx> runner = vertx -> vertx.deployVerticle("ServerVerticle", new DeploymentOptions());
Vertx vertx = Vertx.vertx();
runner.accept(vertx);
}
@Override
public void start() throws Exception {
NetServerOptions options = new NetServerOptions();
NetServer server = vertx.createNetServer(options);
server.connectHandler(socket -> {
socket.handler(buffer -> {
vertx.eventBus.send("get.gender", buffer, res -> socket.write(res.toString()));
});
});
server.listen(1234, "localhost");
//Deploy worker verticles
DeploymentOptions deploymentOptions = new DeploymentOptions()
.setInstances(Runtime.getRuntime().availableProcessors())
.setWorker(true);
vertx.deployVerticle("GenderServiceVerticle", deploymentOptions);
}
}
Run Code Online (Sandbox Code Playgroud)
GenderVerticle.java
public class GenderVerticle extends AbstractVerticle {
@Override
public void start() throws Exception {
vertx.eventBus().consumer("get.gender", message -> {
String gender = singleIndexLookup(message);
message.reply(gender);
});
}
singleIndexLookup() { ... }
}
Run Code Online (Sandbox Code Playgroud)
这里有几个问题,对vert.x有一些误解.使用Verticles 实现代码后,您不需要实现自己的main方法,因为在木材下,内部main方法将使用什么来确保您可以拥有CPU能力的全部容量,而您不需要自己扩展它有:
//Deploy worker verticles
DeploymentOptions deploymentOptions = new DeploymentOptions()
.setInstances(Runtime.getRuntime().availableProcessors())
Run Code Online (Sandbox Code Playgroud)
您应该阅读文档的以下部分.
其次,你指的是你GenderVerticle作为一名工人,因为它会为你做一些操作.请注意vertx,工作者意味着它应该在专用线程池上执行,因为可能发生该Verticle中的代码将执行某些阻塞IO.
使用工作模式将导致性能损失,因为您失去了异步IO的好处,并且您的请求需要为池中的线程排队.
由于您的示例解释了您的所有代码都在内存中查找,我认为它是CPU限制而不是IO绑定,这意味着您应该避免将其部署为工作者.
回到你的例子,你有1个Verticle处理所有HTTP流量,第二个处理它.为了获得最佳性能,您可能只需要1个Verticle,因为跳数较少,但此解决方案不会水平扩展(问题的原因)如何处理3000rps,假设一个节点只能执行1000rps.
现在你已经走上了正确的道路,你将http处理与业务处理分开,它有一点点损失,但是如果你知道1个节点可以处理1000rps并且你必须至少处理3000rps所有你需要做的就是部署GenderVerticleon 3台额外的机器.
执行此操作并启用群集后,您可以通过添加依赖项(例如:hazelcast)来执行此操作:
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-hazelcast</artifactId>
<version>3.3.3</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
并通过标志启动您的应用程序--cluster.您将拥有一个由4台计算机组成的集群,其中请求将以循环方式对每个计算机进行负载平衡GenderVerticles.
由于HTTP代码是由netty高度优化的,因此您可能不需要多个服务器,如果不是这样,可以使用一个选项在服务器前添加流量负载均衡器并再次ServerVerticle在另一台机器上部署另一个在您的群集中,现在流量负载均衡器将负载平衡两个服务器之间的HTTP流量,这两个服务器将循环到GenderVerticles.
所以我猜你开始看到一种模式,一旦你的监控告诉你你的CPU/NetworkIO被最大化,你就会向集群添加更多的机器.