我正在服务架构中写一个可靠的演员,他的工作就是听取Firebase DB中的变化并根据这些变化运行逻辑。我有它的功能,但不正确。到目前为止我所做的是使用名为MonitorRules()的方法编写actor代码,该方法使用名为FireSharp的C#Firebase客户端包装器来监听Firebase。 MonitorRules()看起来像这样:
public async Task MonitorRules()
{
FireSharp.FirebaseClient client = new FireSharp.FirebaseClient(new FireSharp.Config.FirebaseConfig
{
AuthSecret = "My5up3rS3cr3tAu7h53cr37",
BasePath = "https://myapp.firebaseio.com/"
});
await client.OnAsync("businessRules",
added: (sender, args) =>
{
ActorEventSource.Current.ActorMessage(this, $"{args.Data} added at {args.Path}");
},
changed: (sender, args) =>
{
ActorEventSource.Current.ActorMessage(this, $"{args.OldData} changed to {args.Data} at {args.Path}");
}
);
}
然后在服务的Main()方法中注册服务后调用MonitorRules():
fabricRuntime.RegisterActor<RuleMonitor>();
var serviceUri = new Uri("fabric:/MyApp.RuleEngine/RuleMonitorActorService");
var actorId = ActorId.NewId();
var ruleMonitor = ActorProxy.Create<IRuleMonitor>(actorId, serviceUri);
ruleMonitor.MonitorRules();
此“有效”,即服务打开与Firebase的连接并响应数据更改。问题是,由于服务在五个节点集群的三个节点上运行,因此它实际上是在监听三次并处理每个消息三次。此外,如果暂时没有活动,则会停用该服务,并且不再响应Firebase中的更改。总而言之,不是正确设置这样的东西的方式我确定,但我找不到任何关于如何在服务结构中设置这样的轮询客户端的文档。有没有办法设置这个符合天蓝色服务结构的精神?
答案 0 :(得分:7)
是的,这里有一些事情要熟悉。第一个是Actor lifecycle and garbage collection。 Tl; dr:如果演员没有收到客户请求(通过ActorProxy)或者提醒一段时间(可配置),则会停用演员。
其次,演员有Timers and Reminders可用于定期工作,例如轮询数据库以进行更改。计时器和提醒之间的区别在于计时器不算作“正在使用”,这意味着仍然可以停用演员关闭计时器,但提醒计为“正在使用”,并且还可以重新激活停用演员。考虑定时器和提醒的方法是你正在进行轮询,而不是等待像你在这里使用FireSharp那样的回调。
最后,从Main()调用MonitorRules并不是最好的主意。原因是Main()实际上是您的actor服务主机进程的入口点,这只是一个用于托管actor实例的EXE。在Main()中应该发生的唯一的事情是注册你的actor类型而不是其他任何东西。让我们更详细地看看这里发生了什么:
因此,您将actor服务部署到群集。首先发生的是我们在必要的节点上启动主机进程来运行actor服务(在你的情况下为3)。我们进入Main(),其中演员服务类型被注册,此时,我们应该这一切,因为一旦演员服务注册到主机进程,我们将创建一个实例(或多个实例或副本(如果它是有状态的)服务,然后服务可以开始执行其工作。对于actor,这意味着当客户端应用程序使用ActorProxy进行调用时,actor服务已准备好开始激活actor。但是使用Main()中的ActorProxy调用,你基本上是说“当主机启动时,在主机启动的每个节点上激活一个actor”,这就是你正在听三次的原因。
考虑到所有这些,首先要问自己的问题是演员是否适合你。如果您只想要一个使用FireSharp客户端监控Firebase的简单位置,可能更容易使用reliable service,因为您可以将监控放在RunAsync中,该服务在服务启动时自动启动,而不像需要的人员客户端激活它们。