作为演员粒度
Akka actor granularity
我第一次尝试思考 Akka/actors,对每个 Actor 职责的粒度有点困惑。
在我的应用程序中有 Widget
可以是 registered/unregistered 和 WidgetRegistrar
。向 Registrar
注册自身,并将 Widget
传递给 registerWidget
方法:
interface WidgetRegistrar {
public void register(Widget w);
}
当 Widget
尝试注册时,会发生验证过程。如果此过程通过,则 Widget
会呈现一个 URL,必须不断(每秒一次)轮询和检查(使用 HTTP GET)以确保 URL 仍然健康。
我的问题是:这个工作量应该如何分配给演员?
我马上就能想到几种不同的策略:
WidgetRegistrar
actor 首先以某种方式委托给 WidgetVerifier
actor(见下文),如果验证通过,则使用 newly-registered/verified [=11] 更新 WidgetChecker
actor =]
WidgetVerifier
验证 Widget
尝试注册自身的 actor
- 1 master
WidgetChecker
为每个 registered/verified Widget
检查一个 URL
或不同的策略:
WidgetRegistrar
actor 首先以某种方式委托给 WidgetVerifier
actor(见下文),如果经过验证,则以某种方式实例化一个新的 WidgetChecker
actor(见下文)
WidgetVerifier
验证 Widget
尝试注册自身的 actor
- 1
WidgetChecker
每个 registered/verified Widget
或不同的策略:
WidgetRegistrar
actor 当场验证 Widget
s(而不是委托给单独的 actor),如果验证通过,更新 WidgetChecker
actor newly-registered/verified Widget
- 1 master
WidgetChecker
为每个 registered/verified Widget
检查一个 URL
...变体列表不断增加。
所以我问:Akka actor 的粒度是多少,我怎么知道什么时候应该将功能分解为另一个 actor 并以某种方式连接这两个 actor?
Akka 意识形态是 'let it crash',因此最好将具有潜在危险的功能隔离到一个单独的参与者中。
我会怎么做 - 演员层次结构示例:
/master
/validator
/authentication
/capability
/registrar
/widget1
/widget2
/widget3
假设您可能希望在您的注册商中拥有除 register/unregister 之外的针对单个小部件的更多功能,最好在特定根目录下分隔小部件 - 例如,如果您的小部件具有功能就像 'update',你在 /registrar/widget1
中调用这个逻辑,如果更新失败,widget1
actor 就会死掉。根据您的需要,您可能需要重新注册小部件,或设置主管层次结构以自动重启小部件参与者。
使用 validators/verifiers 和其他逻辑 - 您可以在验证器上构建管道(顺序处理)或分散-收集(并行),例如:
- /master 发送消息给/validator
AttemptRegister(WidgetInfo)
- /validator 将此消息发送给它的所有子节点(例如通过
ask
模式),并期待 Accept(WidgetInfo)
或 Reject(WidgetInfo)
- 如果没有拒绝 - 它会发送RegisterWidget
到 /registrar
并且注册商将产生一个新的 /registrar/widget2
.
当然,这完全取决于具体的用例——例如:
- 验证会崩溃或阻塞吗?那么你需要
/validator/capability/doOrDieActor1
- 您需要顺序 processing/pipeline 吗?你可能想要实现这个序列,比如
../authentication
将发送 Pass
或 Fail
到 ../authorization
,然后将它发送到 capability
等等 - 只有最后的演员会将 ValidationSucceeded
发送到 /validator
,后者又将 RegisterWidget
事件发送到 registrar
我第一次尝试思考 Akka/actors,对每个 Actor 职责的粒度有点困惑。
在我的应用程序中有 Widget
可以是 registered/unregistered 和 WidgetRegistrar
。向 Registrar
注册自身,并将 Widget
传递给 registerWidget
方法:
interface WidgetRegistrar {
public void register(Widget w);
}
当 Widget
尝试注册时,会发生验证过程。如果此过程通过,则 Widget
会呈现一个 URL,必须不断(每秒一次)轮询和检查(使用 HTTP GET)以确保 URL 仍然健康。
我的问题是:这个工作量应该如何分配给演员?
我马上就能想到几种不同的策略:
WidgetRegistrar
actor 首先以某种方式委托给WidgetVerifier
actor(见下文),如果验证通过,则使用 newly-registered/verified [=11] 更新WidgetChecker
actor =]WidgetVerifier
验证Widget
尝试注册自身的 actor- 1 master
WidgetChecker
为每个 registered/verifiedWidget
检查一个 URL
或不同的策略:
WidgetRegistrar
actor 首先以某种方式委托给WidgetVerifier
actor(见下文),如果经过验证,则以某种方式实例化一个新的WidgetChecker
actor(见下文)WidgetVerifier
验证Widget
尝试注册自身的 actor- 1
WidgetChecker
每个 registered/verifiedWidget
或不同的策略:
WidgetRegistrar
actor 当场验证Widget
s(而不是委托给单独的 actor),如果验证通过,更新WidgetChecker
actor newly-registered/verifiedWidget
- 1 master
WidgetChecker
为每个 registered/verifiedWidget
检查一个 URL
...变体列表不断增加。
所以我问:Akka actor 的粒度是多少,我怎么知道什么时候应该将功能分解为另一个 actor 并以某种方式连接这两个 actor?
Akka 意识形态是 'let it crash',因此最好将具有潜在危险的功能隔离到一个单独的参与者中。
我会怎么做 - 演员层次结构示例:
/master
/validator
/authentication
/capability
/registrar
/widget1
/widget2
/widget3
假设您可能希望在您的注册商中拥有除 register/unregister 之外的针对单个小部件的更多功能,最好在特定根目录下分隔小部件 - 例如,如果您的小部件具有功能就像 'update',你在 /registrar/widget1
中调用这个逻辑,如果更新失败,widget1
actor 就会死掉。根据您的需要,您可能需要重新注册小部件,或设置主管层次结构以自动重启小部件参与者。
使用 validators/verifiers 和其他逻辑 - 您可以在验证器上构建管道(顺序处理)或分散-收集(并行),例如:
- /master 发送消息给/validator
AttemptRegister(WidgetInfo)
- /validator 将此消息发送给它的所有子节点(例如通过
ask
模式),并期待Accept(WidgetInfo)
或Reject(WidgetInfo)
- 如果没有拒绝 - 它会发送RegisterWidget
到/registrar
并且注册商将产生一个新的/registrar/widget2
.
当然,这完全取决于具体的用例——例如:
- 验证会崩溃或阻塞吗?那么你需要
/validator/capability/doOrDieActor1
- 您需要顺序 processing/pipeline 吗?你可能想要实现这个序列,比如
../authentication
将发送Pass
或Fail
到../authorization
,然后将它发送到capability
等等 - 只有最后的演员会将ValidationSucceeded
发送到/validator
,后者又将RegisterWidget
事件发送到registrar