写在前面
Orleans 是基于 Actor 模型思想的. NET 领域的框架, 它提供了一种直接而简单的方法来构建分布式大规模计算应用程序, 而无需学习和应用复杂的并发或其他扩展模式. 我在 2015 年下半年开始应用 Orleans, 当时公司的交易系统采用的架构就是基于 Orleans 框架的, 其展现出来的高性能, 高并发以及惊人的稳定性深深地吸引了我, 也让我认识到了传统三层无状态架构的缺陷. 本文主要关注 Orleans 的思想基础, Actor 模型及其应用.
Orleans 思想基础: Actor 模型
传统三层无状态架构的缺陷
在讨论 Actor 模型之前, 我们可以先讨论一下传统三层架构在当前高并发环境中所面临的尴尬境遇.
三层架构包括表示层, 业务逻辑层或者叫做中间层, 数据访问层(也就是存储层), 其架构图如下所示:
正如我们在实践中所知道的那样, 中间层和数据访问层在伸缩性方面有着很大的限制, 同时存储层常常会成为系统的瓶颈, 这就意味着整套系统也会因为存储层的限制而变得低效. 通常的做法是在中间层与存储层中间加一层缓存逻辑出来, 以提升系统性能, 但是很快就会遇到存储层与缓存层的数据一致性问题, 这无疑为开发人员和运维人员增加了额外的工作量.
试想一下, 如果我们中间层本身就携带着状态或者简单来说中间层与缓存层是合二为一的, 那么我们的系统性能是不是就提升了一个级别, 答案是肯定的. 那么该如何去做呢? 那就是我们需要考虑使用另外一套系统设计架构: Actor 模型.
Actor 模型
Actor 模型允许建立一个有状态的中间层, 其内存级的读写性能和特定于相关领域的业务实体行为, 确保了系统的高性能以及数据的一致性. Actor 模型天然的拥有着面向对象的程序设计功能. 在实践中我们应该把主要精力放到组件之间的消息传递, 而不是对象的属性和内部行为.
Actor 模型作为一种用于处理并发计算的数学模型, 它将 Actor 对象用作并发计算的通用基元, 它也是一种重要的软件设计思想, 它在架构, 设计, 实现以及组件之间的消息传递方面有着非常好的应用, 也更好的发挥了多核计算机的潜力. 通过创建新的 Actor 对象, 可以在计算操作的生命周期中以抽象方式提高系统的分布性.
Actor 作为一种计算实体, 它会对收到的消息做出回应, 并且还会在内部做其他一些事情:
向其他 Actor 对象发送消息
创建一定数量的新 Actor 对象
设置对下一条消息做出的回应方式
下图展示了多种 Actor 模型的交互示例
Actor 模型具有以下特点:
通过异步消息方式进行通信: 使消息就像从一个 Actor 对象传输到了另一个 Actor 对象(通过 MailBox 交互, 这跟 CSP 的通信模式完全不同, 有兴趣的朋友可以自行查阅)
状态机: Actor 模型支持有限状态机
独立性: 多个 Actor 对象之间不会共享状态
无锁的并发处理方式: 由于 Actor 不会共享状态, 且在同一时刻只处理一条消息, 因而无需使用锁策略, 这极大的提高了 Actor 系统的性能
并行性: 当顶级 Actor 将任务分拆后发送给多个下级 Actor 后, 可以使用 Actor 模型的并行处理方式
位置透明: 可以使用抽象引用表示 Actor 对象的地址
Future/Promise 对象: 这是对异步操作的发送与接收方式, 以表示异步操作的完成结果
Orleans 对 Actor 的应用
Actor 平台 (例如 Erlang 和 Akka) 在简化分布式系统编程方面向前迈了一步. 但是, 由于提供的抽象和系统服务的水平相对较低, 它们仍然使开发人员承担着许多分布式系统的复杂性. 主要包括开发用于管理 Actor 的生命周期, 处理分布式簇, 处理 Actor 的失败和恢复, 放置 Actor 以及由此产生的管理分布式资源的应用程序代码. 要为应用程序中的这些问题构建正确的解决方案, 这就开发人员的要求就非常高了, 必须是分布式系统专家级别的.
为了减少这些问题的发生, Orleans 框架引入了虚拟 Actor 的新型抽象, 它解决了许多复杂的分布式系统问题, 例如可靠性和分布式资源管理, 从而使开发人员摆脱了那些麻烦. 同时, Orleans 运行时使应用程序能够获得高性能, 可靠性和可伸缩性.
Orleans 对 Actor 的实现特点:
Orleans Actor 无处不在: 无法明确创建或销毁它. 它的生命周期超越了其任何内存对象的生命周期, 因此也超越了任何特定服务器的生命周期.
Orleans Actor 会自动实例化: 如果没有 Actor 的内存实例, 则发送给 Actor 的消息会促使在可用服务器上创建一个新实例. 作为运行时资源管理的一部分, 将自动回收未使用的 Actor 实例. Actor 永远不会失败: 如果服务器崩溃了, 下一条发送给运行在故障服务器上的 Actor 的消息将会促使 Orleans 自动在另一台服务器上重新实例化该 Actor , 从而无需应用程序来监督和显式重新创建已经挂掉的 Actor.
Actor 实例的位置对于应用程序代码是透明的, 从而大大简化了编程.
Orleans 可以自动创建同一个无状态 Actor 的多个实例, 从而无缝扩展热门 Actor.
虚拟 Actor 的引入, 相当于为开发者提供了一个虚拟的内存空间, 使开发人员可以调用系统中的任何角色, 无论它是否存在于内存中. 虚拟化依赖于从虚拟角色映射到当前运行的物理实例的间接寻址. 运行时通过一个分布式目录支持间接寻址, 该目录将 Actor 标识映射到其当前物理位置. Orleans 通过使用该映射的本地缓存来最小化间接寻址的运行时开销. 这个策略被证明是非常有效的. 在我们的生产服务中, 缓存命中率通常远远超过 90%.
下图展示了微软对 Orleans 的应用
参考链接:
来源: https://www.cnblogs.com/edison0621/p/11567800.html