`
deepinmind
  • 浏览: 452260 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
1dc14e59-7bdf-33ab-841a-02d087aed982
Java函数式编程
浏览量:41682
社区版块
存档分类
最新评论

Akka笔记之请求与响应

阅读更多
前面我们讲到了Actor的消息传递,并看到了如何发送一条fire-n-forget消息(也就是说,消息发送给Actor后我们就不管了,不从Actor那接收响应)。

技术上来讲,消息发送给Actor就是希望能有副作用的。设计上便是如此。目标Actor可以不做响应,也可以做如下两件事情——

1. 给发送方回复一条响应(在本例中,TeacherActor会将一句名言回复给StudentActor)
2. 将响应转发给其它的目标受众Actor,后者也可以进行响应/转发/产生副作用。Router和Supervisor就是这种情况。(很快我们就会看到)


请求及响应

本文中我们只关注第一点——请求及响应周期。




这张图说明了我们这次要做的事情。为了简单点,图中我并没有画出ActorSystem, Dispatcher以及Mailbox。

1. DriverApp将一条InitSignal消息发送给StudentActor。
2. StudentActor响应InitSignal消息并将一条QuoteRequest消息发送到TeacherActor。
3. 正如前面所说的那样,TeacherActor会回复一个QuoteResponse。
4. StudentActor将日志打印到控制台或者logger里。

同样的,我们会写一个测试用例来验证下它。

现在我们来仔细地分析下这四个步骤:

1. DRIVERAPP将一条INITSIGNAL消息发送给STUDENTACTOR




现在你应该能猜到DriverApp到底是干什么的了。它只做了4件事情:

1. 初始化ActorSystem


//Initialize the ActorSystem
  val system = ActorSystem("UniversityMessageSystem”)




2. 创建TeacherActor


//create the teacher actor
  val teacherRef = system.actorOf(Props[TeacherActor], "teacherActor”)




3. 创建StudentActor


//create the Student Actor - pass the teacher actorref as a constructor parameter to StudentActor
  val studentRef = system.actorOf(Props(new StudentActor(teacherRef)), "studentActor")
 


你会注意到我把TeacherActor的一个ActorRef的引用作为构造函数的参数传给了StudentActor,这样StudentActor才能够通过ActorRef来将消息发送给TeacherActor。当然还有别的方法(比如通过Props来传递),不过这么做对后续即将讲到的Supervisor和Router来说会方便一点。很快我们会看到子Actor也能实现这个功能,不过那个方法用在这里并不适合——学生来生成老师,这看起来不太对劲吧?

最后,

4. DriverApp将InitSignal消息发送给了StudentActor,这样StudentActor会开始将QuoteRequest消息发送给TeacherActor。


//send a message to the Student Actor
  studentRef ! InitSignal
 



DriverClass讲的已经够多了。后面的Thread.sleep和ActorSystem.shutdown就是等了几秒,以便消息发送完成,然后再最终将ActorSystem关掉。

DRIVERAPP.SCALA


package me.rerun.akkanotes.messaging.requestresponse

import akka.actor.ActorSystem 
import akka.actor.Props 
import me.rerun.akkanotes.messaging.protocols.StudentProtocol._ 
import akka.actor.ActorRef

object DriverApp extends App {

  //Initialize the ActorSystem
  val system = ActorSystem("UniversityMessageSystem")

  //construct the teacher actor
  val teacherRef = system.actorOf(Props[TeacherActor], "teacherActor")

  //construct the Student Actor - pass the teacher actorref as a constructor parameter to StudentActor
  val studentRef = system.actorOf(Props(new StudentActor(teacherRef)), "studentActor")

  //send a message to the Student Actor
  studentRef ! InitSignal

  //Let's wait for a couple of seconds before we shut down the system
  Thread.sleep(2000)

  //Shut down the ActorSystem.
  system.shutdown()

}




2. STUDENTACTOR响应INITSIGNAL消息并将QUOTEREQUEST消息发送给TEACHERACTOR

以及

4. STUDENTACTOR接收到TEACHERACTOR回复的QuoteResponse然后将日志打印到控制台/logger上来

为什么我把第2和第4点放到一起来讲?因为它太简单了,如果分开讲的话我怕你嫌我啰嗦。



那么,第2步——StudentActor接收到DriverApp发过来的InitSingal消息并将QuoteRequest发送给TeacherActor。



def receive = { 
    case InitSignal=> {
          teacherActorRef!QuoteRequest
    }
    ...
    ...

   

搞定!

第4步——StudentActor将TeacherActor发过来的消息打印出来。



说到做到:


case QuoteResponse(quoteString) => { 
      log.info ("Received QuoteResponse from Teacher")
      log.info(s"Printing from Student Actor $quoteString")
}




我猜你肯定觉得这很像是伪代码。

那么,完整的StudentActor应该是这样的:

STUDENTACTOR.SCALA


package me.rerun.akkanotes.messaging.requestresponse

import akka.actor.Actor 
import akka.actor.ActorLogging 
import me.rerun.akkanotes.messaging.protocols.TeacherProtocol._ 
import me.rerun.akkanotes.messaging.protocols.StudentProtocol._ 
import akka.actor.Props 
import akka.actor.ActorRef

class StudentActor (teacherActorRef:ActorRef) extends Actor with ActorLogging {

  def receive = {
    case InitSignal=> {
      teacherActorRef!QuoteRequest
    }

    case QuoteResponse(quoteString) => {
      log.info ("Received QuoteResponse from Teacher")
      log.info(s"Printing from Student Actor $quoteString")
    }
  }
}




3. TeacherActor回复QuoteResponse

这和我们在前面的fire-n-forget那篇)中看到的代码是类似的。

TeacherActor接收到QuoteRequest消息然后回复一个QuoteResponse。

TEACHERACTOR.SCALA



package me.rerun.akkanotes.messaging.requestresponse

import scala.util.Random

import akka.actor.Actor 
import akka.actor.ActorLogging 
import akka.actor.actorRef2Scala 
import me.rerun.akkanotes.messaging.protocols.TeacherProtocol._


class TeacherActor extends Actor with ActorLogging {

  val quotes = List(
    "Moderation is for cowards",
    "Anything worth doing is worth overdoing",
    "The trouble is you think you have time",
    "You never gonna know if you never even try")

  def receive = {

    case QuoteRequest => {

      import util.Random

      //Get a random Quote from the list and construct a response
      val quoteResponse = QuoteResponse(quotes(Random.nextInt(quotes.size)))

      //respond back to the Student who is the original sender of QuoteRequest
      sender ! quoteResponse

    }
  }
}



测试用例

现在,我们的测试用例会来模拟下DriverApp。由于StudentActor只是打印了个日志消息,我们没法对QuoteResponse本身进行断言,那么我们就看下EventStream中是不是有这条日志消息就好了(就像上回做的那样)

那么,我们的测试用例看起来会是这样的:


"A student" must {

    "log a QuoteResponse eventually when an InitSignal is sent to it" in {

      import me.rerun.akkanotes.messaging.protocols.StudentProtocol._

      val teacherRef = system.actorOf(Props[TeacherActor], "teacherActor")
      val studentRef = system.actorOf(Props(new StudentActor(teacherRef)), "studentActor")

      EventFilter.info (start="Printing from Student Actor", occurrences=1).intercept{
        studentRef!InitSignal
      }
    }
  }
 



代码

项目的完整代码可以从Github中进行下载。

在下一篇中,我们将会看到如何在Akka中使用调度器以及如何通过Kamon来监控你的Akka应用。

原创文章转载请注明出处:http://it.deepinmind.com

英文原文链接


1
0
分享到:
评论

相关推荐

    响应式架构 消息模式Actor实现与Scala.Akka应用集成

    响应式架构是一种设计模式,...而提供的"响应式架构 消息模式Actor实现与Scala.Akka应用集成"文档,很可能是对这些概念的详细讲解,包括沃恩·弗农的观点和实践经验,对于深入理解Akka和响应式架构有着重要的参考价值。

    响应式架构++消息模式Actor实现与Scala.Akka应用集成+,沃恩·弗农+

    在《响应式架构++消息模式Actor实现与Scala.Akka应用集成+》中,作者沃恩·弗农深入探讨了如何利用Akka和Scala来构建响应式的应用程序。他可能详细讲解了以下知识点: 1. **Actor系统**:介绍Akka中的Actor系统是...

    响应式架构 消息模式Actor实现与Scala.Akka应用集成 ,沃恩·弗农

    响应式架构是一种设计思想,它强调系统在面对不断变化的工作负载和网络延迟时,能够保持弹性、反应迅速...阅读"响应式架构 消息模式Actor实现与Scala.Akka应用集成"这本书,将有助于你掌握这些概念并应用于实际项目中。

    Akka入门与实践

    网络上各系统进行交互的困难之处,并介绍如何使用 Akka 提供的解决方案来解决这些 问题。 作者简介 Jason Goodwin 是一个基本上通过自学成才的开发者。他颇具企业家精神,在学校 学习商学。不过他从 15 岁起就开始...

    akka java实现tcp远程调用

    下面我们将深入探讨如何使用Akka与Java来实现TCP远程调用,以及其中涉及的关键知识点。 首先,我们需要理解Akka的Actor系统。Actor是Akka的核心概念,每个Actor都是一个独立的执行单元,拥有自己的状态和邮箱,用于...

    Akka 实战 akka in action v13 2014版本

    Akka可以与现有的技术栈和消息系统集成,这让开发者能够更容易地在现有架构中引入Akka。 集群功能是Akka的另一亮点,它使得开发者能够将多个Akka节点组成一个集群,从而实现更高的性能和更好的容错性。集群中的节点...

    akka学习入门实践

    - **Akka 中的应用**:Akka 支持通过 Future 和 Promise API 实现异步操作,这有助于构建响应式的系统。 - **优势**:提高了系统的并发能力和用户体验,减少了等待时间。 #### 四、Akka 消息传递模式 - **核心机制*...

    响应式架构 消息模式Actor实现与Scala.Akka应用集成 高清扫描版

    响应式架构 消息模式Actor实现与Scala.Akka应用集成 高清扫描版

    c#分布式框架akka范例

    使用`Tell`方法非阻塞地发送消息,而`Ask`方法则允许异步请求-响应模式。 3. **远程通信**:Akka.NET的Remote功能使得Actor可以在不同的网络节点上运行。这使得构建分布式系统成为可能,Actor可以通过网络透明地...

    响应式架构 消息模式Actor实现与Scala.Akka应用集成.rar

    其中包括:Actor模型和响应式软件的主要概念、Scala语言的基础知识、Akka框架与Akka集群功能、Actor模型中的通道机制和技术、降低消息源与消息目的地之间耦合性的方式、持久化Actor对象和幂等接收者。附录A中还介绍...

    akka-http-1.0-RC2.jar.zip

    1. **响应式设计**:Akka HTTP遵循响应式宣言,确保了系统对请求的快速响应,同时保持资源的高效利用和良好的弹性。 2. **流式处理**:支持HTTP/2协议,可以处理数据流,允许数据在请求和响应之间无缝传输,减少了...

    Learning Akka

    10. **集成和测试**:了解如何将Akka与其他技术(如 Spray for RESTful服务、Cassandra for分布式数据存储)集成,以及如何编写有效的Akka测试,都是学习过程中的重要部分。 通过阅读《Learning Akka》,开发者不仅...

    akka实例参考

    10. **事件驱动和响应式编程**:Akka遵循响应式宣言,强调非阻塞I/O、背压和弹性,使其非常适合构建高性能、低延迟的应用。 11. **Future和Promise**:Akka中的Future代表一个异步计算的结果,Promise则是用来设置...

    Learning Akka(PACKT,2015)

    Akka is a distributed computing toolkit that enables developers to build correct concurrent and distributed applications using Java and Scala with ease, applications that scale across servers and ...

    Akka 基础学习pdf中文文档

    网络上各系统进行交互的困难之处,并介绍如何使用 Akka 提供的解决方案来解决这些 问题。 作者简介 Jason Goodwin 是一个基本上通过自学成才的开发者。他颇具企业家精神,在学校 学习商学。不过他从 15 岁起就开始...

    java解决AKKA的疑点难点.docx

    7. **将HTTP请求异步接管到Akka集群**:AKKA-HTTP与Akka Actor系统紧密集成,可以将HTTP请求转换为消息并异步处理。如`websocketFlow`中的`actor.tell`方法,将接收到的消息发送到actor系统,实现非阻塞处理。 在...

Global site tag (gtag.js) - Google Analytics