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

  "Using ask will send a message to the receiving Actor as with tell, and the receiving actor must reply with sender() ! reply in order to complete the returned Future with a value.
  The ask operation involves creating an internal actor for handling this reply, which needs to have a timeout after which it is destroyed in order not to leak resources"

  上面是官方文档对ask的一个描述,很明显,调用ask的时候会创建一个临时的actor和一个future。这看起来问题也不大。初学者总是忍不住使用ask,因为这比较符合平时的开发思维:像调用函数那样调用actor。

  一旦用akka来实现系统的功能,那么我们一定要记住三个准则:一切皆异步、一切皆actor、没有阻塞。ask并不符合这三个准则。也许你会说不使用ask,把一次调用分成两个阶段有点啰嗦。嗯,某种意义上说,你是对的。本来一次调用就完成的业务逻辑,现在必须用两种类型的消息进行通信来完成。不过,这是一切皆异步的微小代价。使用akka开发系统,其实就是在面向消息编程。一切皆异步、actor,就意味着需要很多类型不同的消息。消息设计的好坏,很大程度上决定你akka系统的质量!

  我们来试想在系统中用到了ask,会出现什么的影响。当然,影响有很多,我只挑其中一点来说。在系统中用到了ask模式,就意味着在服务端会多创建一个临时actor出来。那么如果有1亿次同样的调用,就意味着多出1亿个临时actor,官方说250万个actor大概消耗1GB内存,那究竟多出了多少内存还请你自己计算。这还是只有一个ask调用的时候,如果ask调用多了,就意味着整个系统占用的内存会翻倍!想想都可怕。

  不过,存在即合理。既然官方实现了ask模式,那自有其适用的场景。ask可以在client中使用!client是在akka系统外部,它只负责与akka系统通信,并获取对应的结果,没有其他复杂的功能,你可以把client理解为akka系统的边界。

  那么客户端使用ask会不会出现上面的内存消耗的情况呢?当然会有,只不过情况会很乐观。假如只有一个client,如果它发起了1亿次调用,就会在本地创建1亿个临时actor,对于服务器没有任何额外的影响。即使客户端因为内存消耗爆掉了,也不会影响服务器的运行。最乐观的情况是有1亿个客户端,发起了1亿次ask,那么同样会创建1亿个临时actor,只不过所有的临时actor平均分布在每个客户端,对服务器仍然没有影响。看到这其中的奥妙了嘛?其实把ask放到client,就是把资源消耗的压力分散到了client!

  那么服务器端的akka系统可以没有ask调用吗?完全可以,如果你仍然没有办法消除服务器端的ask调用,请参考我《akka设计模式系列》的其他文章。

akka设计模式系列-慎用ask的更多相关文章

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

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

  2. akka设计模式系列

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. docker-compose 报错记录

    1.如往常一样对docker-compose.yml配置修改后,docker-compose up -d 后台启动,启动后报错,由原来的done变成了error. 第一反应就是down掉这些容器: d ...

  2. mac下用crontab实现pytho3脚本自动定期执行,包括scrapy的定期执行

    呃 其实要明天上午才能知道是否成功,毕竟改了一个小参数的. 首先,来学两个小命令: step1: $ sudo crontab -e step2: # 然后提示password输入密码,即可进入编辑页 ...

  3. photon Unity RPC 调用流程

    本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/51425225 作者:car ...

  4. go 语言学习指南(一)

    参考资料: http://www.runoob.com/go/go-tutorial.html

  5. JavaSE 学习笔记之新特性之泛型(二十)

    泛型:jdk1.5版本以后出现的一个安全机制.表现格式:< > 好处: 1:将运行时期的问题ClassCastException问题转换成了编译失败,体现在编译时期,程序员就可以解决问题. ...

  6. HDU 1210

    感觉就是乱搞找规律 自己写几组数据 本来开始是想着把 n 个数字每次回到原来位置各需要多少次,然后取它们的最小公倍数就好了 但是数据写着写着发现每一个数回到原来位置次数都是一样的,那么就简单了,直接第 ...

  7. HDU - 3407 - String-Matching Automata

    先上题目: String-Matching Automata Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  8. 【BZOJ2342】双倍回文(manacher,并查集)

    题意: 思路:From http://blog.sina.com.cn/s/blog_8d5d2f04010196bh.html 首先我可以看出: (1)我们找到的串的本身也是一个回文串(显然) (2 ...

  9. MEAN,从MONGO DB里弄出点东东来啦,以REST风格显示JSON

    最近一直在弄弄的... javascript的风格弄熟了,我觉得肯定很快,,但心中有种感觉,DJANGO和MEAN这种结构,搞大的不行. 因为MVC这种结构感觉不如SPRING这些严谨,是不是我有偏见 ...

  10. 1043 方格取数 2000 noip 提高组

    1043 方格取数  2000 noip 提高组 题目描述 Description 设有N*N的方格图(N<=10,我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0.如下图所示(见样 ...