您可以在单个vert.x上运行Verticle的并发实例吗?这些实例是线程安全的吗?

人气:221 发布:2023-01-03 标签: thread-safety concurrency vert.x actor

问题描述

我知道这个问题已经被问过了,但我认为它从来没有得到过准确的答案。

Vert.x是否可以在单个Vert.x上运行同一Verticle的多个实例,这意味着单个Verticle可以在多个事件循环上运行?如果是这样的话,每个事件循环是运行相同的处理程序实例还是运行单独的处理程序实例,换句话说,是同一个Verticle的多个实例线程安全且不共享任何状态,还是会有并发问题?

根据Vert.x文档-

即使Vertx实例维护多个事件循环,任何 特定的处理程序永远不会并发执行,而且在大多数情况下 案例(工作者垂直对象除外)将始终被调用 使用完全相同的事件循环。

很难说它们到底是什么意思。

我想弄清楚Actor模型和Vert.x在并发性和线程映射方面的比较。到目前为止,Vert.x看起来就像Actors,Verticle是分配给单个线程的Actor的捆绑,潜在的唯一区别是在Vert.x中,一位代码可以在其他地方并发运行(在同一Vert.x上),尽管很可能作为具有其自己状态的单独实例运行,而对于Actors,这是严格禁止的,除非您将Actor作为单独的类复制,然后它是相同的。

推荐答案

可以,Vertx可以运行同一个Verticle的多个实例。

创建vertx实例时,它将创建一定数量的事件循环线程。默认情况下,它是计算机上CPU数量的2倍。

部署的所有vertiles都将被多路传输到这些线程上。您可以在4个事件循环线程上拥有100个verticle。

但是,一旦为Verticle分配了线程,它将始终从该事件循环线程执行。

如果某个地方有一个非原子/线程安全的全局变量,并且在多个事件循环上有verticle--从多个verticle同时访问该变量是不安全的。但在Verticle中,除非您启动自己的不同线程,否则一切都是线程安全的。

然而,无论如何,这不应该是处理它的方式。应用程序应该建模为垂直的,然后应该部署多个副本以利用您计算机上的所有内核。

Verticle内的所有内容都可以认为是线程安全的,因为它是单线程的。

如果多个顶点需要访问全局数据,则使用共享数据、EventBus、锁定或任何其他并发友好的数据结构,如并发散列映射。

需要理解的基本概念是,我希望我的代码作为单线程运行并保持安全,但我希望能够使用我机器上的所有核心。你怎么做到的?您可以通过部署Verticle的多个实例来实现这一点。每个实例都是单线程的,但由于存在多个实例,因此它们将利用所有CPU核心。

它类似于node.js--node js是单线程的,因此要利用机器上的所有核心,开发人员要部署进程的多个副本。JVM具有真正的线程化,因此我们在不同的线程上部署多个副本,而不是多个jvm/进程。

就演员模型而言,垂直可以被认为是演员。你不必以这种方式建模,因为vertx是不受影响的。并且消息通过EventBus在它们之间传递。Verticle是扁平的,没有层次结构或监督,不像Akka或Erlang的角色模型,您的用例可能需要也可能不需要。

20