java - 消息驱动应用程序简单方法调用之间的差异

标签 java concurrency akka quasar

我一直在阅读相关内容,发现一些库确实扰乱了我的想法,例如 Akka、Quasar、Reactor 和 Disruptor,Akka 和 Quasar 实现了 Actor 模式,Disruptor 是一个线程间消息传递库,而 Reactor是基于 。那么,与简单方法调用相比,使用消息驱动架构的优势和用例是什么?

给定一个 RabbitMQ 队列监听器,我从该方法接收一条消息,确定 RabbitMQ 消息的类型(NewOrderPayment,...)。

使用消息驱动库我可以做到。

伪代码:

actor.tell('决策者邮箱',消息)

这基本上是说“我把这条消息放在这里,当你们可以处理它时,就去做”)等等,直到它被保存。 Actor 再次准备好接收另一条消息

但是直接调用像 messageHandler.handle(message) 这样的方法,不是更好、更少抽象吗?

最佳答案

Actors Model看起来很像人们一起工作;它基于消息传递,但还有更多内容,我想说并非所有消息传递模型都是相同的,例如 Quasar实际上不仅支持类似 Erlang 的 actor,还支持类似 Go 的 channel ,这些 channel 更简单,但不提供容错模型(还有光纤,顺便说一句,它们就像线程一样,但更轻量级,即使没有任何消息,你也可以使用它-完全通过)。

方法/函数遵循严格的、可嵌套的调用-返回(即请求-响应)规则,并且通常不涉及任何并发性(至少在命令式和非纯函数式语言中)。

消息传递,从广义上来说,允许松散耦合,因为它不强制执行请求-响应规则,并允许通信各方同时执行,这也有助于隔离故障、热升级和一般维护(例如,Actors 模型提供这些功能)。通常,消息传递还可以通过使用更动态的消息类型来允许更宽松的数据契约(对于参与者模型尤其如此,其中每一方或参与者都有一个传入 channel ,即他的邮箱)。 除此之外,细节在很大程度上取决于您正在考虑的消息传递模型/解决方案,例如通信 channel 可以同步交互部分或具有有限/无限缓冲,允许多个源和/或多个生产者和消费者等

请注意RPC确实是消息传递,但具有严格的请求-响应通信规则。

这意味着,根据具体情况,其中一个可能更适合您:当您处于调用返回规则和/或您只是使您的顺序代码更加模块化。当您需要一个潜在并发的、自治的“代理”网络来进行通信但不一定按照请求-响应规则进行通信时,消息传递会更好。

至于 Actor 模型,我认为您可以对此有更多的了解,例如 by reading the first part of this blog post (注意:我是这篇文章的主要作者,也是 Parallel Universe - 和 Quasar - 开发团队的一员):

The actor model is a design pattern for fault-tolerant and highly scalable systems. Actors are independent worker-modules that communicate with other actors only through message-passing, can fail in isolation from other actors but can monitor other actors for failure and take some recovery measures when that happens. Actors are simple, isolated yet coordinated, concurrent workers.

Actor-based design brings many benefits:

  • Adaptive behaviour: interacting only through a message-queue makes actors loosely coupled and allows them to:
    • Isolate faults: mailboxes are decoupling message queues that allow actor restart without service disruption.
    • Manage evolution: they enable actor replacement without service disruption.
    • Regulate concurrency: receiving messages very often and discarding overflow or, alternatively, increasing mailbox size can maximize concurrency at the expense of reliability or memory usage respectively.
    • Regulate load: reducing the frequency of receive calls and using small mailboxes reduces concurrency and increases latencies, applying back-pressure through the boundaries of the actor system.
  • Maximum concurrency capacity:
    • Actors are extremely lightweight both in memory consumption and management overhead, so it’s possible to spawn even millions in a single box.
    • Because actors do not share state, they can safely run in parallel.
  • Low complexity:
    • Each actor can implements stateful behaviour by mutating its private state without worrying about concurrent modification.
    • Actors can simplify their state transition logic by selectively receiving messages from the mailbox in logical, rather than arrival order.

关于java - 消息驱动应用程序简单方法调用之间的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32390586/

相关文章:

Java国际地址解析

java - 为什么这个 FindBugs 警告没有被抑制?

java - 包结构应该与 Java "always"中的目录结构相同?

c++ - thread::hardware_concurrency() 作为模板参数

scala - Akka 在 Play 中如何使用?

java - 发现 JSTL 时区 (KST) 实现错误

concurrency - Erlang:设计一个不可变但启动缓慢的服务组件

java - 收到 ConcurrentModificationException 但我没有删除

scala - 如何使用 Akka 2.1.2 可视化 Actor 消息流?

scala - 在 Akka 中,如何将响应从下游参与者路由到正确的上游?