
AKKA是JVM上的Actor模型的实现,用于构建响应式,高并发,分布式应用的工具包.
这里首先介绍下Actor模型: Actor模型是由Carl Hewitt在1973年提出的用于解决并发计算的数学模型,不过受限于当时的硬件条件, 并没有普遍应用的实现. 在Actor模型理论体系中,Actor是并发计算的通用基本单元, Actor可以接受/发送消息, 创建其他Actor, 并且有自己的状态, Actor之间基于消息来通信.
Actor发送消息是非阻塞式的, 每个Actor同时只会处理一个消息, 这样也避免了并发控制和锁竞争等题.
当Actor接收消息时会有以下流程:
🔘被发送的消息加入叫做mailbox的队列末尾
🔘任务调度获取到Actor并开始执行
🔘Actor从队列开始提取消息并开始消息处理逻辑
🔘如果需要与其他Actor通信, 则发送消息到其他Actor
那么比较下传统的OOP的方式:
其中同一段方法会有两个线程调用执行, 这样就涉及到共享变量的线程安全问题, 需要引入锁机制, 这样会对并发性能有影响, 并且有死锁的隐患, 而且调用线程在等待方法执行的过程中是阻塞的, 这样其实也是资源的浪费. 当来到多实例交互的情况下, 还需要引入分布式锁, 又增加了系统的复杂性.
那么基于AKKA的这套toolkit能提供以下的特性:
🔘避免编写底层并发代码来支持多线程, 无需过多考虑内存可见性问题,更多的专注于功能实现.
🔘更简单的服务和模块之间的通信
🔘集群架构, 易于扩展实例
下面从AKKA官方demo的quickstart入手, 初步了解下AKKA, AKKA支持Java和Scala, 这里用Java做介绍:
运行gradle run后能看到输出:
首先定义了Greeter Actor:
其中Greeter Actor继承了akka.actor.AbstractActor并实现了createReceive方法, 在此方法中定义了消息接收实现, 其中具体到匹配消息类型和对应的操作.
这里创建的props是用来在AKKA容器中初始化Actor的一种通用模式, 其中的ActorRef则是Printer Actor的引用, 通过printerActor.tell的方式来向相应的Actor发送消息.
下面是Printer Actor的实现:
这里定义了欢迎消息体Greeting, 并在createReceive中匹配消息打印信息.
下面看下Actor的初始化:
这里的akka.actor.ActorSystem是Actor的容器, 负责管理Actor的生命周期, 通过actorOf方法传入props和name来创建Actor, 其中name用来在容器中寻找Actor, 所以需要有含义的命名, 示例代码中创建了3个Greeter Actor和1个Printer Actor, 并通过tell的方式向Greeter发送了WhoToGreet消息和Greet消息, 这样我们才看到了最开始的欢迎语输出, 整体流程如下:
以上只是AKKA的一个入门介绍, 如果需要搭建一套成熟的基于AKKA的分布式应用还需要了解更多的AKKA组件和集群配置体系. 有兴趣的朋友可以更多了解下.
Reference Link:
https://doc.akka.io/docs/akka/current/guide/index.html
https://en.wikipedia.org/wiki/Actor_model
往期精彩:

