Vertx事件总线的性能是否与Java中的ConcurrentQueues一样好或更好?

huangapple go评论125阅读模式
英文:

Is the performance of Vertx event bus as good or better than ConcurrentQueues in Java?

问题

在我的项目中,我决定使用Vertx来处理HTTP API,因为它已经证明了其出色的性能记录。然后,由于应用程序在内部使用事件队列,我开始考虑是否应该使用Vertx事件总线和顶点,而不是使用我的通常的ArrayBlockingQueue。我对Vertx还不太熟悉,所以我不知道它是否合适。我有使用Akka和Actors的经验,它们非常适合我的需求,但我不确定Vertx事件总线是否设计成每秒可扩展到10万个事件?

英文:

In a project of mine, I decided to use Vertx for the HTTP APIs, given its proven performance record. Then, because the application does use event queues internally I started wondering if I should use Vertx event bus and verticles, instead of using my usual ArrayBlockingQueue. I am still quite new to Vertx so I don't know how suitable it could be. I've experience with Akka and Actors and those would fit the bill very well, but I'm not sure if Vertx event bus is designed to scale to 100k events per second?

答案1

得分: 3

我从Vert.x版本3开始使用它,并且已经完成了一些项目(这是我的主要技术栈,已经有几年了)。我从未遇到过事件总线成为限制因素的情况。事件总线设计用于处理这么多事件,甚至更多。正如@injecteer所提到的,限制因素基本上是硬件,事件处理取决于您对它们的处理方式以及如何扩展代码。

Vert.x始终遵循非阻塞的编程模型,您也应该遵循这一模型...永远不要阻塞。Vert.x具有松散耦合的概念,通过“verticles”(https://vertx.io/docs/vertx-core/java/#_verticles)对代码进行分区处理来解决这个问题。您可以部署/启动多个这些verticle实例(代码片段)。另一个基本概念是事件循环线程(默认核心数*2)。

每个部署的verticle实例都将在特定的事件循环线程上运行,并且所有已注册的处理程序(事件总线、http服务器等)都会在任何时候在此特定的事件循环线程上调用。通过这种方式,您可以根据需要以“每个线程”方式扩展代码。事件总线上的事件在verticle实例之间(以及verticles内的处理程序)之间以轮询方式分发...顺便说一下,http请求的处理程序也以轮询方式分发。

集群模式有点不同。如何(反)序列化dto(Json、Protobuf等)在性能方面可能会有显著差异。集群事件总线在所有节点之间具有TCP套接字,这意味着事件是点对点发送的。另一方面,集群管理器(Hazelcast是默认值)定义了事件应发送到哪个节点(在集群级别上轮询),但事件不会通过集群管理器发送。例如,集群管理器知道哪个节点在事件总线上(在哪个地址上)注册了消费者。

自从Vert.x 4的里程碑5版本起,集群管理器SPI提供了一个入口点,您可以在其中实现自己的轮询替代方案,例如,特定的负载分布等。

有一些基本概念,如事件循环线程、非阻塞编程和verticles(这不是强制性的,但建议使用)。如果/当这些概念清晰明了,您将获得一个非常灵活的基础,适用于几乎任何类型的应用程序。我个人非常喜欢它,也从未见过任何其他框架/技术能够达到类似的性能(在适当的扩展负载下)。

英文:

I work with Vert.x since version 3 and have done some projects with it (It's my main stack, since a couple of years). I did never run into a situation where the event bus was the limiting factor. The event bus is designed to handle such an amount of event and even much more. As @injecteer mentioned, the limiting factor is basically the hardware and how many events will be processed depends on what do you with them and how you scale your code.

Vert.x follows consequently a non-blocking programming model and you should follow it as well ... never be blocking. Vert.x has the concept of loose coupling, that's solved with portioning of the code with "verticles" https://vertx.io/docs/vertx-core/java/#_verticles. You can deploy/start multiple instances of those verticles (your pieces of code). A further base concept is event loop threads (default count of cores * 2).

Each deployed verticle instance will run on a specific event loop thread, and ALL registered handlers (event bus, http server, etc.) are get called on this specific event loop thread at any time. This way you are able to scale your code in a "per thread" fashion, according to your needs. Events over the event bus are distributed with round robin between the verticle instance (and the handlers within the verticles) ... btw handlers of http requests are also distributed with round robin.

Clustered mode is a bit different. How do you (de)serialize dtos (Json, Protobuf, etc.) can become a significant difference in terms of performance. A clustered event bus has TCP sockets between all nodes, means events are sent point-to-point. The cluster manager (Hazelcast is the default) on the other hand defines to which node an event should get send to (round robin on cluster level), but events are NOT sent over the cluster manager. E.g. the cluster manager knows which node has consumers registered on the event bus (on which address).

Since Vert.x 4 milestone 5 the cluster manager SPI provides an entry point where you can implement your own alternative to round robin, e.g. load specific distribution etc.

There are some basic concepts like event loop threads, non-blocking programming, and verticles (which is not mandatory but recommended). If / when those concepts are clear you get a very flexible base for near any kind of application. I personally love it and also did never see any other framework/technology that reaches near a comparable performance (with a proper scaling that fit the load).

答案2

得分: 1

我对Vert.x事件总线进行了基准测试(仅使用纯Vert.x进行发布和订阅),发现其性能最高可达每CPU约100K消息/秒(使用高端Xeon CPU)。有趣的是,性能与Vert.x的WebSocket实现相当,所以我同意如果你这样做:

WebSocket -> 事件总线

但如果你在事件总线上进行10次跳转,那么它可能成为瓶颈。

我观察到LMAX Disrupter的性能要高得多,但一旦引入I/O,那么I/O就会成为Disrupter的瓶颈。Disrupter的问题在于你无法与Netty一起使用。

英文:

I benchmarked Vert.x event bus (using pure Vert.x for pub and sub) and found it to max out at around 100K msg/s / CPU (using high-end Xeon CPU). Interestingly the performance was comparable to Vert.x's WebSockets implementation so I agree it's not the bottleneck if you do:

WS -> Event Bus

But if you do 10 hops on the Event Bus then it could be the bottleneck.

I observed the performance of the LMAX Disrupter to be much higher but once you introduce I/O then the I/O become the bottleneck with Disrupter. The problem with disrupter is that you can't use it with Netty.

答案3

得分: 0

从我的理解来看,所有在单个JVM中运行的库都具有可比较的性能水平,并受到您的硬件和设置的限制。
因此,本地事件总线的性能与任何其他本地技术一样好。

当您将系统扩展到不同的JVM和/或不同的机器时,事情开始变得有趣。这就是Vert.x事件总线的亮点,因为您无需更改verticles的代码!

您只需用集群事件总线替换本地事件总线,这只涉及添加依赖项和配置集群,但仍然无需更改事件总线操作的原始代码。反之亦然,如果您想将多个verticles放入同一个JVM中,也可以正常工作。

事件总线的集群当然是有代价的,但其性能更多取决于底层的集群技术,如Hazelcast(默认)或Infinispan,而不是Vert.x本身。

英文:

From my understanding all libraries running in a single JVM would have comparable performance levels and are limited by your hardware and settings.
So, local event-bus would perform as good as any other local tech.

The things start getting interesting, if you scale up your system across different JVMs and/or different machines. This is where Vert.x EB shines, as you don't have to change the code of your verticles!

You replace the local EB with clustered one, which is a matter of adding dependencies and configuring the cluster, but still no original code for event-bus operations has to be changed. The other way around also works just fine, if you want to squeese several verticles into the same JVM.

Clustering of the EB of course has it's price, but it's performance has to do rather with underlying clustering technologies like Hazelcast (default) or Infinispan than with Vert.x itself.

huangapple
  • 本文由 发表于 2020年7月21日 20:12:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/63014319.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定