一、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的更多相关文章

  1. 基于雪花算法生成分布式ID(Java版)

    SnowFlake算法原理介绍 在分布式系统中会将一个业务的系统部署到多台服务器上,用户随机访问其中一台,而之所以引入分布式系统就是为了让整个系统能够承载更大的访问量.诸如订单号这些我们需要它是全局唯 ...

  2. 基于Actor模型的CQRS、ES解决方案分享

    开场白 大家晚上好,我是郑承良,跟大家分享的话题是<基于Actor模型的CQRS/ES解决方案分享>,最近一段时间我一直是这个话题的学习者.追随者,这个话题目前生产环境落地的资料少一些,分 ...

  3. redis生成分布式id方案

    分布式Id - redis方式   本篇分享内容是关于生成分布式Id的其中之一方案,除了redis方案之外还有如:数据库,雪花算法,mogodb(object_id也是数据库)等方案,对于redis来 ...

  4. Actor模型(分布式编程)

    Actor的目的是为了解决分布式编程中的一系列问题.所有消息都是异步交付的,因此将消息发送方与接收方分开,正是由于这种分离,导致actor系统具有内在的并发性:可以不受限制地并行执行任何拥有输入消息的 ...

  5. 分布式ID系列之为什么需要分布式ID以及生成分布式ID的业务需求

    为什么需要分布式id生成系统 在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识.如在美团点评的金融.支付.餐饮.酒店.猫眼电影等产品的系统中,数据日渐增长,对数据分库分表后需要有一个唯一ID ...

  6. 雪花算法生成分布式ID

    分布式主键ID生成方案 分布式主键ID的生成方案有以下几种: 数据库自增主键 缺点: 导入旧数据时,可能会ID重复,导致导入失败 分布式架构,多个Mysql实例可能会导致ID重复 UUID 缺点: 占 ...

  7. 高系统的分布性有状态的中间层Actor模型

    写在前面 https://www.cnblogs.com/gengzhe/p/ray_actor.html Orleans是基于Actor模型思想的.NET领域的框架,它提供了一种直接而简单的方法来构 ...

  8. 美团分布式ID生成框架Leaf源码分析及优化改进

    本文主要是对美团的分布式ID框架Leaf的原理进行介绍,针对Leaf原项目中的一些issue,对Leaf项目进行功能增强,问题修复及优化改进,改进后的项目地址在这里: Leaf项目改进计划 https ...

  9. 程序员修神之路--🤠分布式高并发下Actor模型如此优秀🤠

    写在开始 一般来说有两种策略用来在并发线程中进行通信:共享数据和消息传递.使用共享数据方式的并发编程面临的最大的一个问题就是数据条件竞争.处理各种锁的问题是让人十分头痛的一件事. 传统多数流行的语言并 ...

随机推荐

  1. ORA-00054、ORA-08002

    https://docs.oracle.com/cd/B10501_01/server.920/a96525/e7500.htm ORA-00054 resource busy and acquire ...

  2. Spring全局异常处理

    最近学习Spring时,认识到Spring异常处理的强大.之前处理工程异常,代码中最常见的就是try-catch-finally,有时一个try,多个catch,覆盖了核心业务逻辑: 1 try{ 2 ...

  3. Android-startService后台运行

    什么时候使用startService? 答:APP在后台长时间运行并执行业务的时候,可以用服务,主要是看服务的特点(在后台长时间运行): Service相关代码: package liudeli.se ...

  4. 使用Hbuilder将自己app发布到App Store(一)

    1.如果你有mac系统那请看第二步. 首先需要一台虚拟机,还需要个插件要不没法装,都在这链接里面了 链接:https://pan.baidu.com/s/1N_pWJWFk-EJILTXuFr6w5g ...

  5. sqlcmd 执行SQL语句或没有足够的内存来执行脚本

    win+r命令提示框里面输入cmd sqlcmd -S . -U username -P password -d database -i url -S 数据库地址 -U 登录名称 -P 密码 -d 数 ...

  6. Visual Studio效率神器——超级扩展ReSharper安装和破解

    Visual Studio效率神器--超级扩展ReSharper安装和破解   ReSharper的使用方法网络上有文章Resharper安装和破解极其简单,2分钟就搞定了.安装ReSharper官方 ...

  7. Let it crash philosophy part II

    Designing fault tolerant systems is extremely difficult.  You can try to anticipate and reason about ...

  8. php 编译代码

    编译其实就是把所有的代码整合在于一个文件,减少文件包含时间,加快php解析,虽然优化后时间上提升了不多,但能优化便多多少少进行优化.下面给一个编译例子,从而引申. // 定义编译状态 define(' ...

  9. break与continue语句

    1.break:立即退出循环 <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...

  10. FastDFS 安装与使用

    FastDFS 安装与使用 1. 什么是 FastDFS FastDFS是一个开源的高性能分布式文件系统(DFS). 它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡的设计. Fa ...