Orleans解决并发之痛(二):Grain状态

Grains是Orleans应用程序的构建块,它们是彼此孤立的原子单位,分布的,持久的, 一个典型的Grain是有状态和行为的一个单实例,每个Grain实例的在单线程内执行,Grain之间共享数据通过消息传递,Grains是由Silo自动化管理。

Grain之间传递消息过程中也可能出现死锁的情况,如:Grain A发送消息给Grain B,并等待它的完成,此时Grain B发送一个消息给Grain A,也等待其完成,这时候出现相互等待而造成死锁。Orleans对Grain之间产生的死锁问题解决也是非常简单的,只需要在Grain上加[Reentrant]属性,具体可查看官方Concurrency。

Grain状态有好几种存储方式,比如:AzureTableStorage、AzureBlobStorage、SQLStorage、MemoryStorage  等,我们还可以自定义存储。MemoryStorage在测试项目使用没问题,但实际生产环境要使用其他持久存储的方式,因为一旦一个Silo被关闭,内存存储的状态将会消失。

在分布式下,State的使用可以减少很多对数据库层面的压力。当然也不是所有的Grain都推荐使用State,还是看实际业务需求。我们可以想象一个场景,一个商品的库存如果保存在State中,所有请求都共享这个State,在判断是否有剩余商品的时候是不是就不需要每次都去查询数据库了?

定义接口

public interface IPersonGrain : IGrainWithStringKey
{Task SayHelloAsync();
}

实现接口

public class PersonGrain : Grain, IPersonGrain
{public Task SayHelloAsync(){string primaryKey = this.GetPrimaryKeyString();Console.WriteLine($"{primaryKey} said hello!");return Task.CompletedTask;}
}

为了实现状态存储,我们需要创建一个class:

public class PersonGrainState
{public bool SaidHello { get; set; }
}

修改代码,实现的PersonGrain不应该再继承Grain,而是Grain<T>

[StorageProvider(ProviderName = "OrleansStorage")]
public class PersonGrain : Grain<PersonGrainState>, IPersonGrain
{public async Task SayHelloAsync(){string primaryKey = this.GetPrimaryKeyString();bool saidHelloBefore = this.State.SaidHello;string saidHelloBeforeStr = saidHelloBefore ? " already" : null;Console.WriteLine($"{primaryKey}{saidHelloBeforeStr} said hello!");this.State.SaidHello = true;await this.WriteStateAsync();}
}

第一次调用这个方法的时候this.State.SaidHello为false,输出'xxx said hello!'。然后我们通过WriteStateAsync修改SaidHello为true,当第二次被调用的时候,从State里取出的SaidHello已经变成了true,则输出'xxx already said hello!'

Orleans 提供了非常简单的API来处理持久化装状态,看方法名就知道什么啥意思了,WriteStateAsync()、ReadStateAsync() 、 ClearStateAsync()。

同时在PersonGrain加了一个StorageProvider属性,参数ProviderName赋值为OrleansStorage,这里需要对Silo的配置文件(OrleansConfiguration.xml)做调整,添加StorageProviders配置,Type表示存储方式,Name表示名称,程序内指定的ProviderName需要和配置中这个名称保持一致。

注意:
当Name为Default时,如果某个Grain使用Default来存储,可以不需要加StorageProvider属性。StorageProviders下可以有多个Provider,每个Provider的Type可以不一样,每个Grain指定的存储方式也可以不一样,ProviderName指定是谁就用谁存储。

<?xml version="1.0" encoding="utf-8" ?>
<OrleansConfiguration xmlns="urn:orleans"><Globals><SeedNode Address="localhost" Port="11111" /><StorageProviders><Provider Type="Orleans.Storage.MemoryStorage"Name="OrleansStorage" /></StorageProviders></Globals><Defaults><Networking Address="localhost" Port="11111" /><ProxyingGateway Address="localhost" Port="30000" /></Defaults>
</OrleansConfiguration>

为了验证Grain之间是独立的,在Client加入以下代码:

 var joe = GrainClient.GrainFactory.GetGrain<IPersonGrain>("Joe");
joe.SayHelloAsync();
joe.SayHelloAsync();var sam = GrainClient.GrainFactory.GetGrain<IPersonGrain>("Sam");
sam.SayHelloAsync();
sam.SayHelloAsync();

测试结果:


Test Result

SQL Server 持久存储State

上面提到State以内存存储的方式并不适合生产环境,那下面我们使用SQL Server来实现。

在Silo程序集中安装依赖包:
Install-Package Microsoft.Orleans.OrleansSqlUtils
Install-Package System.Data.SqlClient
创建数据库和表:
  1. 在SQL Server中创建一个数据库,命名如:OrleansStorage(随意);

  2. 在解决方案下找到目录:packages\Microsoft.Orleans.OrleansSqlUtils.1.5.0\lib\net461\SQLServer,目录下有一个.sql文件,在OrleansStorage数据库下执行这个sql脚本即可;

修改OrleansConfiguration.xml的StorageProviders节点为:
<StorageProviders><Provider Type="Orleans.Storage.AdoNetStorageProvider"Name="OrleansStorage"AdoInvariant="System.Data.SqlClient"DataConnectionString="Server=.;Database=OrleansStorage;
User ID=sa;Password=123456;"/> </StorageProviders>
重新启动Silo和Client:

执行完成后查看数据库中表Storage的内容,数据的值是二进制是方式存储。



storage

之后不管重启多少次,输出的结果都是 "xxx already saild hello!" 。

参考链接:

  • Actor模型

  • Orleans

  • 案例Demo-OrleansState

相关文章: 

  • .NET的Actor模型:Orleans

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

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

  • Aaron Stannard谈Akka.NET 1.1

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

  • Orleans入门例子

  • Orleans例子再进一步

  • Orleans稍微复杂的例子—互动

  • Orleans简单配置

  • Orleans配置---持久化

  • Orleans—一些概念

  • Orleans的集群构建

  • Oleans集群之Consul再解释

  • Orleans解决并发之痛(一):单线程

原文地址:http://www.jianshu.com/p/ccd9cffa77bf


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

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

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

相关文章

汇编语言(三十四)之输出中文

输出中文 程序运行&#xff1a; 代码&#xff1a; daones segmentfull_name db 0,1,2,3,4,5 full_name_length dw $-full_name start_char db 0 change_char_count dw 6color db 1 x dw 40 y …

vue使用element ui实现下拉列表分页的功能!!!

“大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。”前几天做了个功能&#xff0c;需求是使用利用element ui如何给下拉列表分页&#xff0c;经过网上查找&#xff0c;自己摸索&#xff0c;已经完成&#xff0c;今天来记录一下吧。实现的…

ASP.NET Core 运行原理解剖[2]:Hosting补充之配置介绍

在上一章ASP.NET Core 运行原理解剖[1]:Hosting中&#xff0c;我们介绍了 ASP.NET Core 的启动过程&#xff0c;主要是对 WebHost 源码的探索。而本文则是对上文的一个补充&#xff0c;更加偏向于实战&#xff0c;详细的介绍一下我们在实际开发中需要对 Hosting 做一些配置时经…

汇编语言(三十五)之输入字符串以$结束然后输出字母个数

输入字符串以$结束然后输出字母个数 程序运行&#xff1a; 代码&#xff1a; datas segment buff db 100h dup(?)letter_count dw 0nextline db 0dh,0ah,$datas ends codes segment assume cs:codes,ds:datas main proc far push dsmov ax,0push ax mov ax,datasmov ds,ax…

vue中如何使用vi-for限制遍历的条数?只查询前三条、查询4-6条怎么实现?

“大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。”前言今天整理个简单的功能&#xff0c;vue中的v-for如何限制遍历输出的数据&#xff0c;比如我想在一个存放10条数据的集合中只输出3条怎么写&#xff1f;只想从第四条开始输出到第10条…

编译原理(一)之词法分析

词法分析 (1)参考附录1设计一个简单语言的词法分析程序&#xff0c;要求能够处理注释、换行回车、部分复合运算符&#xff08;如>&#xff09;。 (2)设计并实现含多条简单赋值语句的语法分析程序&#xff0c;要求有一定的出错提示与错误恢复功能。 (参考附录2) 附录1:…

粗略使用.NetCore2.0自带授权登陆Authorize

上篇Linux.NetCoreNginx搭建集群 有朋友提及到如果nginx做集群后应该还会有下一篇文章主讲session控制&#xff0c;一般来说就是登陆&#xff1b;本篇分享的内容不是关于分布式session内容&#xff0c;而是netcore自带的授权Authorize&#xff0c;Authorize粗略的用法&#xff…

vue中如何在地图中标点…

“大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。”前言昨天分享了下vue中v-for的一些特殊用法&#xff0c;料想标题给写成了vi-for…太粗心了。文章连接在这里&#xff1a;vue中如何使用v-for限制遍历的条数&#xff1f;只查询前三条、…

被黑客盯上了…数据都给打包带走了…

“大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。”前言在创建数据库的时候&#xff0c;突然之间&#xff0c;发现创建的表通过select * from 表名 查询不到了&#xff0c;于是就开始检查是不是sql语句写错了&#xff0c;检查半天&#…

编译原理(二)之语法分析

采用实验1的简单语言&#xff0c;设计并实现含多条简单赋值语句的语法分析程序&#xff0c;要求采用算符优先的分析算法。 注意与实验1、2的衔接。 using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using Syste…

ASP.Net Core Razor 页面路由

在服务器端 Web 应用程序框架中&#xff0c;其中非常重要的设计是开发人员如何将URL与服务器上的资源进行匹配&#xff0c;以便正确的处理请求。最简单的方法是将 URL 映射到磁盘上的物理文件&#xff0c;在 Razor 页面框架中&#xff0c;ASP.NET团队就是这样实现的。 关于 Ra…

vue实现下拉列表远程搜索示例(根据关键词模糊搜索)

“大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂”前言昨天的链接没有放上去……大家访问新站的时候&#xff0c;可以在浏览器地址栏中输入&#xff1a;www.穆雄雄.com或者www.muxiongxiong.cn都可以。今天分享的效果如下&#xff1a;ima…

编译原理(三)之语义分析

采用实验1的简单语言&#xff0c;设计并实现含多条简单赋值语句的语法语义分析程序&#xff0c;要求采用递归下降翻译法。 注意与实验1、2的衔接。 using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.T…

活动: 北京Xamarin分享会第6期(2017年9月9日)

每月第二个周六&#xff0c;北京丹棱街5号微软大厦&#xff0c;有什么活动&#xff1f;对, BXUG线下分享活动又来啦! 本次分享嘉宾阵容庞大&#xff0c;在金秋凉爽的季节&#xff0c;期待与大家面对面的交流。内容预告&#xff1a; 案例分享&#xff1a;某大型国企IT项目如何采…

捡到东西说给钱才给东西?算不算敲诈勒索……

“大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂”前言前两天&#xff0c;将一个那天急要但是后来就不重要的东西&#xff0c;放在车筐里面&#xff0c;结果到目的地一看&#xff0c;没了……椅子还没坐热&#xff0c;有人打来电话了“你…

编译原理(四)之解析语言翻译成三地址代码

选择部分C语言的语法成分&#xff0c;设计其词法语法语义分析程序。 设计并实现一个一遍扫描的词法语法语义分析程序&#xff0c;将部分C语言的语法成分翻译成三地址代码&#xff0c;要求有一定的出错提示和错误恢复功能。 例如简单赋值语句&#xff1a; area3.14*a*a; s 2*…

[北京微软技术直通车]前端 Visual Studio Code 开发 Angular 与亿级 SQL Servern

微软技术直通车第一期将于2017年9月9日与大家见面&#xff0c;本次邀请华北区微软技术专家和大家一起交流前端工具与技术&#xff0c; Visual Studio Code&#xff0c;TypeScript 与 Anuglar 项目开发和亿级数据库运维的最佳实践&#xff0c;分享相关技术的发展前景和从业经验&…

vue中如何实现全全全屏和退出全屏?

“大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂”最近总有人给我说ta有社恐&#xff0c;明明是有社牛好不好……前言在做大屏界面的时候&#xff0c;客户有个要求&#xff0c;一进去登录成功之后&#xff0c;要有全屏的功能&#xff0c;…

【深圳】掌通宝科技有限公司技术总监(兼架构师),约吗

技术总监&#xff08;兼架构师&#xff09; 岗位职责&#xff1a; 1、主持研发中心日常管理工作&#xff0c;负责公司O2O平台,SaaS平台管理&#xff1b; 2、负责公司.net后台&#xff0c;Android客户端、IOS客户端、WEB平台等架构设计&#xff1b; 4、解决开发中的技术问题…

树层级处理上万条数据优化!

“大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。”前言项目中&#xff0c;部门数超万&#xff0c;导致页面加载价卡顿怎么办&#xff1f;使用若依自带解析树的方法在本地运行没有任何问题&#xff0c;但是一发布到服务器上就显示加载超…