Akka 和单身演员

Geo*_*rge 1 scala actor akka akka-http akka-actor

我最近开始摆弄 akka 的 actor 和 http 模块。然而,我偶然发现了一个相当烦人的小怪癖,即创建单一演员。

下面是两个例子:

1)

我有一个内存缓存,我的服务非常小(它是一个应用程序),所以我真的很喜欢这个内存模型。我可以在 Map 中保存与用户相关的大多数信息(嗯,列表的映射,但仍然很容易推理结构),并且我没有得到 redis、geode 或 aerospike 的开销和复杂性。

唯一的问题是这个内存中的缓存可以被多个源修改,并且所述修改必须是同步的。我没有同步该结构的所有 3 个访问方法(例如,通过构建消息队列或实现锁),而是将结构及其访问方法包装到参与者中,构建消息队列,简单的接收->发送逻辑和如果规模扩大,将很容易用 DA actor 代替专用的内存数据库。

2)我有一个“服务”层,应该用于为各种作业调度参与者(访问数据库,访问内存缓存,使用数据进行计算并将结果传递给用户......等)。

将此服务层理解为某种“单例”,即某些功能的闭包,因为它不执行任何阻塞或 CPU/内存密集型操作,它只是简单地向下分配任务(例如,决定有多少个任务)。演员/线程/我们应该被创建以及请求应该去哪里)

然而,这件事需要:

a) 使两个对象成为单例参与者或

b) 使两个对象都成为实际的“对象”(如在 scala 对象表示法中指定单个命名单例,其函数在其范围内具有闭包)

b) 存在很多问题,即服务层必须将 Actor 系统“传递”给它(我不确定这是最佳实践),以便创建 Actor,而不是创建自己的 Actor “childrens” 它将使用全局参与者系统创建儿童,并且消息传递和监控逻辑将更加尴尬和不直观。另外,内存中的缓存不会具有内置消息队列的优势(我并不是说它很难实现,但这似乎是其中一种情况,人们会说“哦,高兴,这很好,我有演员,我不必花时间实现和测试此代码”)

a) 一般而言,似乎存在 akka 文档中记录不足且未建议的问题。我是说:

http://doc.akka.io/docs/akka/2.4/scala/cluster-singleton.html

看看这个狗屎,一半的文档警告不要使用它,它是它自己的依赖项,坦率地说,对于像我这样还没有涉足函数式和并发编程象牙塔的可怜的草皮来说,它很难阅读。

所以,嗯。你们中的任何人都可以向我解释为什么使用单例演员不好吗?如果他们不能成为演员,你如何设计单身人士?有没有什么方法可以设计出不会造成大量损坏的单例演员?整个“服务”模型是否具有“全局”服务,这些服务被调用而不是实例化“un akka like”?

emo*_*rol 5

只是为了澄清文档,他们并没有警告不要使用它。他们警告说,在某些情况下使用单例会导致问题,考虑到这种情况,这是预料之中的。他们提到了以下情况:

  • 如果单例是性能瓶颈。这是有道理的。如果一切都依赖于一个运行缓慢的对象,那么一切都会很慢。
  • 如果参与者需要不间断地可用,那么如果单例发生故障,您就会遇到问题,因为这些消息不能仅由另一个实例处理。重新启动单例需要一段时间才能恢复工作。
  • 如果您打开了自动关闭功能,就会出现最大的问题。自动关闭是一种策略,通过该策略假定无法访问的节点已关闭并从网络中删除。如果您这样做,但该节点实际上并未关闭,而只是由于网络分区而无法访问,则分区的两侧将决定它们是幸存的节点并创建自己的单例。所以现在你有两个单身人士。当然,这不是您想要从单身人士那里得到的。但无论如何,您都不应该在测试之外使用自动关闭功能。这是一个糟糕的恢复策略,它是为了测试的完整性和方便性而包含在内的。

所以我并不认为这是建议不要使用它。只要根据结构的性质清楚使用它时预期的陷阱即可。