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模型如此优秀🤠
写在开始 一般来说有两种策略用来在并发线程中进行通信:共享数据和消息传递.使用共享数据方式的并发编程面临的最大的一个问题就是数据条件竞争.处理各种锁的问题是让人十分头痛的一件事. 传统多数流行的语言并 ...
随机推荐
- JSP中的一个树型结构
看方力勋的javaWeb,采用左右值来表示树型结构(就是俺门的多级分类)表结构 页面代码 <%@ page language="java" import="java ...
- PostgreSQL CPU满(100%)性能分析及优化
业务场景:大批量更新时,数据库长时间CPU占用超过90,影响其他正常业务流程,参考阿里云上的一篇文章:https://help.aliyun.com/knowledge_detail/43562.ht ...
- Oracle学习笔记(六)
八.函数 1.函数的作用 (1)方便数据的统计 (2)处理查询结果,让数据显示更清楚 2.函数分类(提供很多内置函数,也可自定义函数) (1)数值函数 平均值,四舍五入 a.四舍五入 表达式 roun ...
- LDA详解
PART 1 这个性质被叫做共轭性.共轭先验使得后验概率分布的函数形式与先验概率相同,因此使得贝叶斯分析得到了极⼤的简化. V:文档集中不重复的词汇的数目 语料库共有m篇文档,: 对于文档,由个词 ...
- 日志文件(关于#IRSA_MDPS_RDM软件 密码登录事项 7月26号)
1.登录:sqlplus 用户名:scott 口令:123 qweas.. //2018-7-16号更改密码 2.查看该用户(已登录)下有几个表:select table_name from user ...
- Appium 之处理首次启动手机App时的系统权限弹框
一般首次启动一个手机App时都会有系统权限弹框,如下图所示: 权限弹窗上面的按钮都是固定的,只需要定位到“ALLOW”按钮,点击就可以了,代码如下: 这里主要用selenium里面的显示等待模块(We ...
- linux常见命令-查看磁盘空间
linux查看磁盘使用情况命令 1. 统一每个目录下磁盘的整体情况: df -h 2. 查看指定目录,在命令后直接放目录名,比如查看“usr”目录使用情况:df -h /usr/ 3. 查看当前目录 ...
- Android-bindService本地服务-初步
在Android开发过程中,Android API 已经有了startService方式,为什么还需要bindService呢? 答:是因为bindService可以实现Activity-->S ...
- [LeetCode 题解]: Linked List Cycle II
Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Foll ...
- PipelineDB On Kafka
PipelineDB 安装yum install https://s3-us-west-2.amazonaws.com/download.pipelinedb.com/pipelinedb-0.9.8 ...