Akka概述
Akka 是一个开源的并发、分布式、基于消息驱动的框架,用于构建高可伸缩性、可靠性和并发性强的应用程序。它是基于 JVM(Java虚拟机)的,主要使用 Scala 编程语言开发,但也提供了 Java API,因此可以在 Java 和 Scala 中使用。
以下是 Akka 框架的关键概念和特点:
- Actor 模型:Akka 的核心构建块是 Actor,它是一种轻量级并发原语。Actor 之间通过消息通信进行互动,每个 Actor 都有自己的状态和行为,它们之间是相互隔离的,这有助于构建高度可伸缩的系统。
- 并发性和并行性:Akka 允许开发人员轻松编写并发和并行代码,而不必担心底层线程管理。它处理所有与多线程编程相关的复杂性,并提供了抽象,以便开发人员可以专注于业务逻辑。
- 分布式系统:Akka 提供了构建分布式系统的支持。您可以将 Actor 部署在不同的节点上,这些节点可以是物理机器或虚拟机。Akka 提供了透明的消息传递,使得在分布式环境中发送消息就像在本地一样简单。
- 容错性:Akka 强调容错性,允许开发人员构建可靠的系统。它提供了监督策略,允许在 Actor 发生故障时采取自定义的恢复操作。这有助于系统在故障时继续运行,提高了系统的可用性。
- 事件驱动:Akka 是基于事件驱动的,它的响应式编程模型适合处理异步事件。它允许开发人员构建反应迅速的系统,适用于大量的并发事件和消息。
- 扩展性:Akka 具有良好的可伸缩性,可以根据需求轻松扩展系统。您可以添加更多的节点或 Actor 来处理更多的负载。
- 插件和扩展:Akka 提供了丰富的插件和扩展机制,可以轻松集成其他库和框架,如 Akka HTTP、Akka Streams 等,以构建全栈应用程序。
为了保持回弹性,Akka采用了“让它崩溃(Let it crash)”模型,该模型已在电信行业成功用于构建具有自我修复功能的应用程序和系统。Actor模型还提供对透明分发的抽象,以及真正可伸缩和容错的应用程序的基础。
下面看下Akka的特性:
可以更简单地构建并发和分布式系统
Akka基于Actor模型和Streams,让我们可以构建可伸缩的,并且可以高效使用服务器资源,使用多个服务器进行扩展的系统。
回弹性设计
遵守“反应式宣言”的原则,Akka让我们编写出可以在出现故障时能够自我修复,并保持响应能力的系统。
高性能
在单台计算机上可以处理高达每秒5000万条消息。内存占用少;每GB堆可以创建约250万个actor(参与者)。
弹性和分散性
分布式系统没有单点故障,具有跨节点的负载平衡和自适应路由。具有群集分片的事件源和CQRS(Command Query Responsibility Segregation,读写责任分离)。使用CRDT(Conflict-free Replicated Data Types,无冲突的复制数据类型)实现最终一致性的分布式数据。
反应流数据
具有回压的异步非阻塞流处理。完全异步和基于流的HTTP服务器和客户端为构建微服务提供了一个很好的平台。
传统编程模型存在的问题
对封装特性的挑战
- 面向对象编程中的封装要求数据只能通过对象提供的方法间接访问,但多线程下多个线程同时修改对象内部数据会导致线程安全问题。
- 解决线程安全问题的方式是使用锁,但锁的使用会影响性能、可能导致死锁,并且难以扩展到分布式系统中。
对共享内存在现代计算机架构上的误解
- 在多核CPU架构中,多线程之间不再有真正的共享内存,而是通过Cache行传递数据,使得共享变量的内存可见性成为问题。
- 使用volatile关键字或原子性数据结构可以解决共享变量的内存可见性问题,但会损害性能,需要谨慎选择需要修饰的变量。
对调用堆栈的误解
- 传统的调用堆栈模型不适用于并发编程,因为异步任务无法通过调用堆栈传递异常或通知主线程。
- 异步任务执行失败时,任务状态可能丢失,需要引入新的错误信令机制以及从故障中恢复的方法。
这些问题突出了Actor模型的优势,因为它提供了一种更适应并发编程的方式,通过消息传递来解决上述挑战,而不是依赖于共享内存和传统的调用堆栈。 Actor模型在处理并发和分布式系统中已经得到验证。
Actor模型解决了传统编程模型的问题
Actor模型
Actor模型用于处理并发计算,每个Actor代表一个基本的计算单元,可以接收消息并基于消息进行计算处理。
Actor之间相互隔离,不共享内存,每个Actor拥有自己的私有状态变量。
每个Actor有自己的地址,通过地址相互发送消息来通信,消息是异步传递的。
Actor模型允许构建分布式系统,不限于单个JVM内。
【Actor系统图】
使用消息传递避免锁和阻塞
Actor之间通信通过消息传递而不是方法调用,不会导致发送消息的调用线程被阻塞。
Actor保持了封装性,因为消息的处理是串行的,不需要使用锁来同步多线程访问。
Actor的状态是本地的,不共享,通过消息传递数据,符合现代系统中内存工作方式。
Actor可以高效地处理大量消息,充分利用多核CPU的潜力。
使用Actor优雅地处理错误
Actor模型中不存在共享调用堆栈,因此错误处理方式不同。
目标Actor可以回复错误消息,提示发生错误情况,错误作为普通消息处理。
Actor模型中采用树状层次结构的监督机制,父Actor可以对子Actor的故障进行监控和处理。
监督程序可以决定是否重新启动子Actor或停止子Actor,确保系统的可恢复性和健壮性。
小结
总的来说,Akka 是一个强大的框架,适用于构建高度并发、分布式、可伸缩和容错性强的应用程序。它在金融、社交媒体、在线游戏等领域得到广泛应用,是构建响应式系统的有力工具。如果您需要构建这类应用程序,了解和使用 Akka 可能会非常有帮助。