akka基本使用

1.Akka介绍

Akka是JVM平台上构建高并发,分布式应用的编程框架。它采用scala语言编写,同时提供了scala和java开发接口。Akka主要解决的问题是:可以轻松的写出高效稳定的并发程序,程序员不需要过多的考虑线程,锁和资源竞争等细节。

2.Akka Actor模型

Akka框架采用Actor模型,如下图所示。
在这里插入图片描述
Actor与Actor之间用消息进行通信,当某一个Actor给另外一个Actor发消息,消息是有序的,当消息投寄到相应的邮箱后,对方Actor怎么处理是异步的,当然也可以等待它的回复。

JVM中的Actor有以下几个特点:

  • 每个Actor都有对应一个邮箱

  • Actor是串行处理消息的

  • Actor中的消息是不可变的

优势:

  • 简化并发编程:每个Actor都是相互独立的,因此没有共享资源,这也就避免了并发编程中锁的问题。
3.案例
import akka.actor.{Actor, ActorRef, ActorSystem, Props}

class SelfActor extends  Actor{
  override def receive: Receive = {
    case "hello" =>  { println("收到hello,回应 hello too") }
    case "ok" => { println("收到ok,回应 ok too") }
    case "exit" => { context.stop(self)}
    case _ =>  { println("匹配不到") }
  }
}

object SelfActor {
  def main(args: Array[String]): Unit = {
    // 创建一个ActorSystem
    val actorSystem = ActorSystem("actorsystem")
    // 创建一个actor
    val actor01:ActorRef = actorSystem.actorOf(Props[SelfActor], "actor01")
    actor01 ! "hello"
    
    actorSystem.shutdown()
  }
}

maven依赖

<dependency>
	<groupId>com.typesafe.akka</groupId>
	<artifactId>akka-actor_2.11</artifactId>
	<version>2.3.11</version>
</dependency>

运行结果

收到hello,回应 hello too

Akka实现跨进程通信
本例实现了一个echo服务器,服务器将从客户端收到的消息返回给客户端。

服务端 AkkaServer.scala

import akka.actor.{Actor, ActorRef, ActorSystem, Props}
import com.typesafe.config.ConfigFactory


class AkkaServer extends Actor {

  override def receive: Receive = {
    case "start" => println("服务器开始工作了....")

    case msg:ClientMessage => {
      println("客户端id: " + msg.clientId + ", 客户端name: " + msg.clientName
       + ",消息: " + msg.msg)
      // 返回服务端的消息
      sender() ! ServerMessage(msg.msg)
    }
  }
}


object AkkaServer  {
  def main(args: Array[String]): Unit = {
    val host = "127.0.0.1"
    val port = 9999

    // 创建 config 对象,指定协议类型、监听的ip和端口
    val config = ConfigFactory.parseString(
      s"""
         |akka.actor.provider="akka.remote.RemoteActorRefProvider"
         |akka.remote.netty.tcp.hostname=$host
         |akka.remote.netty.tcp.port=$port
        """.stripMargin)


    val actorSystem = ActorSystem("server", config)
    // 创建一个actor
    val serverActor:ActorRef = actorSystem.actorOf(Props[AkkaServer], "server-actor")
    serverActor ! "start"
  }
}

客户端 AkkaClient.scala

import akka.actor.{Actor, ActorRef, ActorSelection, ActorSystem, Props}
import com.typesafe.config.ConfigFactory

import scala.io.StdIn


class AkkaClient(clientID:String, clientName:String, host: String, port: Int) extends Actor{

  var serverActorRef: ActorSelection = _

  override def preStart(): Unit = {
    serverActorRef = context.actorSelection(s"akka.tcp://server@${host}:${port}/user/server-actor")
    println("this.serverActorRefer=" + this.serverActorRef)
  }


  override def receive: Receive = {
    case "start" => println("客户端开始工作...")

    case msg:String => {
      serverActorRef ! ClientMessage(clientID, clientName, msg)
    }

    case msg:ServerMessage => {
      println("收到服务器消息:" + msg.toString )
    }
  }
}


object AkkaClient {
  def main(args: Array[String]): Unit = {

    val (host, port, serverHost, serverPort) = ("127.0.0.1", 9990, "127.0.0.1", 9999)
    val config = ConfigFactory.parseString(
      s"""
         |akka.actor.provider="akka.remote.RemoteActorRefProvider"
         |akka.remote.netty.tcp.hostname=$host
         |akka.remote.netty.tcp.port=$port
        """.stripMargin)

    // 创建 ActorSystem
    val actorSystem = ActorSystem("client-actorsystem", config)
    // 创建 clientActor 的 Actor 和 ActorRef
    val clientActor: ActorRef = actorSystem.actorOf(Props(new AkkaClient("01", "client-01", serverHost, serverPort)), "client-01")

    // 启动客户端
    clientActor ! "start"


    while (true) {
      val mes = StdIn.readLine()
      clientActor ! mes
    }
  }
}

maven依赖

<dependency>
    <groupId>com.typesafe.akka</groupId>
    <artifactId>akka-remote_2.11</artifactId>
    <version>2.3.11</version>
</dependency>

运行结果:

server

[INFO] [07/08/2020 11:13:04.385] [main] [Remoting] Starting remoting
[INFO] [07/08/2020 11:13:05.091] [main] [Remoting] Remoting started; listening on addresses :[akka.tcp://server@127.0.0.1:9999]
[INFO] [07/08/2020 11:13:05.092] [main] [Remoting] Remoting now listens on addresses: [akka.tcp://server@127.0.0.1:9999]
服务器开始工作了....
客户端id: 01, 客户端name: client-01,消息: hello world

client

[INFO] [07/08/2020 11:13:06.549] [main] [Remoting] Starting remoting
[INFO] [07/08/2020 11:13:07.249] [main] [Remoting] Remoting started; listening on addresses :[akka.tcp://client-actorsystem@127.0.0.1:9990]
[INFO] [07/08/2020 11:13:07.250] [main] [Remoting] Remoting now listens on addresses: [akka.tcp://client-actorsystem@127.0.0.1:9990]
this.serverActorRefer=ActorSelection[Anchor(akka.tcp://server@127.0.0.1:9999/), Path(/user/server-actor)]
客户端开始工作...
hello world
收到服务器消息:ServerMessage(hello world)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内容简介 本书将尝试帮助入门级、中级以及高级读者理解基本的分布式计算概念,并且展示 如何使用 Akka 来构建具备高容错性、可以横向扩展的分布式网络应用程序。Akka 是一 个强大的工具集,提供了很多选项,可以对在本地机器上处理或网络远程机器上处理的 某项工作进行抽象封装,使之对开发者不可见。本书将介绍各种概念,帮助读者理解 网络上各系统进行交互的困难之处,并介绍如何使用 Akka 提供的解决方案来解决这些 问题。 作者简介 Jason Goodwin 是一个基本上通过自学成才的开发者。他颇具企业家精神,在学校 学习商学。不过他从 15 岁起就开始学习编程,并且一直对技术保持着浓厚的兴趣。这对 他的职业生涯产生了重要的影响,从商学转向了软件开发。现在他主要从事大规模分布 式系统的开发。在业余时间,他喜欢自己原创电子音乐。 他在 mDialog 公司第一次接触到 Akka 项目。mDialog 是一家使用 Scala/Akka 的公司, 为主流出版商提供视频广告插入软件。这家公司最终被 Google 收购。他同时还是一名很 有影响力的“技术控”,将 Akka 引入加拿大一家主要的电信公司,帮助该公司为客户提 供容错性更高、响应更及时的软件。除此之 外,他还为该公司中的一些团队教授 Akka、 函数式以及并发编程等知识。 目录 第 1 章 初识 Actor:Akka 工具集以及 Actor 模型的介绍。 第 2 章 Actor 与并发:响应式编程。Actor 与 Future 的使用。 第 3 章 传递消息:消息传递模式。 第 4 章 Actor 的生命周期—处理状态与错误:Actor 生命周期、监督机制、Stash/ Unstash、Become/Unbecome 以及有限自动机。 第 5 章 纵向扩展:并发编程、Router Group/Pool、Dispatcher、阻塞 I/O 的处理以 及 API。 第 6 章 横向扩展—集群化:集群、CAP 理论以及 Akka Cluster。 第 7 章 处理邮箱问题:加大邮箱负载、不同邮箱的选择、熔断机制。 第 8 章 测试与设计:行为说明、领域驱动设计以及 Akka Testkit。 第 9 章 尾声:其他 Akka 特性。下一步需要学习的知识。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值