假设您需要编写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);
}
}
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() { ... }
}
答案 0 :(得分:6)
这里有几个问题,对vert.x有一些误解。使用Verticle
实现代码后,您不需要实现自己的main
方法,因为在内部main
方法下,内部//Deploy worker verticles
DeploymentOptions deploymentOptions = new DeploymentOptions()
.setInstances(Runtime.getRuntime().availableProcessors())
方法将确保您拥有完全满足您的CPU功率,您无需自行扩展:
GenderVerticle
您应该阅读documentation的以下部分。
其次,您指的是vertx
作为工作人员,因为它会为您执行某些操作。请注意,在GenderVerticle
中, worker 表示它应该在专用线程池上执行,因为可能发生该Verticle中的代码将执行某些阻塞IO。
使用 worker 模式会导致性能下降,因为您失去了异步IO的好处,并且您的请求需要为池中的线程排队。
由于您的示例解释了您的所有代码都是内存查找,我认为它是CPU限制而不是IO绑定,这意味着您应该避免将其部署为工作者。
回到你的例子,你有1个Verticle处理所有HTTP流量,第二个处理它。为了获得最佳性能,您可能只需要1个Verticle,因为跳数较少,但此解决方案不会水平扩展(问题的原因)如何处理3000rps,假设一个节点只能执行1000rps。
现在你已经走上了正确的道路,你将http处理与业务处理分开,它有一点点损失,但是如果你知道1个节点可以处理1000rps并且你必须至少处理3000rps所有你需要做的就是在3台额外的机器上部署<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-hazelcast</artifactId>
<version>3.3.3</version>
</dependency>
。
执行此操作并启用群集后,您可以通过添加依赖项(例如:hazelcast)来执行此操作:
--cluster
使用标记GenderVerticles
启动应用程序。您将拥有一台包含4台计算机的集群,其中请求将以循环方式对每个ServerVerticle
进行负载平衡。
由于netty对HTTP代码进行了高度优化,因此您可能不需要多个服务器,如果不是这样,可以使用一个选项在服务器前添加流量负载均衡器并再次部署另一个服务器GenderVerticles
在群集中的另一台计算机上,现在流量负载均衡器将对2个服务器之间的HTTP流量进行负载均衡,这些服务器将循环到$date = Carbon::now(); // or $date = new Carbon();
$date->setISODate(2016,42); // 2016-10-17 23:59:59.000000
echo $date->startOfWeek(); // 2016-10-17 00:00:00.000000
echo $date->endOfWeek(); // 2016-10-23 23:59:59.000000
。
所以我猜你开始看到一种模式,一旦你的监控告诉你你的CPU / NetworkIO被最大化,你就会向集群中添加更多的机器。