前言

简单说明一下,为什么有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. 多线程系列(十一) -浅析并发读写锁StampedLock

    一.摘要 在上一篇文章中,我们讲到了使用ReadWriteLock可以解决多线程同时读,但只有一个线程能写的问题. 如果继续深入的分析ReadWriteLock,从锁的角度分析,会发现它有一个潜在的问 ...

  2. 十一: 数据库缓冲池(buffer pool)

    数据库缓冲池(buffer pool) InnoDB 存储引擎是以页为单位来管理存储空间的,我们进行的增删改查操作其实本质上都是在访问页 面(包括读页面.写页面.创建新页面等操作).而磁盘 I/O 需 ...

  3. kafka的数据同步原理ISR、ACK、LEO、HW

    1.数据可靠性保证,数据同步 为保证 producer 发送的数据,能可靠的发送到指定的 topic,topic 的每个 partition 收到 producer 发送的数据后,都需要向 produ ...

  4. 阿里巴巴/1688 api接口 获取商品详情 数据采集

    iDataRiver平台 https://www.idatariver.com/zh-cn/ 提供开箱即用的阿里巴巴1688电商数据采集API,供用户按需调用. 接口使用详情请参考阿里巴巴1688接口 ...

  5. Jetpack Compose(3) —— 状态管理

    上一篇文章拿 TextField 组件举例时,提到了 State,即状态.本篇文章,即讲解 State 的相关改概念. 一.什么是状态 与其它声明式 UI 框架一样,Compose 的职责非常单纯,仅 ...

  6. MYSQL 是如何保证binlog 和redo log同时提交的?

    MYSQL 一个事务在提交的时候能够保证binlog和redo log是同时提交的,并且能在宕机恢复后保持binlog 和redo log的一致性. 先来看看什么是redo log 和binlog,以 ...

  7. 已安装docker-compose,安装harbor时还是提示docker-compose未安装或者Permission denied的解决方案

    安装Harbor时,下载安装了docker-compose并赋予权限 sudo curl -L "https://github.com/docker/compose/releases/dow ...

  8. chm之已取消到该网页的导航解决办法

    1. 右键单击该 CHM 文件,然后单击"属性". 2. 单击"取消阻止"或者"解除锁定". 3. 双击此 .chm 文件以打开此文件.

  9. 结构体、共用体与C++基础

    结构体.共用体与C++基础 1.结构体 结构体是C编程中一种用户自定义的数据类型,类似于Java的JavaBean //Student 相当于类名 //student和a 可以不定义,表示结构变量,也 ...

  10. [vscode]使用cmake时将命令行参数传递给调试目标

    一.简介 本文介绍了在vscode中使用cmake工具时,如何传递参数给编译目标的方法. 前提:使用vscode+cmake编译C/C++程序. 二.方法 在.vscode/目录下新建settings ...