Orleans框架------基于Actor模型生成分布式Id
一、Actor简介
actor模型是一种并行计算的数学模型。 响应于收到的消息,演员可以:做出决定,创建更多Actor,发送更多消息,并确定如何响应接收到的下一条消息。 演员可以修改自己的状态,但只能通过消息相互影响(避免需要任何锁)。
actor是一个计算实体,当其收到消息时,可以并发执行如下操作:
1. 发送有限数量的消息给其他actor
2. 创建有限数量的新actor
3. 指定收到下一消息时的行为
在Orleans中使用的是虚拟Actor方式,详细:http://dotnet.github.io/orleans/Documentation/Introduction.html
详细参见: https://en.wikipedia.org/wiki/Actor_model
二、Orleans框架
Orleans是一个框架,可以直接构建分布式大规模计算应用程序,而无需学习和应用复杂的并发或其他缩放模式。 它是由Microsoft Research创建的,旨在用于云端。
Orleans已被Microsoft Azure广泛应用于微软的几个产品集团,其中最着名的是343个行业,作为所有Halo 4和Halo 5云服务的平台,以及越来越多的其他公司。
特性:
1、默认可扩展
奥尔良处理构建分布式系统的复杂性,使您的应用程序能够扩展到数百台服务器。
2、低延迟
奥尔良允许您保持内存所需的状态,因此您的应用程序可以快速响应传入的请求。
3、简化并发
Orleans允许您编写简单的单线程C#代码,通过actor之间的异步消息传递来处理并发。
三、生成流水号项目实战
1、场景
现在系统基于分布式服务开发,数据在客户端处理后提交到服务端入库,但是由于多个系统间的并发而流水号全部在一张表,每次都是先select在update 高并发容易直接死锁。
如图:
2、基于Orleans的actor
将每条数据改造成一个Actor,由个Actor之间的状态来保证流水号的递增,这样即使单个流水号访问量大只要扩展Orleans的soli即可。
四、关键代码:
1、利用初始化SerialNumberStorgeProvider初始化管理Grain的状态
public class SerialNumberStorgeProvider : IStorageProvider
{
public Logger Log { get; set; } public string Name { get; set; } public Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
{
return TaskDone.Done;
} public Task Close()
{
return TaskDone.Done;
} public Task Init(string name, IProviderRuntime providerRuntime, IProviderConfiguration config)
{
this.Name = nameof(SerialNumberStorgeProvider);
this.Log = providerRuntime.GetLogger(this.Name); return TaskDone.Done;
} public Task ReadStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
{
Console.WriteLine("获取种子信息");
var SerialNumber = grainReference.GetPrimaryKeyString();
using (var db = new DBContext())
{
var query = db.SerialNumbers.AsNoTracking().FirstOrDefault(o => o.Name.Equals(SerialNumber));
if (query != null)
grainState.State = query;
else
{
db.SerialNumbers.Add(new SerialNumberInfo
{
Name = grainReference.GetPrimaryKeyString(),
Number =
});
db.SaveChanges();
grainState.State = new SerialNumberInfo
{
Name = grainReference.GetPrimaryKeyString(),
Number =
};
}
}
return TaskDone.Done;
} public async Task WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
{
var model = grainState.State as SerialNumberInfo;
using (var db = new DBContext())
{
var query = db.SerialNumbers.FirstOrDefault(o => o.Name.Equals(model.Name));
query.Number = model.Number;
await db.SaveChangesAsync();
}
}
}
2、Grain获取流水号的实现
[StorageProvider(ProviderName = "SerialNumberStorgeProvider")]
public class SerialNumberGrain : Grain<SerialNumberInfo>, ISerialNumberGrain
{
/// <summary>
/// 获取多个流水号
/// </summary>
/// <param name="number"></param>
/// <returns></returns>
public Task<List<long>> GetMutilSerialNumber(int number)
{
if (number == ) { number = ; } List<long> list = new List<long>();
for (int i = ; i <= number; i++)
{
this.State.Number += ;
list.Add(this.State.Number);
}
this.WriteStateAsync();
return Task.FromResult(list);
} /// <summary>
/// 获取单个流水号
/// </summary>
/// <returns></returns>
public Task<long> GetSerialNumber()
{
this.WriteStateAsync();
return Task.FromResult(this.State.Number);
}
}
最后,最多说一句,在测试的时候发现如果不适用如下这种方式,并发时会发生Task调度异常

源码地址:https://github.com/liyang-live/MakeSerialNumber
参考资料:http://dotnet.github.io/orleans/index.html
http://www.cnblogs.com/joab/p/5657851.html
https://github.com/dotnet/orleans
Orleans框架------基于Actor模型生成分布式Id的更多相关文章
- 基于雪花算法生成分布式ID(Java版)
SnowFlake算法原理介绍 在分布式系统中会将一个业务的系统部署到多台服务器上,用户随机访问其中一台,而之所以引入分布式系统就是为了让整个系统能够承载更大的访问量.诸如订单号这些我们需要它是全局唯 ...
- 基于Actor模型的CQRS、ES解决方案分享
开场白 大家晚上好,我是郑承良,跟大家分享的话题是<基于Actor模型的CQRS/ES解决方案分享>,最近一段时间我一直是这个话题的学习者.追随者,这个话题目前生产环境落地的资料少一些,分 ...
- redis生成分布式id方案
分布式Id - redis方式 本篇分享内容是关于生成分布式Id的其中之一方案,除了redis方案之外还有如:数据库,雪花算法,mogodb(object_id也是数据库)等方案,对于redis来 ...
- Actor模型(分布式编程)
Actor的目的是为了解决分布式编程中的一系列问题.所有消息都是异步交付的,因此将消息发送方与接收方分开,正是由于这种分离,导致actor系统具有内在的并发性:可以不受限制地并行执行任何拥有输入消息的 ...
- 分布式ID系列之为什么需要分布式ID以及生成分布式ID的业务需求
为什么需要分布式id生成系统 在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识.如在美团点评的金融.支付.餐饮.酒店.猫眼电影等产品的系统中,数据日渐增长,对数据分库分表后需要有一个唯一ID ...
- 雪花算法生成分布式ID
分布式主键ID生成方案 分布式主键ID的生成方案有以下几种: 数据库自增主键 缺点: 导入旧数据时,可能会ID重复,导致导入失败 分布式架构,多个Mysql实例可能会导致ID重复 UUID 缺点: 占 ...
- 高系统的分布性有状态的中间层Actor模型
写在前面 https://www.cnblogs.com/gengzhe/p/ray_actor.html Orleans是基于Actor模型思想的.NET领域的框架,它提供了一种直接而简单的方法来构 ...
- 美团分布式ID生成框架Leaf源码分析及优化改进
本文主要是对美团的分布式ID框架Leaf的原理进行介绍,针对Leaf原项目中的一些issue,对Leaf项目进行功能增强,问题修复及优化改进,改进后的项目地址在这里: Leaf项目改进计划 https ...
- 程序员修神之路--🤠分布式高并发下Actor模型如此优秀🤠
写在开始 一般来说有两种策略用来在并发线程中进行通信:共享数据和消息传递.使用共享数据方式的并发编程面临的最大的一个问题就是数据条件竞争.处理各种锁的问题是让人十分头痛的一件事. 传统多数流行的语言并 ...
随机推荐
- K8s基于DNS的服务发现(转)
原文地址:https://www.oschina.net/question/2657833_2201246 1.Kubernetes中如何发现服务 ◆ 发现Pod提供的服务 首先使用nginx-d ...
- Linux网络(一)
[root@localhost ~]# ifconfig eth0 Link encap:Ethernet HWaddr :0C:::F6: inet addr:172.17.4.128 Bcast: ...
- Linux的系统引导
启动引导: 1.主机加电自检,加载BIOS信息 2.读取MBR的引导文件[grub lilo] 3.引导linux内核 4.运行第一个进程init pid=1 5.进入相应的运行级别[0-6] 6.运 ...
- UIWebView清除缓存和cookie[转]
现在项目遇到一个问题,游戏底层用Cocos2d-x,公告UI实现是用的UIWebView, 然后第一次在有网络的环境下运行公告UI,会加载url链接,同时就会自动存入缓存,当下次手机没有网络的环境下, ...
- jmeter 计数器 (可自动生成新数字、注册专用)
1.打开jmeter,创建好线程组后,添加计数器 2.设置计数器 3.添加HTTP请求,验证所设置的计数器 4.填写对应参数 5.添加查看结果树,查看结果 6.修改一下线程属性 7.跑一下,看下结果就 ...
- (字典树)Revenge of Fibonacci -- HDU -- 4099
链接: http://acm.hdu.edu.cn/showproblem.php?pid=4099 要用c++交哦, G++ MLE 不是很懂,先粘上慢慢学习 代码: #include<std ...
- weevely入手使用笔记
-前言 weevely是一款使用python编写的webshell工具,集webshell生成和连接于一身,采用c/s模式构建,可以算作是linux下的一款php菜刀替代工具,具有很好的隐蔽性(生成随 ...
- How To Use XDOLoader to Manage, Download and Upload Files? (DOC ID 469585.1)
In this Document Goal Fix Downloading Files Uploading Files References Applies to: BI Publishe ...
- pssh执行本地文件(脚本)
场景:目标命令中含有特殊符号,导致pssh批量执行可能出问题. 用法: pssh -h RemoteHosts.ip -P -I < ~/LocalScript.sh
- ES6——异步操作之Promise
基本概念: Promise : 是 ES6 中新增的异步编程解决方案,提现在代码中他是一个对象 可以通过Promise构造函数来实例化. -new Promise(cb) ===> 实例的基本使 ...