在之前的akka设计模式系列-消息模型中,我们介绍了akka的消息设计方案,但随着实践的深入,发现了一些问题,这里重新梳理一下设计方法,避免之前的错误、不当的观点给大家带来误解。


命令和事件

  我们仍然把akka中的消息分为命令和事件两大类,但二者的具体含义和实现有一点变化。“命令,是指一个actor给另外一个actor发送指令做相关的业务逻辑;事件,则是actor对某个命令的响应结果,或者对其他事件的响应结果”。之前是这样定义的,但在具体的实践过程中发现了一些问题。

  比如,命令如何归类?是根据命令的发送者归类还是根据接收者归类呢?是不是根据消息的作用对象更恰当呢?事件的定义是不是可以更加宽泛一下呢?如果某个消息是定时产生的,那它应该是一个命令还是一个消息呢?

  当然还有一些其他的问题,认真总结后,在代码设计上我们做了一些优化。

消息

trait Message {
/**
* 消息发生的时间
*/
final lazy val at: Long = System.currentTimeMillis()
}

  消息的定义很简单,只有一个时间字段,表示命令或事件的产生时间。但在实践过程中发现,很少使用这个字段,再加上System.currentTimeMillis()多线程调用会有性能问题,所以干脆把它定义成了lazy。关于这一点,大家可以根据各自的实际情况修改。

命令

trait Reply{
def replyTo:ActorRef
} trait Command extends Message with Reply

  命令就是含有回复对象的消息,之所以强化这一点,主要是想 用Command模拟能返回结果的函数。也就是说,actor收到Command之后必须有一个返回事件。

trait TaskCommand extends Command
object TaskCommand{
final case class Run(jobContext: JobContext,replyTo:ActorRef) extends TaskCommand
final case class Kill(jobId:UID, taskId:UID, executorType: ExecutorType, replyTo:ActorRef) extends TaskCommand
}

  上面定义两个命令:Run、Kill。很明显我们是根据命令的作用对象进行归类,也就是实现统一的trait(TaskCommand)。之所以这样做是因为我们发现很多命令被某一个actor处理之后,并不返回结果,而是发送给下一个actor处理,并由其返回结果。这种情况下无论从发送者还是接收者归类都不恰当,而用命令的作用对象进行归类则比较合适。

事件

trait SchedulerEvent extends Event
object SchedulerEvent{
final case class ScheduleTriggered() extends SchedulerEvent
final case class NodeDowned(nodeAnchor:String) extends SchedulerEvent
}

   事件的含义和实现方法跟之前基本不变,但总体来说也是围绕某个对象进行归类。比如Scheduler这个对象有两个事件:ScheduleTriggered、NodeDowned。这样事件在多个actor传递的时候不会改变其原始的含义,比较容易理解。

命令结果

  actor处理命令的时候,需要有一个返回结果,仍然需要对如何返回进行界定。我们根据面向过程编程的一个优良习惯进行规范:对某一类Command返回结果时,只能有一个地方返回成功结果,可以有多个地方返回失败结果。这只是一个软性约束,但非常有用,这样排查问题比较方便,也有利于画系统的流程图。

总结

  在Akka中消息设计的好坏往往决定着应用的质量,非常重要。每个人的设计理念不同,实现的方式也就不同,这里也只是抛砖引玉,如果你有更好的设计模式,欢迎留言或者加微信(HelloGrape)讨论。

akka设计模式系列-消息模型(续)的更多相关文章

  1. akka设计模式系列-消息模型

    通过前面的文章我们总结了几个常见的actor设计模式,但此处不得不提前介绍一下在Akka中消息的设计模式.随着对Akka的使用,我们会发现,使用Akka设计系统其实就是面向消息编程.actor之间消息 ...

  2. akka设计模式系列-慎用ask

    慎用ask应该是Akka设计的一个准则,很多时候我们应该禁用ask.之所以单独把ask拎出来作为一篇博文,主要是akka的初学者往往对ask的使用比较疑惑. "Using ask will ...

  3. akka设计模式系列

    由于本人爱好Scala,顺便也就爱好Akka,但目前网上对Akka的介绍大多都是概念上或技术方向上的介绍,基本没有Akka设计模式或者Actor模型设计模式的资料.这对于Akka的普及非常不利,因为即 ...

  4. akka设计模式系列(Actor模型)

    谈到Akka就必须介绍Actor并发模型,而谈到Actor就必须看一篇叫做<A Universal Modular Actor Formalism for Artificial Intellig ...

  5. akka设计模式系列-While模式

    While模式严格来说是while循环在Akka中的合理实现.while是开发过程中经常用到的语句之一,也是绝大部分编程语言都支持的语法.但while语句是一个循环,如果循环条件没有达到会一直执行wh ...

  6. akka设计模式系列-Backend模式

    上一节我们介绍了Akka使用的基本模式,简单点来说就是,发消息给actor,处理结束后返回消息.但这种模式有个缺陷,就是一旦某个消息处理的比较慢,就会阻塞后面所有消息的处理.那么有没有方法规避这种阻塞 ...

  7. akka设计模式系列-actor锚定

    actor锚定模式是指使用actorSelection对acor进行锚定的设计模式,也可以说是一个对actor的引用技巧.在某些情况下,我们可能需要能够根据Actor的path锚定对应的实例.简单来说 ...

  8. akka设计模式系列-Chain模式

    链式调用在很多框架和系统中经常存在,算不得上是我自己总结的设计模式,此处只是简单介绍在Akka中的两种实现方式.我在这边博客中简化了链式调用的场景,简化后也更符合Akka的设计哲学. trait Ch ...

  9. akka设计模式系列-akka在秒杀场景的应用

    本博客讨论一下akka在秒杀场景下的应用,提出自己的见解,只做抛砖引玉,大神勿喷.秒杀活动涉及到前中后台各个阶段,为了说明问题,我们简化场景,只研究akka在后台如何处理秒杀业务. 秒杀活动 所谓的秒 ...

随机推荐

  1. 《Kubernetes权威指南》01_Kubernetes入门——Kubernetes 是什么

    01_Kubernetes入门 li {list-style-type:decimal;}.wiz-editor-body ol.wiz-list-level2 > li {list-style ...

  2. inode和block的理解

    什么是inode和block? 所谓的inode就是索引节点(index node)的意思,在每一个存储设备被格式化创建文件系统后,所有的文件大致被分为了两部分,分别是inode和block. 其中i ...

  3. ubuntu 14.04 安装gvim 后报出warning

    (gvim:3572): GLib-GObject-WARNING **: Attempt to add property GnomeProgram::sm-connect after class w ...

  4. C# WinForm 使用SMS接口发送手机验证码+图形验证码+IP限制

    https://blog.csdn.net/IT_xiao_guang_guang/article/details/104299983 前言   1.发送手机验证码用的是网建的SMS接口(http:/ ...

  5. HDU 6602 Longest Subarray (线段树)

    题意: 1e5的数组,c(1e5)种数字求最长的子串,使得其中每个出现的数字出现的次数为0次或者大于k次 思路: 枚举右端点i,维护当前右端点时,每个左端点的可行元素数量,当且仅当可行元素为c时更新答 ...

  6. 快速应用开发(RAD)平台 - 20 年的演进

    过去几年中,现代软件开发的整体环境发生了巨大的变化.对我个人来说,这种变化与宇宙的加速膨胀差不多.第二个千年刚到来时,产业的发展看起来还不是那么快,只是逐步在前进.现在技术发展的复杂度和多样性已经可以 ...

  7. Java线程核心基础(上)

    Java线程核心基础(上) 一.实现多线程 根据Oracle官方文档,目前推荐的创建线程方法主要有两种,分别是继承Thread类和实现Runnable接口.通过阅读Thread类源码,可以发现二者不同 ...

  8. PHP在程序处理过程中动态输出内容

    在安装discuz或其他一些开源产品的时候,在安装数据库时页面上的安装信息都是动态输出出来的,主要通过php两个函数来实现的, flush();ob_flush(); 代码如下 <html xm ...

  9. Django表单Form类对空值None的替换

    最近在写项目的时候用到Form,发现这个类什么都好,就是有些空值的默认赋值真是很不合我胃口. 查阅资料.官方文档后发现并没有设置该值的方式.于是,便开始了我的踩坑之路...... 不过现在完美解决了, ...

  10. EF core (code first) 通过自动迁移实现多租户数据分离 :按Schema分离数据

    前言 本文是多租户系列文章的附加操作文章,如果想查看系列中的其他文章请查看下列文章 主线文章 Asp.net core下利用EF core实现从数据实现多租户(1) Asp.net core下利用EF ...