Orleans稍微复杂的例子—互动

我费力费心的翻译过官方的教程,但是本人英语词汇量不高,可是架不住电子词典啊…只要肯花时间,我这些内容谁都可以做出来.所以这个事例告诉我们一个道理,那就是码农有三好,钱多话少死得早.我也许只有后两好.

       当初阿尔法狗在围棋上战胜人类的时候,人工智能一时大热,不管老小,都大肆谈论一番深度神经网络学习算法等等,我当时也是一时兴起去拿出我崭新的书本,说起来都是泪,大学并没有好好学习,都玩游戏了…不过不管如何,数学系毕业的,底子好点,翻看完必要的知识后,就去看深度神经网络算法,去了解它们的原理,看到最后,我发现,这不就是一种全分类算法吗?顿时觉得高大上的深度学习网络没有那么神秘了.经常看到这样的图片:

 

 

  我们拿过来用,借用微软的话:一个服务本质上是多个可通信actor的集合,用上面的图片好像正合适.

       Grain类是轻量级的,为了更好的设计,现实中往往使用grain类来代表颗粒度很细的东西.比如一个商城,可以用GrainA来代表店铺,用GrainB来代表商品…商铺管理商品,所以GrainB就会和GrainA之间有互动,在系统中,对每个商品进行单独控制,就需要很多的GrainB的实例,这在Orleans中很容易做到,更难得的是,可以对GrainB或者GrainA发生的事件进行记录,实现eventsourcing. Actor的建模方式,使得eventsourcing显得很自然,也很容易处理.

  让多个Grain互动起来才有更多的可能性,一个服务本质上是多个可通信actor的集合.所以在这个例子中,我们创造多个Grain实例,让它们彼此之间有联系.我们使用”现实中的经理于员工的关系”这样一个背景模型来构造这个例子.

步骤

我把它们添加到basic项目里,接口如下图

 

 

还是跟以前一样,定义接口.这里注意这些接口只有方法,尽量避免使用属性.虽然现实当中一个经理同时也是一个员工,但是这里的经理接口并没有继承自员工接口.这样做是基于以下考虑:这两个接口都要被扩展成Grain类,以后对员工和经理的状态值进行持久化存储的时候,”非继承”的两个grain类会带来一些方便.稍微说一下持久化:意思就是对Grain类的各个字段进行持久化存储(存到数据库或者文件都可以),方便下一次Grain激活的时候读取各个字段的值.

好了,不管如何,我就是这么勤快的人,直接写了两个接口,而不是选择继承.现在我勤快的实现这两个Grain类.

如下图:

 

 

大部分基础工作做完了,我们再client调用它们.

 

 

运行之后的截图如下:

 

 

上个例子虽然正确的运行了,但是隐藏一个小坑,真正正确的操作应该如下图

 

 

这是因为Grain的方法都是异步的.如果不添加await,在一些耗时的操作中也许会出现先后顺序的错误.不过对于这个例子,添加不添加与否,并不影响结果.

 

解释一下

  以前说过,Orleans是基于actor模型构建的,但是Orleans把actor模型做到了极致,它是虚拟的actor模型.一个grain的生命周期,是从一个激活开始,到一个反激活结束.它既然是”激活”而不是构造,这就要求grain类不应该有构造函数,即便是没有参数的构造函数.一个grain从来不是    从构建到销毁,而是处于激活或者非激活两个状态. 可以在OnActivateAsync()中控制Graini的激活行为,实现类似于”构造”的过程Orleans保证这个方法会在所有其他方法之前调用.在上一个例子中就展现了如何使用这个方法.

  在多线程的编程中,最讨厌的两个事情是死锁和错误处理.有时候,在开发的时候测试一百次都不会死锁,但是到部署到客户哪里,一次就给你死锁.这一般是因为测试的环境简单化了,没有考虑到客户环境的并发量以及并发的时间点.更因为这两个因素很多时候根本无法考虑.

  消息死锁

  Orleans编程可以做到全程无锁,它同时使得多线程编程逻辑上更容易处理,错误更容易捕捉.但是这不代表不需要设计.为了展现一下,我再此修改员工和经理.这次我们设计一个问候消息如下:

public class GreetingData
{    
   
public Guid From { get; set; }  
    
public string Message { get; set; }  
    
public int Count { get; set; } }

 

  我设想,新员工加入的时候经理给一个问候,同时新员工回答thanks,这样来来回回的消息,就像两个乒乓球机器人一样对发对打.加上一个count,本意是想着来回的次数不要超过3次.不然就进入了死循环了.

修改IEmployee 中的Greeting方法的参数.

Task Greeting(GreetingData data);

修改对接口的实现.

public async Task Greeting(GreetingData data)
{Console.WriteLine("{0} said: {1}", data.From, data.Message); // stop this from repeating endlesslyif (data.Count >= 3) 
        return; // send a message back to the sendervar fromGrain = GrainFactory.GetGrain<IEmployee>(data.From);
   
await fromGrain.Greeting(new GreetingData From = this.GetPrimaryKey(),Message = "Thanks!",Count = data.Count + 1 }); }

 

也更新Manager类,这样它就会发送一个新的消息.

public async Task AddDirectReport(IEmployee employee)
{_reports.Add(employee);  
  
await employee.SetManager(this);  
  
await employee.Greeting(new GreetingData {From = this.GetPrimaryKey(),Message = "Welcome to my team!" }); }

现在经理说”Welcome to my team!" ,员工应该回复一个Thanks.

  如果运行这个程序,就造成了一个死锁,这是因为经理发送消息给员工,并等待回应,员工回答Thanks,并等待经理回应.问题就在于员工的消息永远得不到回答,因为经理正在忙着等待它第一个消息完成呢,在经理那里,员工的回答必须排队等待.这就是一个死锁!!同样的还有死循环.在Actor编程中死循环往往容易处理(在任何编程中都容易处理),因为它容易定位.但是死锁就稍微困难点.

  Orleans提供了日志,可以记录并提示可能的死锁,它一般用WARNING 体现出来,结尾是About to break its promise. 注意在服务器繁忙的时候,网络不好的时候,都有可能出现这个警告.

  为了 应对这样的死锁,Orleans提供了一个特性[Reentrant],它可以标志一个Grain,使得这个类在处理其他消息的时候,稍微富有”弹性”,可以同时接受其他新消息的到达,(只是”到达”这个步骤”弹性”化,”处理消息”这个步骤依然是刚性的”单线程约束”).使用方法很简单.如下:

[Reentrant]
public class Employee : Grain, IEmployee {... }

 

 处理建议

  Orleans系统分为客户端和服务端.对于网站来说,Orleans客户端通常是asp或者其他的http框架,而Orleans服务端通常是数据库操作端等等.在一个中大型的Orleans系统中,多重Actor互相关联,最好是自上而下的设计,遵循好消息流或者数据流的流动方向,让它们的流动可以分支,但是小心处理回流,(需要回流的地方请小心设计,不过这种情况也不会很多,如果很多,请检查自己的数据设计是否合理).

  在用一个Grain去管理多个Grain类的想法中,还有一点要注意的是,尽量不要产生过于繁忙的Grain实例.由于Grain实例是”单线程机制”的,一个实例操作过于繁忙会影响效率.上例中,如果一个经理直接下属有一百万个人.那么这样设计的程序过热点就是这个经理.此时需要分散过热点.一个简单的办法是按照员工主标识hash表分段,每一段分给一个经理…此时组合主标识就会派上用场.

  吃瓜群众应该觉得此处应该有总结:

接口项目就是平时说的”消息协议”.发送消息就是调用接口.在方法内部可以不用锁而随意读写字段.避免死锁和过热的grain实例.

  上例中设计了单独的问候类,在.net世界里,在作为参数传递和使用的时候,.net是传递实例的地址.但是这种机制在并发和多线程的情况下,并不能很好的工作.在Orleans世界里,作为消息的参数(即Grain方法的参数),传递的时候默认都是对类实例进行一个深度拷贝,在跨机器的情况下,这是很有必要的.但是如果消息发送的目的地就是在本地silo里,如果还是需要进行深度拷贝,就显得多余和浪费了.Orleans提供了一个特性[immutable],用它来标明一个类一旦建立就不会再对它进行修改.如果消息目的地是本地silo,使用[immutable]标明的类作为参数时,Orleans就会跳过对此参数的深度拷贝,而是只传递一个引用.使用非常简单.如下:

[Immutable]
public class GreetingData {  
   
public Guid From { get; set; }
   
public string Message { get; set; }  
   
public int Count { get; set; } }


       好了,第二个例子就说完了.有点Orleans实际项目的影子了,但是还是不够…

       似乎应该更进一步,那就是存储,把Grain的状态值保存起来,下一次激活的时候,恢复它的状态值,这样才能符合现实需要.可以尝试在OnActivateAsync里控制读取动作,在OnDeactivateAsync中控制存储动作.不过微软提供了更为通用的存储中间件(StorageProvider),使得这些工作变得容易.所以完全没有必要自己另外实现一个(当然你愿意也行).要想使用这些存储中间件,就必须配置一下.可以使用配置文件,也可以在代码里配置.所以持久化就按下暂且不表,我来说说配置.

相关文章: 

  • .NET的Actor模型:Orleans

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

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

  • Aaron Stannard谈Akka.NET 1.1

  • 使用Akka.net开发第一个分布式应用

  • Orleans入门例子

  • Orleans例子再进一步

原文地址:http://www.cnblogs.com/gaopang/p/7387607.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/324010.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(链表 栈 队列 递归)

文章目录链表反转链表删除点链表中给定值的结点栈和队列双向链表实现栈和队列数组实现队列获取栈的最小值用两个栈实现一个队列用两个队列实现一个栈递归链表 反转链表 &#xff08;反转单链表 反转双向链表&#xff09; public class Code01_ReverseList {public static cl…

一文带你了解Java Agent

转载自 一文带你了解Java Agent Java Agent这个技术&#xff0c;对于大多数同学来说都比较陌生&#xff0c;像个黑盒子。但是多多少少又接触过&#xff0c;实际上&#xff0c;我们平时用的很多工具&#xff0c;都是基于Java Agent实现的&#xff0c;例如常见的热部署JRebel&am…

P3834-【模板】可持久化线段树 1(主席树)

正题 评测记录&#xff1a;https://www.luogu.org/recordnew/lists?uid52918&pidP3834 题意 给定一个长度为n的序列&#xff0c;有m个询问&#xff0c;求一个区间内的第k小的树。 解题思路 我们先思考用线段树快速询问第k小的树 我们可以用权值线段树来处理第k小的树&…

点滴小组KTV点歌系统简介

‍‍20级青鸟四班 点滴小组指导老师&#xff1a;穆老师 班主任&#xff1a;佟老师小组成员&#xff1a;组长&#xff1a;路鑫 副组长&#xff1a;戴洁 王硕组员&#xff1a;马蓥芳 组员&#xff1a;徐圣乾组员&#xff1a;徐圣坤 组员&#xff1a;赵昌杰制作周期&#xff1a;…

迁移.net framework 工程到.net core

在迁移.net core的过程中&#xff0c;第一步就是要把.net framework 工程的目标框架改为.net core2.0&#xff0c;但是官网却没有提供转换工具&#xff0c;需要我们自己动手完成了。.net framework 工程迁移为.net core工程大体上有两种方案&#xff1a; 1.创建一个.net core的…

(归并排序 快排 堆)

文章目录归并排序递归方法实现非递归方法实现求数组的小和求数组的降序对个数快排荷兰国旗问题&#xff08;Partition过程&#xff09;快排1.0快排2.0快排3.0堆大根堆堆排序使用堆排序归并排序 递归方法实现 public class Code01_MergeSort {// 递归方法实现public static vo…

亦云小组KTV点歌系统简介

20级青鸟四班 亦云小组指导老师&#xff1a;穆老师 班主任&#xff1a;佟老师小组成员&#xff1a;组长&#xff1a;靳天宇组员&#xff1a;王晓丹 谢佳泽 王睿志 蒲璐颖 张铨政目录&#xff1a;1.首页 2.项目前台 3..项目后台总结&#xff1a;本次KTV项目总结。总体来说&…

学习手记(2018/7/14~2018/7/18)——快乐纪中

2018/7/14&#xff1a;普通的纪中一天 儿子兄弟表示法 将一颗多叉树转换为二叉树的方法&#xff0c;左子节点连原树的第一个儿子&#xff0c;右子节点连原树的右边的兄弟 适用范围&#xff1a;树形dp 数位dp常见方法 状态压缩 分类讨论记忆法&#xff08;记忆化搜索&#x…

Entity Framework Core 2.0 特性介绍和使用指南

前言 这是.Net Core 2.0生态生态介绍的最后一篇&#xff0c;EF一直是我喜欢的一个ORM框架&#xff0c;随着版本升级EF也发展到EF6.x&#xff0c;Entity Framework Core是一个支持跨平台的全新版本&#xff0c;可以用三个词来概况EF Core的特点&#xff1a;轻量级、可扩展、跨平…

图解elasticsearch原理转载自

转载自 图解elasticsearch原理 版本 elasticsearch版本: elasticsearch-2.x 内容 图解ElasticSearch 云上的集群 集群里的盒子 云里面的每个白色正方形的盒子代表一个节点——Node。 节点之间 在一个或者多个节点直接&#xff0c;多个绿色小方块组合在一起形成一个Elas…

零云九歌小组KTV点歌系统简介

指导老师&#xff1a;穆老师 班主任&#xff1a;佟老师小组成员&#xff1a;组长&#xff1a;张炜林 副组长&#xff1a;李钰组员&#xff1a;郑宪佳 宋翔 李兆勋 杜庆霖零云九歌目录&#xff1a;1.首页 2.项目前台 3..项目后台总结&#xff1a;本次KTV项目总结。总体来说&am…

Orleans简单配置

话说曾几何时,我第一次看到xml文件,心中闪过一念想:"这<>是什么鬼?"…用ini或者json多简单易懂,现在发觉作为配置文件,json有赶超xml的趋势.不过xml用多了,也觉得顺眼多了.不觉得<>难看了,反而它能折叠让我觉得组织起来也更方便了.这说明一个道理:不是你…

say小组KTV点歌系统简介

指导老师&#xff1a;穆老师 班主任&#xff1a;佟老师小组成员&#xff1a;组长&#xff1a;焦文宇 组员&#xff1a;窦倩 王晓凤 巩固 石虹蔓 田锋目录&#xff1a;1.首页 2.项目前台 3..项目后台总结&#xff1a;从5月25号开始的到6月10号结束&#xff0c;这期间我们遇…

Java虚拟机必学之四大知识要点,附学习资料

转载自 Java虚拟机必学之四大知识要点&#xff0c;附学习资料 作为一位 Java 程序员&#xff0c;在尽情享受 Java 虚拟机带来好处的同时&#xff0c;我们还应该去了解和思考“这些技术特性是如何实现的”&#xff0c;去了解最底层的原理。只有熟悉 JVM&#xff0c;你才能在遇…

程序配置amp;amp;ConfigurationManager

配置组件是.net framework中非常常用的功能。在创建.net framework 工程时&#xff0c;系统不仅会自动生成app.config文件&#xff0c;而且还提供了非常强大的访问类库。但是这些好东西&#xff0c;在.net core 2.0中已经不复存在&#xff0c;至少说没有.net framework 中那么完…

既然参与,那就做好,我相信我们是最棒的!!!

‍‍大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。今天是3班的KTV项目答辩&#xff0c;也是20级的最后一个班级&#xff0c;连续6天的KTV项目答辩终于告一段落。回顾各班所做的项目&#xff0c;通过我自己参与点评的以及从班内参观同学…

又发生频繁FGC,这次是谁的锅

转载自 又发生频繁FGC&#xff0c;这次是谁的锅 这是笨神JVMPocket群里一位名为"云何*住"的同学提出来的问题&#xff0c;问题现象是CPU飙高并且频繁FullGC。 重现问题 这位同学的业务代码比较复杂&#xff0c;为了简化业务场景&#xff0c;笔者将其代码压缩成如…

三个剩两个,两个剩一个,最后一个都没剩下。

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。今天文章的标题本来是&#xff1a;“从未见过如此不要脸耍无赖的人&#xff01;&#xff01;&#xff01;”&#xff0c;后来想了想&#xff0c;毕竟公众号里面还有那么多不同身份的粉丝&a…

算法面试,如何在100 亿URL中判断某个URL是否存在

转载自 算法面试&#xff0c;如何在100 亿URL中判断某个URL是否存在 如果面试官问你&#xff0c;一个网站有 100 亿 url 存在一个黑名单中&#xff0c;每条 url 平均 64 字节。问这个黑名单要怎么存&#xff1f;若此时随便输入一个 url&#xff0c;如何判断该 url 是否在这个…

.NET Core 2.0迁移技巧之web.config配置文件

大家都知道.NET Core现在不再支持原来的web.config配置文件了&#xff0c;取而代之的是json或xml配置文件。官方推荐的项目配置方式是使用appsettings.json配置文件&#xff0c;这对现有一些重度使用web.cofig配置的项目迁移可能是不可接受的。 但是好消息是&#xff0c;我们是…