.NET的Actor模型:Orleans

14-07-22 banq
              

Orleans是微软推出的类似Scala Akka的Actor模型,可用于实现DDD+EventSourcing/CQRS系统。

Orleans是一个简化开发的可伸缩的云服务的项目。   

 构建交互式服务的可伸缩性和可靠性是困难的。交互性对可用性和延迟有严格要求,直接影响最终用户的体验。为支持大量并发用户会话,高吞吐量是至关重要的。

传统的三层体系结构包括无状态的前端,无状态的中间层和存储层在可伸缩性方面是有限制的,由于存储层在延迟和吞吐量方面的限制,这对于每个用户请求都有影响。通常办法是在中间层和存储层之间添加缓存层来提高性能。然而,缓存会失去了大部分的并发性和底层存储层的语义保证。为了防止缓存和存储池的不一致更新,应用程序或缓存管理器需要实现一个并发控制协议。

无论是否使用缓存,无状态中间层并不提供本地数据,因为它使用的是数据装载范式: 对于每个请求,数据是来自存储层或缓存加装到中间层,如果是一个社会关系图,一个请求将会激活关联很多子实体对象,这就对缓存一致性带来更大的挑战。

Actor模型提供了一个解决这些挑战的有吸引力的依靠函数装载的范式。Actor允许建立一个有状态的中间层,缓存的性能优势与封装的数据局部性都通过特定于应用程序的业务实体封装协调了(DDD的聚合根用行为守卫状态,聚合根保存在缓存中,聚合根实体的状态字段也在缓存中,对状态字段的操作只能通过实体行为,保证状态一致性)。此外,Actor容易实现中间层中水平的、“社会”、实体之间的关系。

分布式系统编程的另一个观点是面向对象编程(OOP)范例。虽然OOP是一个建立复杂系统模型直观的方法,但是他被受欢迎的面向服务的体系结构(SOA)边缘化了。当然人们仍然可以受益于OOP实现服务组件时。然而,在系统层面上,开发人员必须考虑松耦合的分区服务,通常会导致和应用程序的概念业务对象不匹配,这导致了目前主流方向由开发人员构建分布式系统非常困难。Actor模型将OOP带回了系统级开发,开发人员非常像熟悉交互的对象的模型。

例如Erlang和Akka的Actor平台在简化分布式系统编程方面是向前迈出了一步。然而,他们仍然负担与许多分布式系统的复杂性,因为开发人员面临相对低水平的抽象和系统服务。关键的挑战是开发管理Actor生命周期的代码,处理分布式竞争、处理故障和恢复Actor以及分布式资源管理等等都很复杂,因此,如果建立一个应用程序必须正确的解决这些问题,开发人员则必须是一个分布式系统专家(难度太大)。

为了避免这些复杂性,我们建造了Orleans的编程模型,运行时它提高了Actor的抽象级别。Orleans的目标不是分布式系统专家级别的开发人员,虽然我们的专家客户发现它也有吸引力。和现有的基于actor平台有本质差异,它是把Actor作为虚拟实体,而不是实际物理的。

首先,一个Orleans的Actor总是存在的,但是它不能被显式地创建或销毁。它的存在超越任何内存中任何实例的生命周期,从而超越了任何特定服务器的生命周期。

第二,Orleans Actor是自动实例化:如果内存没有Actor实例,它会自动创建,发送到Actor的一个消息是当前服务器上创建一个新的实例。一个未使用的Actor实例作为运行时资源管理的一部分自动回收。一个actor实例从来不会失败: 如果服务器S崩溃, 发送给这个S中Actor的下一个消息将被自动实例化到另外一个服务器A,消除应用程序需要监督和人为编码显式地重建失败的Actor。

第三,Actor的位置实例对应用程序代码是透明的,这极大地简化了编程。

第四,Orleans可以自动创建多个实例相同的无状态的Actor,Actor可以无缝地热扩展。

Orleans给开发人员一个虚拟“Actor空间”,类似于虚拟内存,使他们能够调用系统中的任何Actor,不管它是否存在于内存。虚拟化间接依赖从虚拟Actor到实际Actor的映射。这种级别的间接寻址为运行时解决许多分布式系统问题带来机会,否则开发人员必须直接自己解决这些复杂问题,如Actor定位和负载平衡、失活未使用的Actor,复苏因服务器失败的Actor,这是出了名的困难。因此,虚拟Actor方法大大简化了编程模型。同时允许运行时加载和透明地从失败中恢复。

Orleans已经被用于构建多个生产服务,当前运行在微软Windows Azure云,包括一些受欢迎的游戏的后端服务。这使我们能够验证使用Orleans为生产编写的应用程序的可伸缩性和可靠性,并根据反馈调整模型和实现。它还使我们能够验证,至少据坊间传言,Orleans编程模型导致显著增加了程序员的工作效率。

              

4
banq
2014-07-22 09:56

出版过“实现DDD”一书的Vaughn Vernon在twitter质疑Orleans不是一个Actor模型,因为总是存在的Actor组件模型好像容易产生误差。

但是Sergey认为常驻内存的模型不容易产生误差,因为它消除了竞争和简化了失败恢复。

Twitter讨论

INFQ关于这段对话的文章:http://www.infoq.com/news/2014/07/approaches-actor-model-net

我个人认为:Orleans实际力图重新以Actor异步消息思路重新开发一个EJB容器,区别于EJB是同步事务慢的特点,Orleans应该是吸取了EJB简化网络复杂的设计思路,但是能否成功?是否会发生抽象泄漏还有待观察,这也是Reactive运动倡导拥抱网络的原因所在,但是网络如果像Web那样简单确实是可以拥抱的,比如现在前端Angular也是倡导拥抱Web,打败了后端MVC框架JSF等,这些后端MVC框架就是当初视图避免程序员接触Web底层,结果搞得比Web底层还要复杂而失败。

根据CAP定律,网络之间的丢包是应该允许的,而Actor模型好像把这种丢包处理扔给程序员开发,那么程序员就要模拟丢包现场,那么模拟软件能那么逼真吗?恐怕容易造成程序员刻舟求剑的解决丢包容错吧,这些问题至少应该由中间件来完成。

rockfire
2014-08-05 12:04

必须依赖azure吗?