主要优点
Orleans的主要优点有:甚至非专家级的程序员都能够达到很高的生产力;对于程序员透明的自带的可扩展性。下面展开来讲这些有点。
开发者的生产力
Orleans编程模型通过提供以下抽象、保证和系统服务来提高专家级和非专家级程序员的生产力。
- 类似面向对象编程(OOP)模型。 Actor是实现了具有异步方法的.NET actor接口的.NET类。因此actor对于程序员来说就是其方法可以直接invoke的远程对象。通过一些列完全透明的过程将方法调用转换成消息,将他们路由到正确的终结点,调用目标actor的方法并且处理错误和极端状况,最终提供给程序员一个类似面向对象编程模型。
- actor的单线程执行. 运行时保证一个actor绝对不会同时在一个以上的纤程执行。结合与其他的actor的失误隔离,程序员永远不会面临actor层面的并发问题,并且因此永远不用使用锁或者其他的同步机制来控制对共享数据的访问。这个特性使得非专家级的程序员也能跟踪调试分布式应用。
- 激活透明化。 运行时只有当有消息需要actor处理的时候才激活actor。这样很清楚的区分了创建一个actor的引用(可见的并且可以通过代码控制)和实际物理内存中的actor激活(对于应用完全透明)两个概念。 很多方面,这有些类似虚拟内存决定什么时候“换入”(激活)或者什么时“换出”(停用)一个actor;应用可以持续访问actor的全部的“内存空间”,不管是否在物理内存中。通过在硬件资源池中安排和迁移actor使得透明的激活可以动态地自适应地进行负载均衡。这个特性是对传统的actor模型(actor的生命周期由应用控制)的重大改进。
- 位置透明化。 程序员用来调用actor方法或者传递给其他组件的的一个actor引用(代理对象)只包含actor的逻辑标识。actor的逻辑表示到它的物理位置的翻译工作和响应的消息的路由是完全透明的,由Orleans运行时完成的。应用代码与其他的actor通信完全不用知道其他actor的物理位置,物理位置可能在这段时间因为错误或者资源管理而而改变,或者因为一个actor在它被调用的时候已经停用。
- 与持久存储集成的透明化。 Orleans允许actor内存中的状态到持久存储的声明式的映射。他同步更新,透明地保证只有在持久状态已经成功后调用者才收到结果。 可以很容易地扩充并且/或者定制一些列现有的持久优化provider。
- 错误的自动传播。 运行时根据异步语义和分布式try/catch自动沿着调用链传播未处理的错误。最终,错误不会在应用内丢失。这使得程序员可以将错误处理逻辑放在合适的地方,不必啰嗦地在每一层手动的传播错误。
默认的透明的可扩展性
Orleans编程模型是设计用来指导程序员可能成功地成数量级的扩展他们的应用或者服务。这是结合了过往经验的最佳实践和模式,并且提供底层系统功能的有效实现。下面说一下几个保证可扩展性和性能的关键因素。
- 应用程序状态的隐式细粒度划分。 通过将actor作为直接寻址的实体,程序员隐式地划分了他们应用程序的整体状态。虽然Orleans框架没有规定一个actor的大小,在大多数情况保持相对大量(百万或者个多)的actor是有意义的,每一个actor代表应用的一个自然实体,就像用户账户或者采购订单之类的。
- 自适应资源管理。 因为actor不对与他们交互的actor的位置做任何假设并且位置透明,运行时可以动态地管理和调节现在有可用硬件资源的分配,运行时可以在计算集群中做一些细粒度的放置/迁移,达到对负载进行响应和不会请求失败的通信模式。如果有必要,运行时可以通过创建特定actor的多副本来提高吞吐量,并且不需要修改任何代码。
- 多路复用通信。 actor在Orleans框架中具有逻辑终结点,并且他们之间的通信复用一组固定的全交换物理连接(TCP scokets)。这使得运行时仅仅使用很低的系统开销就可以承载大量(百万级)的可寻址实体。另外激活/停用一个acttor不会导致物理终结点的注册/注销开销(TCP端口或者HTTP URl,甚至关闭一个TCP连接)。
- 有效的调度。 运行时在一个线程池中调度大量的单线程actor,每个线程使用一个物理处理器核。因为actor的代码是非阻塞连续风格的(Orleans编程框架的要求之一),应用代码以一种高效的“合作”多线程形式无竞争地运行。这使得系统可以达到很高的吞吐量和有很高的CPU利用率(高达90%+)仍然十分稳定。事实表明系统中actor数量和负载的增长不会导致多余的线程或者系统原语,这点提高了各个节点和整个系统的可扩展性。
- 显式异步。 Orleans编程模型使得分布式应用的异步特性更加明显,并且指导程序员写异步的非阻塞的代码。结合异步消息和高效的调度,可以在没显式使用多线程的情况下很大程度地提高分布式并行性和整体吞吐量。