使用Akka, Spring Boot, DDD建立Java分布式系统

17-04-18 banq
                   

当需要处理的数据增长超过单个JVM中时,这时候AKKA集群提供了构建此类实现的可扩展的解决方案。这是一篇涉及分布式计算许多方面的文章。请准备在文章上阅读上花费大量的时间,参考所提到的各种外部链接,才能充分了解每个子主题,并可下载并运行文章提供的AKKA initializer/ util代码库才能更深入地了解本文主题。这里所提供的initializer程序库具有良好的文档注释,贯穿整个代码都提供了代码的上下文含义。

actor是AKKA的构建块。通过使用AKKA集群分片sharding技术,Actor可以在AKKA集群中的许多可用节点之一中创建。针对群集分片的AKKA Actor的消息是使用分片算法进行路由传入。在许多情况下,每个群集分片的AKKA Actor代表了领域驱动设计(DDD)的一个聚合[root] 。

AKKA持久性模块使开发人员能够创建有状态的Actor,Actor状态被持久化为事件溯源,并且可以在actor或节点发生故障后恢复。上述集群分片的actor可以使用AKKA弹性持久性配置

将AKKA与Spring框架结合起来可以从两个世界中获益匪浅。

目的

本文为用户提供了一个使用上述技术栈的可重用的akka-initializer程序库。将上述技术集成在一起使用并不是一件小事,本文就是旨在简化这项复杂事情。akka-initializer库可用于基于微服务实现大型分布式系统。

本文的后半部分采用银行领域的一个任意用例。该例属于 复杂事件处理(CEP:Complex Event Processing )领域。本文演示了如何使用akka-initializer库构建高度可扩展和灵活的CEP解决方案。

akka-initializer库有以下功能:

1.使集群分片实现更容易。

2.使AKKA持久化实现更容易。

3.通过提供一组实用程序类,使单元测试更容易。

4.使AKKA和Spring引导集成更容易。

5.提供了一个名为生存时间 time-to-live的功能:当集群切片actor实现此接口时,该actor将被akka-initializer库自动删除,包括从持久存储和内存中清除该actors的状态。

6.提供一个名为消息到期Message-Expiry的功能:当包含状态的集群切片actor中现此接口时,actor中状态将被akka-initializer库以指定的间隔自动过期。

AKKA-Initializer详细解释

该项目源码见Github,Clone该项目,作为Maven项目导入IDE,执行git clean install ,并运行单元测试案例。

Akka Actor基础知识:AKKA支持其核心的异步消息处理。每个处理逻辑表示为一个actor,actor有一个与之相关联的邮箱。消息通过邮箱发送给另外Actor,并按照收到的顺序发送。这些内存中消息由AKKA框架自动创建。Actor可以是本地Actor,远程Actor或在AKKA集群中运行的Actor。

多个actor系统节点可以组合形成一个AKKA集群,以这种方式Actor系统扩展到多台机器。

akka-initializer库可以轻松创建AKKA集群切片Actor。下面讲解关于AKKA集群分片内部工作概述,以及akka-initializer库如何简化实现集群分片。每个分片的[Aggregate] actor只需要在AKKA集群中的一个可用节点上运行。




1.AkkA使用内部分片sharding actor来管理许多sharded-entity actor,sharding actor是帮助在一个集群内的sharded-entity actor进行通信,并处理这些Actor的故障切换和恢复,传入消息的Shard-id和entity-id 用于确定该消息应该发送哪个 sharded-entity actor。

2.sharded-entity actor会通过entity-id创建,akka-initializer库的Message接口定义了一个通过系统发送的消息的强制执行合同,必须包含entity-id字段和可选的shard-id。

3.如果Shard-Id 不存在,则akka-initializer库使用稳定算法从消息的entity-id中导出。

4.Entity-id 是聚合ID,并在分片shard中使用,以确定消息需要发往目的地的实际聚合。

5.shard应该配置在shard region中, shard regions 应该在程序启动时启动,在启动过程中,可以通过YAML文件选择提供初始化参数。akka-initializer库使这些步骤更容易

6.在一个节点发生故障时,AKKA会重新启动shard region分片区域,并自动将该分片区域内的sharded-entity actor迁移到可用节点之一。

akka-initializer可以轻松创建AKKA persistence actors(持久性):

1.AKKA持久性模块可以轻松实现事件溯源。因此,当一个节点失败时,actor的状态会在其他任何一个可用节点上自动重新创建。

2.akka-initializer库使所有上述设置变得更加容易。

3.akka-initializer库可以方便地使用内存中的持久性存储来进行单元测试。对于生产场景,应使用如Cassandra等信任持久存储。

4.随着时间的推移,集群分片的持久性actor本身可能需要被终止。akka-initializer库具有这样的功能,可以通过实现一个名为TimeToLive的接口实现。

5.随着时间的推移,集群中持久性actor实例状态的旧消息/数据应该过期失效。从用户的角度来看,他们需要实现两个接口。集群分片的持久化actor应该实现MessageExpiry 接口,而持有actor状态的类应该实现MessageExpiryListener接口。

更详细案例见:

Scalable, Distributed Systems Using Akka, Spring B

                   

9