Java Vert.x:具有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转/秒任务的最佳方案吗 当

假设您需要编写一个具有1000 RPM的服务器。未来的负荷可能会增加。服务器只提供一种请求-
getGender(name)
,该请求接受一个名称,并返回
Male
/
Female
。性别的确定是最简单的操作,需要单索引查找,其中索引是内存中的数据结构

如果理解正确,您可以创建单个
ServerVerticle
,并运行
Runtime.getRuntime().availableProcessor()
将作业委派到的工作程序verticle(请参阅下面的代码)

问题:

  • 这是完成1000转/秒任务的最佳方案吗
  • 当15名工人不足时,在请求高峰会发生什么?假设一个工人可以处理100转/秒。你有15个工人。但在高峰期,你有3000转。
    • 假设
      NetServer
      可以处理3000转/秒,但工人们坚持要处理它们。Vert.x是否有队列来等待请求?怎么做?如果有-工人失败时会发生什么
    • 假设
      NetServer
      无法处理3000 RPM—只需运行几个服务器实例。没有陷阱,对吧
  • TCP是任务的更好选择吗
  • x是多反应器,它像节点一样运行它的事件循环。
    ServerVerticle
    与事件循环在同一线程中运行,对吗
  • 如果您有16个内核,那么1个内核专用于事件循环,所以Vert.x将运行15个GendServerticles,对吗?没有更多的广告了
  • ServerVerticle.java


    这里有几个问题和一些关于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>