akka设计模式系列-慎用ask

简介:   慎用ask应该是Akka设计的一个准则,很多时候我们应该禁用ask。之所以单独把ask拎出来作为一篇博文,主要是akka的初学者往往对ask的使用比较疑惑。  "Using ask will send a message to the receiving Actor as with tell,...

  慎用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设计模式系列-While模式
  While模式严格来说是while循环在Akka中的合理实现。while是开发过程中经常用到的语句之一,也是绝大部分编程语言都支持的语法。但while语句是一个循环,如果循环条件没有达到会一直执行while语句体的代码,且会阻塞while语句外的代码。
1397 0
|
设计模式 Scala
akka设计模式系列-Chain模式
  链式调用在很多框架和系统中经常存在,算不得上是我自己总结的设计模式,此处只是简单介绍在Akka中的两种实现方式。我在这边博客中简化了链式调用的场景,简化后也更符合Akka的设计哲学。 trait Chained{ def receive:Receive = Actor.
1622 0
|
设计模式 流计算 分布式计算
akka设计模式系列-Aggregate模式
  所谓的Aggregate模式,其实就是聚合模式,跟masterWorker模式有点类似,但其出发点不同。masterWorker模式是指master向worker发送命令,worker完成某种业务逻辑。
1907 0
|
设计模式
akka设计模式系列-消息模型
  通过前面的文章我们总结了几个常见的actor设计模式,但此处不得不提前介绍一下在Akka中消息的设计模式。随着对Akka的使用,我们会发现,使用Akka设计系统其实就是面向消息编程。actor之间消息设计的是否合理,往往意味着Akka应用设计的是否合理。
2274 0
|
Java
akka设计模式系列-Backend模式
  上一节我们介绍了Akka使用的基本模式,简单点来说就是,发消息给actor,处理结束后返回消息。但这种模式有个缺陷,就是一旦某个消息处理的比较慢,就会阻塞后面所有消息的处理。那么有没有方法规避这种阻塞呢,这就是本章要讲的Backend模式。
1603 1
|
设计模式
akka设计模式系列-基础模式
  本文介绍akka的基本使用方法,由于属于基础功能,想不出一个很高大上的名称,此处就以基础模式命名。下文会介绍actor的使用方法,及其优劣点。 class SimpleActor(name:String) extends Actor { private def doWork(message...
2267 0
|
Java 设计模式 安全
akka设计模式系列(Actor模型)
  谈到Akka就必须介绍Actor并发模型,而谈到Actor就必须看一篇叫做《A Universal Modular Actor Formalism for Artificial Intelligence 》的论文,它最早发表于1973年,提出了一种并发计算的理论模型,Actor就源于该模型。
8170 0
|
11天前
|
设计模式 SQL 算法
设计模式了解哪些,模版模式
设计模式了解哪些,模版模式
19 0
|
30天前
|
设计模式 Java uml
C++设计模式之 依赖注入模式探索
C++设计模式之 依赖注入模式探索
37 0
|
3月前
|
设计模式 存储 算法
Java 设计模式最佳实践:三、行为模式
Java 设计模式最佳实践:三、行为模式