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