前言

简单说明一下,为什么有orleans 这个框架。

正文

orleans 这个框架的理论基础是 actor, 在1973年提出,当初是为了大量处理高并发计算机的并行模型,其核心思想是将系统中独立的计算过程抽象为actor。

高并发场景有什么问题呢,那就是同时修改一个对象的时候,那么会出现线程不安全的情况。

actor 模型是怎么做的呢? actor 模型做法是同一时刻仅响应一个外部的请求。

当actor 模型同时受到多个外部的请求的时候,通过一定的规则(通常是先入先出)对外部请求进行排序一次执行。

有人觉得这样可能会很慢,那么如果有很多个actor模型呢? 那么其实这个压力就被平坦了。

如果每个都是actor模型的话,那么就有一个问题,actor之间是否能通信呢? 怎么通信?

actor 之间也是可以通信的,对于这一点来说,跟外部访问actor 没有什么区别。

那么orleans 就是为了实现这种思想的。

在orleans 中,actor模型的基础响应单位为grain。

每一个grain 由服务(service),状态(State) 及标识(identtiy)组成。

grain 示例:

那么grain 是怎么作为标识的呢?

当程序使用guid 进行grain 寻址的时候,n0 和 n1 分布由guid 字节数组的0-7 和 8-15 位组成。

采用长整数寻址的时候,n1 为地址位,n0 为0 位。

这个typecodeData 是什么呢? 是最低为4个字节的标识及其所标识对象的类别:

类别如下:

IGrainWithGuidKey:带有 Guid 键的 grain 标记接口。
IGrainWithIntegerKey:带有 Int64 键的 grain 标记接口。
IGrainWithStringKey:带有 string 键的 grain 标记接口。
IGrainWithGuidCompoundKey:带有组合键的 grain 标记接口。
IGrainWithIntegerCompoundKey:带有组合键的 grain 标记接口。

那个keyExt 就是我们可以额外扩展的字段。

var n0 = BitConverter.ToUInt64(new Guid(guididentity).ToByteArray(), 0);

var n1 = BitConverter.ToUInt64(new Guid(guididentity).ToByteArray(), 8);

var identitiy = string.Format("GrainReference={0:x16}{1:x16}{2}+{3}", n0, n1, "06ffffffe23dcf33", ln)

ln 是 keyext。

06ffffffe23dcf33 这个固定的是什么呢? 06 表示标识符。 后面的ffffffe23dcf33 表示了服务的标识。

grain 通过接口调用来定义接口的标识类型:

调用方式:

那么grain的唤醒和休眠是什么样的呢?

因为系统的资源有限,不可能在内存中加载全部的grain。

在orleans 应用程序的内部,grain 示例对象实际会自动在休眠状态(persisted) 和 活跃状态 (volatile) 间进行切换,

在空闲状态下释放对系统资源的占用。

在休眠状态的grain实例对象不占用任何运行时资源(cpu和内存),其内部状态由orleans 运行时通过存储服务进行存储。

当orleans 应用程序首次启动时,其内部所以的grain实例都默认处于休眠态。

Grain对象的休眠过程仅由Orleans运行时触发:当Orleans运行时监测到活跃态Grain实例的闲置时间超过阈值时,Orleans运行时将自动保存其当前状态并对其所占用的运行时资源进行回收。

这里就有一个问题,有一些比较热门的grain,如果监测到非活跃就回收了,那么可以多次激活的情况。

那么可以这样:

Task<string> IHello.SayHello(string greeting)
{
TimeSpan timeSpan = TimeSpan.FromSeconds(500);
DelayDeactivation(timeSpan); logger.LogInformation($"SayHello message received: greeting = '{greeting}'");
return Task.FromResult($"You said: '{greeting}', I say: Hello!");
}

使用DelayDeactivation 延迟一下回收时间。

如果呢,你想马上回收,怎么处理呢?

public async Task<string> NoThing()
{
DeactivateOnIdle(); return string.Empty;
}

这样可以让其尽快回收,下一次gc 就会回收掉。

这里值得注意的是:DelayDeactivation(timeSpan); 这个timespan 可以设置为负数,如果为负数表示取消。

在orleans 中,状态也是有几种类型的。

比如继承: IpersistentStat 和 grain:

grain 基类中可以重载:

IPersistentState类则具有以下API可供调用及重载。

这里非常值得注意一点: grain 的初始化过程是先于onactivateasync 函数调用的,因此storageprovider 中任何读取错误都将直接导致grain 实例激活失败。

在此值和orleans 运行时并不会继续调用onactivateasync ,会由运行时抛出Orleans.BadProviderConfigException异常

对于状态写入场景而言,StorageProvider中的任何错误也都将由WriteStateAsync方法抛出,开发人员在业务逻辑中需要对依赖WriteStateAsync方法的逻辑分支进行单独的异常处理。

IGrainStorage接口的所有API参数列表中都接受一个类型为IGrainState的输入参数,而IGrainState接口中定义了一个字符串类型的属性ETag,该字段在IPersistentState<T>接口中是可见的,实际上ETag是存储服务在并发读写场景下用以区分状态版本的“数据版本标识位”字段:当需要对外部存储状态进行刷新时,可以将状态的ETag指定为上一次读取该状态时获得的ETag值,若该ETag与当前实际存储的ETag值相同,则证明在上一次状态读取到当前时刻外部存储的状态值没有发生变化,可以进行直接状态的刷新;若ETag不相符,则表明在此段时间内有其他逻辑对外部存储的状态进行了更新,此次状态更新操作面临数据不一致的情况(类似于CPU并发场景下的CAS操作);若业务场景中需要跳过外部状态的版本校验逻辑,则可以在调用外部状态写入API时将状态的ETag值保留为null。而在实现IGrainStorage接口时,任何在读写API方法中检测到读写ETag约束不一致时都需要抛出一个InconsistentStateException异常以终止该API调用并将异常信息传递给上层调用者。

下一节实操一些例子。

orleans —————— 为什么有这个框架 [ 一]的更多相关文章

  1. Orleans 框架3.0 官方文档中文版系列一 —— 概述

    关于这个翻译文档的一些说明: 之前逛博客园的时候,看见有个园友在自己的博客上介绍Orleans. 觉得Orleans 是个好东西. 当时心想:如果后面有业务需要的时候可以用用Orleans框架. 当真 ...

  2. .NET 跨平台RPC框架DotNettyRPC

    DotNettyRPC 1.简介 DotNettyRPC是一个基于DotNetty的跨平台RPC框架,支持.NET45以及.NET Standard2.0 2.产生背景 传统.NET开发中遇到远程调用 ...

  3. Orleans核心功能

    一.Grain持久性 二.定时器和提醒 三.依赖注入 四.观察者 五.无状态工作者Grains 六.流 一.Grain持久化 1,Grain持久化目标 ①允许不同类型的存储提供者使用不同类型的存储提供 ...

  4. .NET 跨平台RPC框架DotNettyRPC Web后台快速开发框架(.NET Core) EasyWcf------无需配置,无需引用,动态绑定,轻松使用 C# .NET 0配置使用Wcf(半成品) C# .NET Socket 简单实用框架 C# .NET 0命令行安装Windows服务程序

    .NET 跨平台RPC框架DotNettyRPC   DotNettyRPC 1.简介 DotNettyRPC是一个基于DotNetty的跨平台RPC框架,支持.NET45以及.NET Standar ...

  5. Orleans 知多少 | 3. Hello Orleans

    1. 引言 是的,Orleans v3.0.0 已经发布了,并已经完全支持 .NET Core 3.0. 所以,Orleans 系列是时候继续了,抱歉,让大家久等了. 万丈高楼平地起,这一节我们就先来 ...

  6. Orleans 知多少 | Orleans 中文文档上线

    Orleans 简介 Orleans是一个跨平台框架,用于构建健壮,可扩展的分布式应用程序 Orleans建立在.NET开发人员生产力的基础上,并将其带入了分布式应用程序的世界,例如云服务. Orle ...

  7. Open Source

    资源来源于http://www.cnblogs.com/Leo_wl/category/246424.html RabbitMQ 安装与使用 摘要: RabbitMQ 安装与使用 前言 吃多了拉就是队 ...

  8. 微软分布式云计算框架Orleans(1):Hello World

    自从写了RabbitHub框架系列后的一段时间内一直在思索更加轻量简便,分布式高并发的框架(RabbitHub学习成本较高),无意间在网上级联看到了很多新框架:从helios到Akka.NET在到Or ...

  9. 微软分布式云计算框架Orleans(2):容灾与集群(1)

    在上一篇:微软分布式云计算框架Orleans(1):Hello World,我们大概了解了Orleans如何运用,当然上一篇的例子可以说是简单且无效的,因为用了Orleans不可能只写一个Hello ...

  10. 微软研究院的分布式云计算框架orleans

    orleans   Orleans 客户端请求的消息流转以及消息在Silo中再路由机制 Witte 2015-04-29 21:58 阅读:196 评论:0     一种基于Orleans的分布式Id ...

随机推荐

  1. 9、mysql的并发参数调整

    从实现上来说,MySQL Server 是多线程结构,包括后台线程和客户服务线程.多线程可以有效利用服务器资源,提高数据库的并发性能.在Mysql中,控制并发连接和线程的主要参数包括 max_conn ...

  2. xxl-job的基本使用

    xxl-job的基本使用 xxl-job是分布式的调度平台调度执行器执行任务,使用的是DB锁(for update)来保证集群分布式调用的一致性,学习简单,操作容易,成本不高. 准备阶段 服务端配置 ...

  3. centos 目录磁盘使用情况

    最简单的查看方法可以使用ls -ll.ls-lh命令进行查看,当使用ls -ll,会显示成字节大小,而ls- lh会以KB.MB等为单位进行显示,这样比较直观一些.   通过命令du -h –max- ...

  4. npm-links - 查看项目依赖包 - vscode 插件

    npm-links 依赖包相关快捷链接

  5. WPF之事件

    目录 WPF的树形结构 事件 路由事件 使用WPF内置路由事件 自定义路由事件 ButtonBase类的Click路由事件 创建一个路由事件 RoutedEventArgs的Source与Origin ...

  6. python基础笔记((1)

    逻辑与或非用的是and or not. 除法即使整除结果也是浮点数 地板除//结果一定是整数. 内存中的字符串是Unicode编码,str.encode('utf-8 or ascii')将class ...

  7. Handler源码解析

    Handler源码解析 一.基本原理回顾 在android开发中,经常会在子线程中进行一些操作,当操作完毕后会通过handler发送一些数据给主线程,通知主线程做相应的操作. 探索其背后的原理:子线程 ...

  8. 关于全景(360)图片拼接的方法(Opencv3.0 Stitcher)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  9. Ubuntu 16.04 LAMP(PHP7.0) 环境搭建并测试

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  10. 自定义Key类型的字典无法序列化的N种解决方案

    当我们使用System.Text.Json.JsonSerializer对一个字典对象进行序列化的时候,默认情况下字典的Key不能是一个自定义的类型,本文介绍几种解决方案. 一.问题重现 二.自定义J ...