原文链接
Akka是JAVA虚拟机平台上构建高并发、分布式和容错应用的工具包和运行时。Akka用Scala语言编写,同时提供了Scala和Java的开发接口。Akka处理并发的方法基于Actor模型,Actor之间通信的唯一机制就是消息传递。
Akka特点:
对并发模型进行了更高的抽象
是异步、非阻塞、高性能的事件驱动编程模型
是轻量级事件处理(1GB内存可容纳百万级别个Actor)
它提供了一种称为Actor的并发模型,其粒度比线程更小,你可以在系统中启用大量的Actor。
它提供了一套容错机制,允许在Actor出现异常时进行一些恢复或重置操作。
Akka既可以在单机上构建高并发程序,也可以在网络中构建分布式程序,并提供位置透明的Actor定位服务。
maven依赖:
Actor模型
在并发程序中线程是并发程序的基本执行单元,但在Akka中执行单元是Actor。
传统并发程序是基于面向对象的方法,通过对象的方法调用进行信息传递,如果对象的方法修改对象本身的状态,在多线程下就可能出现对象状态的不一致,此时就必须对方法调用进行同步,而同步操作会牺牲性能。
在Actor模型中并不是通过Actor对象的某个方法来告诉Actor需要做什么,而是给Actor发送一条消息。当一个Actor收到消息后,它有可能根据消息的内容做出某些行为,如更改自身状态,此时这个状态的更改是Actor自身进行的,并非由外界干预进行的。
Greeter定义
HelloWorld定义
sample.conf
main方法
运行结果
第一行打印了HelloWorld Actor的路径,它是系统内第一个被创建的Actor。路径为:akka://hello/user/helloworld。第一个hello表示ActorSystem的系统名称,即构造时第一个入参。user表示用户Actor,所有的用户Actor都会挂载在user路径下。最后helloworld是这个Actor的名字。
第二行打印了Greeter Actor的路径,三、四行为Greeter中输出的信息。
第五行表示系统遇到了一条消息投递失败,原因是HelloWorld将自身停止了,导致Greeter发送的信息无法成功投递。
当使用Actor进行并发开发时,关注点已经不在线程上了,线程调度已经被Akka框架进行封装,只需关注Actor对象即可。Actor对象之间的通过显示的消息发送来传递信息。
当系统内有多个Actor时,Akka会自动在线程池中选择线程来执行我们的Actor,不同的Actor可能会被同一个线程执行或者一个Actor可能被不同的线程执行。
注意:不要在一个Actor中执行耗时的代码,这样可能会导致其他Actor的调度出现问题。
消息投递
Akka应用是由消息驱动的,消息是除Actor之外最重要的核心组件。在Actor之间传递的消息应该满足不变性,即不变模式,可变的消息无法高效的在并发环境中使用。在Akka中推荐使用不可变对象。在代码中可以使用final字段声明,在消息构造完成后,就不能再发生改变了。
消息投递策略:
至多一次投递:此策略中每一条消息最多会被投递一次,可能会偶尔出现投递失败的情况,从而导致消息丢失。此策略高性能。
至少一次投递:此策略中每一条消息至少会被投递一次,直至成功。在一些偶然的情况,接收者可能会收到重复消息,但消息不会丢失。此策略需要保存消息投递的状态并不断重试。
精确投递:所有消息保证被精确的投递并成功接收一次,既不会丢失也不会重复。此策略成本最高且不易实现。
关于消息的可靠性:没有必要在Akka层保证消息的可靠性,这样做成本太高且无必要。消息可靠性应该在应用的业务层进行保证,有时丢失一些消息是符合应用要求的。
消息投递的顺序性:Akka可以保证在一定程度上的投递顺序性。如Actor A1向A2顺序发送了M1、M2、M3三条消息,Actor A3想A2顺序发送了M4、M5、M6三条消息,则系统可以保证:
对于A2来说,来自A1向A3的消息并没有顺序性保证。
另外这种消息投递规则不具备可传递性,如下图:
C收到M1和M2的顺序是没有保证的
--参考文献《实战Java高并发程序设计》
作者:夏与清风
链接:https://www.jianshu.com/p/7d941a3b0ccb
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。