Java Vert.x:具有1000 RPM的最简单服务器
假设您需要编写一个具有1000 RPM的服务器。未来的负荷可能会增加。服务器只提供一种请求-Java Vert.x:具有1000 RPM的最简单服务器,java,vert.x,reactor,high-load,Java,Vert.x,Reactor,High Load,假设您需要编写一个具有1000 RPM的服务器。未来的负荷可能会增加。服务器只提供一种请求-getGender(name),该请求接受一个名称,并返回Male/Female。性别的确定是最简单的操作,需要单索引查找,其中索引是内存中的数据结构 如果理解正确,您可以创建单个ServerVerticle,并运行Runtime.getRuntime().availableProcessor()将作业委派到的工作程序verticle(请参阅下面的代码) 问题: 这是完成1000转/秒任务的最佳方案吗 当
getGender(name)
,该请求接受一个名称,并返回Male
/Female
。性别的确定是最简单的操作,需要单索引查找,其中索引是内存中的数据结构
如果理解正确,您可以创建单个ServerVerticle
,并运行Runtime.getRuntime().availableProcessor()
将作业委派到的工作程序verticle(请参阅下面的代码)
问题:
- 假设
可以处理3000转/秒,但工人们坚持要处理它们。Vert.x是否有队列来等待请求?怎么做?如果有-工人失败时会发生什么NetServer
- 假设
无法处理3000 RPM—只需运行几个服务器实例。没有陷阱,对吧NetServer
ServerVerticle
与事件循环在同一线程中运行,对吗这里有几个问题和一些关于vert.x的误解。一旦您使用
Verticle
s实现了您的代码,您就不需要实现自己的main
方法,因为在木头下面,内部main
方法将实现什么,以确保您可以拥有CPU的全部容量,并且您不需要使用以下方法来扩展它:
//Deploy worker verticles
DeploymentOptions deploymentOptions = new DeploymentOptions()
.setInstances(Runtime.getRuntime().availableProcessors())
您应该阅读本手册的以下部分
其次,您将您的genderticle
称为工作者,因为它将为您执行一些操作。请注意,在vertx
中,worker意味着它应该在专用线程池上执行,因为该垂直中的代码可能会执行某些阻塞IO
使用worker模式将带来性能损失,因为您失去了异步IO的好处,并且您的请求需要排队等待池中的线程
因为您的示例解释了您的代码所做的只是内存中的查找,所以我假设它是CPU绑定的,而不是IO绑定的,这意味着您应该避免将其部署为工作程序
回到您的示例,您有一个垂直通道处理所有HTTP流量,另一个垂直通道处理HTTP流量。为了获得最佳性能,您可能希望只有1个垂直点,因为跳数较少,但此解决方案不能水平扩展(您问题的原因)假设一个节点只能执行1000转,如何处理3000转/秒
现在,您已经走上了正确的道路,您将http处理与业务处理分离,这有一点损失,但是如果您知道一个节点可以处理1000rpm,并且必须至少处理3000rpm,那么您需要做的就是在3台额外的机器上部署genderticle
完成此操作并启用集群后,您可以通过添加依赖项(例如:hazelcast)来完成此操作:
io.vertx
Vertex hazelcast
3.3.3
通过使用标志--cluster
启动应用程序。您将拥有一个由4台计算机组成的集群,其中请求将以循环方式负载均衡到每个genderticles
由于netty对HTTP代码进行了高度优化,您可能不需要多台服务器,如果不是这样,您可以选择在服务器前面添加流量负载平衡器,然后在群集中的另一台机器上再次部署另一台ServerVerticle
,现在,流量负载平衡器将在两台服务器之间对HTTP流量进行负载平衡,这两台服务器将循环到genderticles
因此,我猜您开始看到这样一种模式:一旦您的监控告诉您您的CPU/NetworkIO已达到最大值,您就会向集群添加更多的计算机。感谢您的充分披露!但是,你能解释一下,如果我每台机器只有一个ServerVerticle/GendServerticle,我将如何从多线程/多核中获益吗?如果Vert.x只有一个垂直体,它将如何在单机上并行化请求处理?抱歉,没有通过链接找到我不需要main method和manuall CPU匹配的原因。这段代码
Runtime.getRuntime().availableProcessors()
也取自同一个文档。换句话说,集群是一个解决方案,但如何从Vert.x单机的所有16核中获益?文档可能不清楚,但是默认启动器的默认行为是,它将始终为每个CPU核心生成一个事件循环。因此,在16核的情况下,将有16个事件循环。这将最大限度地提高您的CPU使用率。答案就在这里:但是如果你使用默认的启动器,它是否是开箱即用的还不清楚。请再问一个问题-如果我有ServerVerticle
和genderticle
作为标准工作线程,默认情况下Vert.x将在单个实例中部署它们。因此将有一个genderticle
实例和16个事件循环,对吗?并发将如何实现?假设您的实例确实实施了某种类型的锁定(例如在某个地方有一个同步块),那么您可能无法使用事件循环的全部容量,在这种情况下,您可以使用命令行参数--instances N
来调整性能,这将生成垂直图标的N
实例
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() { ... }
}
//Deploy worker verticles
DeploymentOptions deploymentOptions = new DeploymentOptions()
.setInstances(Runtime.getRuntime().availableProcessors())
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-hazelcast</artifactId>
<version>3.3.3</version>
</dependency>