Akka是一组开源库,用于设计跨处理器核心和网络的可扩展弹性系统。Akka允许您专注于满足业务需求,而不是编写低级代码以提供可靠的行为,容错和高性能。
Akka有什么特点呢?多线程行为,不使用像atomics或locks这样的低级并发结构。您甚至不需要考虑内存可见性问题。系统及其组件之间的透明远程通信,您不需要编写或维护困难的网络代码。集群,高可用性架构,具有弹性,可按需扩展或扩展。接下来我们就实践一把这个akka组件,首先VS项目安装一下包
安装完成后,我们新建一个winform项目,开始。这里我设计一个学校打扫卫生的案例,有三种演员,第一个是班长,第二个是劳动委员,第三个是全班其他学生们。当向班长发布打扫卫生的命令后,班长通知劳动委员。劳动委员告诉大家开始打扫卫生,大家收到消息后开始打扫。当向班长发布停止打扫的命令后,班长通知劳动委员。劳动委员告诉大家停止打扫卫生,大家收到消息后停止打扫卫生。
首先定义这三个演员actor模型。
internal class StudentActor : ReceiveActor { IActorRef laborLeaderActor; public StudentActor() { laborLeaderActor = Context.ActorOf(Props.Create<LaborLeaderActor>(), "LaborMember"); Receive<string>(message => { Sender.Tell(message); ; laborLeaderActor.Tell(message); }); } } internal class LaborLeaderActor : UntypedActor { private IActorRef child; protected override void PreStart() { Console.WriteLine("Labor leader coming..."); child = Context.ActorOf(Props.Create<LaborMemberActor>(), "LaborMember"); } protected override void PostStop() { Console.WriteLine("Labor Leader:Labor Stop"); } protected override void OnReceive(object message) { switch (message.ToString()) { case "stop": Context.Stop(Self); Context.Stop(child); break; case "labor": Console.WriteLine("Labor Leader: Labar,Labar,quickly!"); child.Tell("labor"); break; } } } internal class LaborMemberActor : UntypedActor { protected override void PreStart() { Console.WriteLine("Labor member coming..."); } protected override void PostStop() { Console.WriteLine("Labor Member: Stop,Stop,Stop,Stop....."); } protected override void OnReceive(object message) { switch (message.ToString()) { case "stop": Context.Stop(Self); break; case "labor": Console.WriteLine("Labor Member: Labar,Labar,Labar,Labar....."); break; } } }
这三个模型建好之后,我们开始打扫卫生,首先我们创建一个演员班长。
private void btnStart_Click(object sender, EventArgs e) { var system = ActorSystem.Create("SchoolSystem"); var monitor = system.ActorOf<StudentActor>("monitor"); monitor.Tell("labor"); }
现在我们向班长发出劳动的命令,班长收到消息后,告诉劳动委员开始打扫卫生。这里其实班长这个演员又把消息通知给了其他演员劳动委员。其实也是Parent/Child的关系。
zlaborLeaderActor.Tell(message);
然后劳动委员LaborLeaderActor又把消息通知给全班学生。
case "labor": Console.WriteLine("Labor Leader: Labar,Labar,quickly!"); child.Tell("labor");
全班同学收到打扫卫生的消息后,开始打扫,最后执行的结果如下。
当班长收到通知后,通知下去以后,劳动委员Labor leader来了,全体学生来了。来了后劳动委员告诉大家快劳动,大家收到命令后,开始劳动,劳动......。上面这些就是一个发布打扫卫生的流程,相比以前的传统写法,这种基于消息通知的架构是不是扩展性更好,耦合度更低,所有交互都是通过发送消息来解决。
举个例子,年底了,你想让别人还你钱,你得先实例化一个还钱人,然后调用他的支付方法,他才能把钱还给你。在actor模型下,欠钱人就是个演员,你发消息告诉他还钱。你完全不需要关注他是否有支付方法,至于我发消息过去,还不还那是由我们自己设计的。就像上面班长发布命令打扫卫生,劳动委员这里如果没有设计通知大家的话,那其实这个流程是走不下去的。
接下来我们再看一下停止打扫卫生。
private void btnStop_Click(object sender, EventArgs e) { var system = ActorSystem.Create("SchoolSystem"); var monitor = system.ActorOf<StudentActor>("monitor"); monitor.Tell("stop"); }
其实执行过程和上面一样,给班长发布停止命令后,班长通知劳动委员停止劳动,劳动委员停止自己和全体同学的劳动。
Context.Stop(Self); Context.Stop(child);
在这里我们看到我们的代码是先停止自己,再停止child,可是执行结果却是先停止了child,再停止自己。很好理解,手下人都没停,自己肯定不能停,因为你是领导。
OK,今天就到这,后面会持续学习这个组件,今天不过看了些皮毛而已就先写出来。
匿名游客