在Service Fabric Reliable Actors Introduction(由Microsoft提供的文档中)中,声明Actor不应“ ”通过发出I / O操作来阻止具有不可预测延迟的调用者。”
我不确定如何解释这一点。
这是否意味着只要请求的延迟是可预测的,I / O就可以了?
或
这是否暗示最佳实践是Actor不应在Service Fabric之外进行任何I / O操作?例如:写入某种REST API或写入某种类型的数据库,数据湖或事件中心。
答案 0 :(得分:1)
从技术上讲,两者兼而有之。
由于actor是单线程的,因此actor中只能同时执行单个操作。
SF Actor使用Ask方法,其中每个呼叫都期望一个答案,如果该Actor收到来自客户的太多呼叫,并且该Actor过于依赖外部组件,则每个呼叫者都会进行呼叫并一直等待答案。处理每个呼叫将花费太长时间,所有其他客户端呼叫将进入队列,并且可能会在某些时候失败,因为它们将等待太长时间且超时。
对于像Akka这样的使用Tell方法的演员来说,这不是什么大问题,因为它不等待答案,它只是将邮件发送到邮箱并收到包含答案的邮件(适用时) 。但是请求和响应之间的延迟仍然是一个问题,因为单个参与者无法处理太多消息。另一方面,如果一个命令失败,则可能会增加复杂性,并且在您知道第一个命令的答案之前会触发2或3个事件序列(此处不是作用域,但您将这种情况与以下示例相关联)。
关于第二点,Actor的主要思想是自给自足,如果它过于依赖外部依赖关系,也许您应该重新考虑设计并评估Actor实际上是否是解决问题的最佳设计。 / p>
自包含角色是可伸缩的,他们不依赖外部状态管理器来管理自己的状态,他们不依赖其他角色来完成任务,它们可以彼此独立地扩展。
示例:
(ActorTypeA的)Actor1依赖于(ActorTypeB的)Actor2执行操作。
要使其更加人性化,可以说:
每当客户(用户)与他的结帐购物车进行交互,添加或删除产品时,它将向Actor1发送添加和删除命令以管理自己的购物车。在这种情况下,依赖关系是一对一的,当另一个用户导航到该网站时,将创建另一个参与者来管理他自己的购物车。在这两种情况下,他们都有自己的演员。
现在让我们说,每当将商品放入购物车时,都将保留库存,以避免同一商品的重复销售。
在这种情况下,两个Actor都将尝试在Actor2中保留产品,并且由于Actor具有单线程特性,如果产品没有库存,则只有第一个会成功,第二个将等待第一个完成并失败不再。另外,第二位用户将无法在其购物车中添加或删除任何产品,因为第一个操作正在等待完成。现在,将这些数字增加成千上万,看看问题是如何迅速发展且可伸缩性失败的。
这只是一个小而简单的示例,因此,第二点不仅适用于外部依赖关系,它还适用于内部依赖关系,actor外部的每个操作都会降低其可伸缩性。
说,您应该尽可能避免外部(actor外部)依赖关系,但是如果需要的话,这并不是犯罪,但是当外部依赖关系限制其独立扩展时,您将降低可伸缩性。
>This other SO question我回答过的您可能也很感兴趣。