我正在服务架构中写一个可靠的演员,他的工作是听取Firebase数据库中的更改并根据这些更改运行逻辑.我有它的功能,但不正确.什么我迄今所做的是写一个方法叫做MonitorRules(),这是什么监听使用一个被称为C#火力地堡客户包装,以火力演员代码FireSharp.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(); var serviceUri = new Uri("fabric:/MyApp.RuleEngine/RuleMonitorActorService"); var actorId = ActorId.NewId(); var ruleMonitor = ActorProxy.Create (actorId, serviceUri); ruleMonitor.MonitorRules();
此"有效",即服务打开与Firebase的连接并响应数据更改.问题是,由于服务在五个节点集群的三个节点上运行,因此它实际上是在监听三次并处理每个消息三次.此外,如果暂时没有活动,则会停用该服务,并且不再响应Firebase中的更改.总而言之,不是正确设置这样的东西的方式我确定,但我找不到任何关于如何在服务结构中设置这样的轮询客户端的文档.有没有办法设置这将坚持天蓝色服务面料的精神?
是的,这里有一些事情要熟悉.第一个是Actor生命周期和垃圾收集.Tl; dr:如果演员没有收到客户端请求(通过ActorProxy)或提醒一段时间(可配置),则会停用演员.
其次,Actors具有可用于定期工作的计时器和提醒,例如轮询数据库以进行更改.计时器和提醒之间的区别在于计时器不算作"正在使用",这意味着仍然可以停用演员关闭计时器,但提醒计为"正在使用",并且还可以重新激活停用演员.考虑计时器和提醒的方法是你正在进行轮询,而不是等待像你在这里使用FireSharp那样的回调.
最后,从Main()调用MonitorRules并不是最好的主意.原因是Main()实际上是actor服务主机进程的入口点,它只是一个用于托管actor实例的EXE.在Main()中应该发生的唯一事情是注册你的actor类型而不是其他任何东西.让我们更详细地看看这里发生了什么:
因此,您将actor服务部署到群集.首先发生的是我们在必要的节点上启动主机进程来运行actor服务(在你的情况下为3).我们进入Main(),其中演员服务类型被注册,此时,这就是我们应该做的全部,因为一旦演员服务注册到主机进程,我们将创建一个实例(或多个实例或副本,如果它是有状态的服务,然后服务可以开始做它的工作.对于actor,这意味着当客户端应用程序使用ActorProxy进行调用时,actor服务已准备好开始激活actor.但是使用Main()中的ActorProxy调用,你基本上是说" 在主机启动时主机所在的每个节点上激活一个actor ",这就是你要三次听的原因.
考虑到所有这些,首先要问自己的问题是演员是否适合你.如果您只想要一个简单的地方来使用FireSharp客户端监控Firebase,可能更容易使用可靠的服务,因为您可以将监控放在RunAsync中,该服务在服务启动时自动启动,而不像需要客户端的运营商那样激活他们.