慎用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. linux(Ubuntu16)下切换python2和python3(转)

    采用update-alternatives 切换版本 1.打开终端:Ctrl+Alt+T 2.查看update-alternatives的帮助信息:update-alternatives --help ...

  2. Linux学习笔记记录(六)

  3. Nginx + Lets'encrypt 实现HTTPS访问七牛空间资源

    上一篇文章 为七牛云存储空间绑定自定义域名,并使用七牛云提供的免费SSL证书,将自定义加名升级为HTTPS 我们提到利用七牛的免费SSL证书,将自定义加名升级为HTTPS的方法. 不知道有没有小伙伴会 ...

  4. BC in fluent

    Boundary conditions in Fluent Table of Contents 1. Boundary Conditions (BC) 1.1. Turbulence Paramete ...

  5. 【Codeforces 369C】 Valera and Elections

    [链接] 我是链接,点我呀:) [题意] 给你一棵树 让你选择若干个修理点. 这些修理点被选中之后,节点i到1号节点之间的所有"坏路"都会被修好 问最少需要选择多少个点才能将所有的 ...

  6. 【Codeforces 466B】Wonder Room

    [链接] 我是链接,点我呀:) [题意] 让你把长为a,宽为b的房间扩大(长和宽都能扩大). 使得它的面积达到6*n 问你最小的能满足要求的面积是多少 输出对应的a和b [题解] 假设a< b ...

  7. POJ 1655 Balancing Act && POJ 3107 Godfather

    题目大意: 根据题目的图很好理解意思,就是记录每一个点的balance,例如 i 的balance就是把 i 从这棵树中除去后得到的森林中含有结点数最多 的子树中的节点个数,然后找到所有节点中对应的b ...

  8. [POJ3162]Walking Race(DP + 单调队列)

    传送门 题意:一棵n个节点的树.wc爱跑步,跑n天,第i天从第i个节点开始跑步,每次跑到距第i个节点最远的那个节点(产生了n个距离),现在要在这n个距离里取连续的若干天,使得这些天里最大距离和最小距离 ...

  9. [COGS309] [USACO 3.2] 香甜的黄油

    ★★   输入文件:butter.in   输出文件:butter.out   简单对比 时间限制:1 s   内存限制:128 MB 描述 农夫John发现做出全威斯康辛州最甜的黄油的方法:糖.把糖 ...

  10. 解决使用myeclipse电脑卡的问题

    1. 原因:myeclipse会自动更新,因此会占用大量内存 2. 解决方法: (1)window->Perferences->General->Startup and Shutdo ...