Scala消息通信之akka,akka案例
来源:互联网 发布:看程序员直播 编辑:程序博客网 时间:2024/05/10 07:22
Scala编程实战
一、 课程目标
1. 目标:熟练使用Scala编写程序
二、 项目概述
1. 需求
目前大多数的分布式架构底层通信都是通过RPC实现的,RPC框架非常多,比如前我们学过的Hadoop项目的RPC通信框架,但是Hadoop在设计之初就是为了运行长达数小时的批量而设计的,在某些极端的情况下,任务提交的延迟很高,所有Hadoop的RPC显得有些笨重。
Spark 的RPC是通过Akka类库实现的,Akka用Scala语言开发,基于Actor并发模型实现,Akka具有高可靠、高性能、可扩展等特点,使用Akka可以轻松实现分布式RPC功能。
2. Akka简介
Akka基于Actor模型,提供了一个用于构建可扩展的(Scalable)、弹性的(Resilient)、快速响应的(Responsive)应用程序的平台。
Actor模型:在计算机科学领域,Actor模型是一个并行计算(Concurrent Computation)模型,它把actor作为并行计算的基本元素来对待:为响应一个接收到的消息,一个actor能够自己做出一些决策,如创建更多的actor,或发送更多的消息,或者确定如何去响应接收到的下一个消息。
Actor是Akka中最核心的概念,它是一个封装了状态和行为的对象,Actor之间可以通过交换消息的方式进行通信,每个Actor都有自己的收件箱(Mailbox)。通过Actor能够简化锁及线程管理,可以非常容易地开发出正确地并发程序和并行系统,Actor具有如下特性:
1.提供了一种高级抽象,能够简化在并发(Concurrency)/并行(Parallelism)应用场景下的编程开发
2.提供了异步非阻塞的、高性能的事件驱动编程模型
3.超级轻量级事件处理(每GB堆内存几百万Actor)
案例介绍:
知识点说明:
1.Akka可以实现不同进程之间的通信
2.老大叫ActorSystem,用于创建和监控Acotr
3.真正用于通信的是Acotr
4.一个进程里面可以有多个Acotor
5.可以有多个进程
6.如果不同ActorSystem下面的Acotor要进行通信,首先AcotorSystem之间要建立连接
在akka的程序中,需要服务端和客户端。
创建一个maven项目,其中maven项目的pom.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.toto.akka</groupId> <artifactId>MyRPC</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> <encoding>UTF-8</encoding> <scala.version>2.10.6</scala.version> <scala.compat.version>2.10</scala.compat.version> </properties> <dependencies> <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> <version>${scala.version}</version> </dependency> <dependency> <groupId>com.typesafe.akka</groupId> <artifactId>akka-actor_2.10</artifactId> <version>2.3.14</version> </dependency> <dependency> <groupId>com.typesafe.akka</groupId> <artifactId>akka-remote_2.10</artifactId> <version>2.3.14</version> </dependency> </dependencies> <build> <!-- 源码包放置的位置 --> <sourceDirectory>src/main/scala</sourceDirectory> <testSourceDirectory>src/test/scala</testSourceDirectory> <plugins> <!--专门用于编译scala的插件--> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>3.2.2</version> <executions> <execution> <goals> <goal>compile</goal> <goal>testCompile</goal> </goals> <configuration> <args> <arg>-make:transitive</arg> <arg>-dependencyfile</arg> <arg>${project.build.directory}/.scala_dependencies</arg> </args> </configuration> </execution> </executions> </plugin> <!--主要使用来的打包的插件--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.4.3</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <filters> <filter> <artifact>*:*</artifact> <!--表示把下面的这些文件给删掉--> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>reference.conf</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>cn.toto.akka.Worker</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build></project>
其中服务端的代码如下:
package cn.toto.akkaimport akka.actor.{Actor, ActorSystem, Props}import com.typesafe.config.ConfigFactory/** * Created by toto on 2017/7/2. */class Master extends Actor { override def receive: Receive = { //里面要有一个偏函数 case "start" => { println("starting...") println("started....") } case "stop" => { println("stoping...") println("stopted..."); } //master接收到worker的消息 case "connect" => { println("a client connected...") //这里表示向客户端发送一个消息 sender ! "success" } case _ => println("123") }}object Master { def main(args: Array[String]): Unit = { //通过s,可以将变量通过$取到 val host = "127.0.0.1" val port = "8888" val confStr = s""" |akka.actor.provider = "akka.remote.RemoteActorRefProvider" |akka.remote.netty.tcp.hostname = "$host" |akka.remote.netty.tcp.port = "$port" """.stripMargin //读取一些默认的配置文件 val conf = ConfigFactory.parseString(confStr) //ActorSystem单例的,用于创建Actor并监控actor val actorSystem = ActorSystem("MasterActorSystem",conf) //通过ActorSystem创建Actor,可以通过Ctrl + P的方式看到这个方法里面可以有哪些参数 //通过Master类型,反射创建实例 var master = actorSystem.actorOf(Props[Master],"Master") //接着可以发消息了。后续这里可以不是发字符串,可以发case class master ! "start" master ! "hello" master ! "stop" actorSystem.awaitTermination() }}
另外,worker端的代码如下:
package cn.toto.akkaimport akka.actor.{Actor, ActorSystem, Props}import com.typesafe.config.ConfigFactory/** * Created by toto on 2017/7/2. */class Worker extends Actor{ //actor里面有声明周期方法 //preStart在构造器之后receive之前执行 override def preStart(): Unit = { //首先跟Master建立连接,其中"akka.tcp://MasterActorSystem@127.0.0.1:8888"可以在Master运行之后的控制台中找到 //下面的地址:"akka.tcp://MasterActorSystem@127.0.0.1:8888"表示要先连接actorSystem,接着要和它下面的/user/Master建立通信 //这样就相当于拿到了master的代理对象 val master = context.actorSelection("akka.tcp://MasterActorSystem@127.0.0.1:8888/user/Master") //通过mater的引用向Master发送消息 //向master发送connect消息 master ! "connect" } override def receive: Receive = { case "success" => { println("a msg form master:success") } }}object Worker { def main(args: Array[String]): Unit = { //通过s,可以将变量通过$取到 //val host = args(0) //val port = args(1).toInt val host = "127.0.0.1" val port = "9999" val confStr = s""" |akka.actor.provider = "akka.remote.RemoteActorRefProvider" |akka.remote.netty.tcp.hostname = "$host" |akka.remote.netty.tcp.port = "$port" """.stripMargin val conf = ConfigFactory.parseString(confStr) //单例的ActorSystem val actorSystem = ActorSystem("WorkerActorSystem",conf) //通过actorSystem来创建actor val worker = actorSystem.actorOf(Props[Worker],"Worker") //这里是等待优雅退出 actorSystem.awaitTermination() }}
运行过程:
1、先启动Master(右键run),运行后的效果如下:
2、接着运行worker(右键run),运行后的效果如下:
- Scala消息通信之akka,akka案例
- Scala之AKKA
- 学习akka之消息
- Scala - Akka
- Scala Akka akka-java-spring
- akka之RPC通信1
- Akka
- Akka
- Akka
- Akka
- scala分布式框架-akka
- Scala Akka库学习
- Akka Documentation(Scala) Introduction
- Minimal Akka Scala Seed
- scala akka wordcount程序
- flink akka scala
- scala akka 资料
- scala akka 中文译文
- 【洛谷P3818】小A和uim之大逃离 II
- 何为面向服务(Service)?及其由来与规则
- 卡方函数和皮尔逊函数选取最佳特征
- 旋转数组的最小数字
- E: 无法获得锁 /var/lib/dpkg/lock – open (11: 资源暂时不可用)
- Scala消息通信之akka,akka案例
- Control Smart Car By Arduino
- 基于以太坊构建私有区块链网络教程指南
- java:Java入门第三季第五课:抛出错误
- Ubuntu16.04软件中心一直闪退的问题
- 缓存淘汰算法--LRU算法(java代码实现)
- 集合2 Iterator迭代器 ListIterator
- java中long类型转换为int类型
- 【洛谷P3819】松江1843路