慎用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. 面试总结——Java高级工程师(一)

    一.无笔试题 不知道是不是职位原因还是没遇到,面试时,都不需要做笔试题,而是填张个人信息表格,或者直接面试 二.三大框架方面问题 1.Spring 事务的隔离性,并说说每个隔离性的区别 解答:spri ...

  2. 【eclipse】外部 jar 包导入教程

    JavaWeb 项目中,可以直接将要导入的 jar 程序包复制到你项目下的 WEB-INF/lib 文件夹下,将来程序移动到别的机子上测试时也能正常运行.如果是普通 Java 工程的话,我们可以在项目 ...

  3. PHP 生成器Generators的入门理解和学习

    什么是生成器Generators 生成器允许你在 foreach 代码块中写代码来迭代一组数据而不需要在内存中创建一个数组, 那会使你的内存达到上限,或者会占据可观的处理时间.相反,你可以写一个生成器 ...

  4. js中的三种弹框分别是alert(),confirm(),prompt()

    1.alert(): ①写在<script>标签中 ②括号中的内容为字符串或者整型 ③点击确认即可关闭,无返回值 2.confirm(): ①写在<script>标签中 ②括号 ...

  5. ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer

    传送门:https://nanti.jisuanke.com/t/31462 本题是一个树上的问题:结点间路径问题. 给定一个有N×M个结点的网格,并给出结点间建立墙(即拆除边)的代价.花费最小的代价 ...

  6. 利用tempalte.js模版引擎渲染页面,作对应的数据处理

    需要启个服务 需引入jquery.js和template.js <!DOCTYPE html> <html lang="en"> <head> ...

  7. 天猫双11红包前端jQuery

    [01]   浏览器支持:IE10+和其他现代浏览器.   效果图:       步骤:   HTML部分:   <div class="opacity" style=&qu ...

  8. java中List遍历删除元素-----不能直接 list.remove()

    https://blog.csdn.net/github_2011/article/details/54927531 这是List接口中的方法,List集合调用此方法可以得到一个迭代器对象(Itera ...

  9. [K/3Cloud]K3Cloud平台开发之Python插件

    有时候我们的表单可能很简单,只是一个简单交互的表单,但有可能还是要劳师动众的给它建个工程写个插件,是不是很不爽?例如我有如下一个表单: 功能很简单就是选个业务对象,收集绑定几个字段名,然后确定返回一个 ...

  10. RSYNC最简实施

    只是内网同步,故而可以省略很多安全方面的东东.不需要通过ssh,而是通过rsync协议.不需要用户名认证,保证只读. rsync用standalone的daemon方式,而不用service方式操作. ...