不知不觉orleans就发布到2.1版本的,但是说也奇怪orleans越是完善我发现园子相关的博客就越少,大概是大佬都在美滋滋用在生产环境,不屑于玩demo了吧。

  但是小弟不才还是只会玩demo,所以只能简单的介绍介绍2.1版本的新玩法了。

  1.新建一个asp.net core的webapi项目,然后引用下面几个nuget包:

 Microsoft.Orleans.OrleansRuntime
Microsoft.Orleans.CodeGenerator.MSBuild
Microsoft.Orleans.Transactions
Orleans.Providers.MongoDB
OrleansDashboard

  2.包装一下orleans的silobuilder类,并且继承IHostedService直接和asp.net core运行在一起

     public class SiloWrapper : IHostedService
{
private readonly ISiloHost _silo;
public readonly IClusterClient Client; public SiloWrapper()
{
_silo = new SiloHostBuilder()
.UseLocalhostClustering()
.ConfigureApplicationParts(parts =>
parts.AddApplicationPart(typeof(Grains.IUserGrain).Assembly).WithReferences())
.EnableDirectClient()//2.1新增的功能,单个Host可以直接使用SiloHost的Client,不需要再用ClientBuilder建Client了
.AddMongoDBGrainStorageAsDefault(options =>
{
options.ConnectionString = "mongodb://localhost/OrleansTestApp";
})//配置数据库
.ConfigureLogging(x =>
{
x.AddConsole();
x.SetMinimumLevel(LogLevel.Warning);
})
.UseDashboard(x =>
{
x.HostSelf = false;
})//HostSelf设置为false
.UseTransactions()//2.1的事务配置简化了
.Build(); Client = _silo.Services.GetRequiredService<IClusterClient>();//把sliohost的IClusterClient暴露出去。
} public async Task StartAsync(CancellationToken cancellationToken)
{
await _silo.StartAsync(cancellationToken);
} public async Task StopAsync(CancellationToken cancellationToken)
{
await _silo.StopAsync(cancellationToken);
}
}

  3.Startup类配置:

     public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
} public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<SiloWrapper>();//注入SiloWrapper
services.AddSingleton<IHostedService>(x=>x.GetRequiredService<SiloWrapper>());//同时把SiloWrapper注入为IHostedService
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSingleton(x => x.GetRequiredService<SiloWrapper>().Client);//注入SiloWrapper的Client
services.AddServicesForSelfHostedDashboard();//注入orleans的dashboard
} public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseOrleansDashboard(new OrleansDashboard.DashboardOptions { BasePath = "/dashboard"});//设置一下dashboard的访问路径
app.UseMvc();
}
}

  4.新建一些Grain类,这里只给出一个后面我会贴代码地址出来。

    public class UserGrain:Grain<UserInfo>,IUserGrain
{
public ValueTask<UserInfo> GetInfo()//同步代码可以返回ValueTask
{
return new ValueTask<UserInfo>(State);
} public async Task<UserInfo> UpdateInfo(UserInfo info)
{
State = info;
await WriteStateAsync();//更新数据才需要数据库相关的操作
return State;
} public async Task<uint> GetBalance()
{
var account = this.GrainFactory.GetGrain<IAccountGrain>(this.GetPrimaryKeyLong());//通过GrainFactory访问其他grain
return await account.GetBalance();
}
}
    [StatelessWorker]
public class ATMGrain : Grain, IATMGrain//转账事务的专用grain
{
Task IATMGrain.Transfer(long fromAccount, long toAccount, uint amountToTransfer)
{
return Task.WhenAll(
this.GrainFactory.GetGrain<IAccountGrain>(fromAccount).Withdraw(amountToTransfer),
this.GrainFactory.GetGrain<IAccountGrain>(toAccount).Deposit(amountToTransfer));
}
} public class AccountGrain : Grain, IAccountGrain//加钱,减钱,查钱啦
{
private readonly ITransactionalState<Balance> _balance; public AccountGrain(
[TransactionalState("balance")] ITransactionalState<Balance> balance)
{
_balance = balance ?? throw new ArgumentNullException(nameof(balance));
} async Task IAccountGrain.Deposit(uint amount)
{
await _balance.PerformUpdate(x => x.Value += amount);
} async Task IAccountGrain.Withdraw(uint amount)
{
await _balance.PerformUpdate(x =>
{
if (x.Value < amount)
{
throw new InvalidOperationException( "The transferred amount was greater than the balance.");
}
return x.Value -= amount;
});
} Task<uint> IAccountGrain.GetBalance()
{
return _balance.PerformRead(x => x.Value);
}
}

 5.controller相关的代码,这里也是照旧只贴一部分

    [Route("api/[controller]")]
public class ValuesController : Controller
{
private readonly IClusterClient _client; public ValuesController(IClusterClient client)
{
_client = client;
} [HttpGet("[action]/{id}")]
public async Task<object> GetInfo(long id)
{
var userGrain = _client.GetGrain<IUserGrain>(id);
return await userGrain.GetInfo();
}
}

  代码地址:https://github.com/iJzFan/orleansdemo

  可以看到2.1之后配置真的简单了很多,简单几步之后你就能快乐的进行无数据库设计无并发考虑的编程啦。

  最后面是我用jmeter做的一个小测试(不是特别严谨,日志都是开着的,不要太纠结数据),配置嘛就是那个1核两G的腾讯云垃圾主机啦,上面跑了一个两个docker,一个是前面的orleansdemo,一个是mongodb。

  测试条件就是用户1和用户2相互转账( ̄︶ ̄)↗ ,10个线程,分别转1000次(对应的URL:/api/values/atm?from=1&to=2&amount=1和/api/values/atm?from=2&to=1&amount=1)。

  测试条件就是1转2,2转3,3转4,4转1,10个线程,分别转500次(url参考上面)。

  时延还是挺低的,平均才55~61ms,腾讯云那个垃圾主机一秒都能处理150~160的事务请求。

  最最后面贴几个orleans相关的代码库,毕竟我上面的demo还是太小儿科了,

  https://github.com/RayTale/Ray 分布式、高性能、事件溯源、事件驱动、最终一致性框架

  https://github.com/Squidex/squidex Headless CMS and Content Managment Hub

[orleans2.1]这是你没玩过的船新版本的更多相关文章

  1. 没玩过这些微信小游戏你就out了

    你确定没玩过下面这些微信小游戏?是不是有点out了?赶紧添加微信号kangfuyk,回复H5马上畅玩! 当然了,扫一下二维码关注后回复H5更快捷噢! 微信小游戏列表,持续更新中 辨色大比拼!心理游戏 ...

  2. 好久没玩docker了,温下手

    好久没玩docker了,温下手 安装 Docker Docker 软件包已经包括在默认的 CentOS-Extras 软件源里.因此想要安装 docker,只需要运行下面的 yum 命令: yum i ...

  3. 好久没玩laravel了,今天玩下Laravel项目迁移步骤

    .在新的目录中克隆git远程版本库 .执行composer install安装依赖 .执行php artisan key:generate生成key 好久没玩laravel了,今天玩下Laravel项 ...

  4. 你没玩过的全新版本!Win10这些骚操作你知多少

    你没玩过的全新版本!Win10这些骚操作你知多少 [PConline技巧]不知不觉,Win10与我们相伴已经整整四个年头了,从最开始的组团抗拒到现在的默默接受,个中滋味相信谁心里都有个数.近日微软开始 ...

  5. 好久没玩laravel了,5.6玩下(三)

    好了,基础的测试通了,咱们开始增删改了 思路整理 先创建项目功能控制器 然后设置路由访问规则 然后开发项目的增删改功能 1 先创建项目的控制器 php artisan make:controller ...

  6. 好久没玩laravel了,5.6玩下(二)

    做个项目的增删改查 第一步  把数据库的表结构建好,生成迁移 1 怎么建,当然是用php artisan命令了 使用 Artisan 命令 make:migration 来创建一个新的迁移: php ...

  7. 好久没玩laravel了,5.6玩下(一)

    那么先到官方找到框架,然后安装下 composer安装的,composer怎么安装的 我就不说了 前置条件: PHP >= OpenSSL PHP Extension PDO PHP Exten ...

  8. 你没有见过的【高恪】船新版本(SX3000 NAT1 X86魔改)

    最近魔改了高恪SX3000 X86,做了如下更改: 开启了SSH 集成了插件(酸酸乳.V2RXY.SMB等等) 开启了NAT1 DIY了主题 精简了官方内置的无用应用和模块 截图(建议右击图片,在新标 ...

  9. 万万没想到!ModelArts与AppCube组CP了

    摘要:嘘,华为云内部都不知道的秘密玩法,我悄悄告诉您! 双"魔"合璧庆双节 ↑开局一张图,故事全靠编 华为云的一站式开发平台ModelArts和应用魔方AppCube居然能玩到一起 ...

随机推荐

  1. es6学习笔记-class之继承

    继承 上一篇学习了class的概念,在es5时,对象的继承有好几种,原型链继承,借用构造函数继承,组合继承,原型式继承,寄生式继承以及寄生组合式继承,都是按照函数的形式去集成的,现在class也有它的 ...

  2. 【Python3爬虫】常见反爬虫措施及解决办法(二)

    这一篇博客,还是接着说那些常见的反爬虫措施以及我们的解决办法.同样的,如果对你有帮助的话,麻烦点一下推荐啦. 一.防盗链 这次我遇到的防盗链,除了前面说的Referer防盗链,还有Cookie防盗链和 ...

  3. Java进阶篇 设计模式之十四 ----- 总结篇

    前言 本篇是讲述之前学习设计模式的一个总结篇,其目的是为了对这些设计模式的进行一个提炼总结,能够通过查看看此篇就可以理解一些设计模式的核心思想. 设计模式简介 什么是设计模式 设计模式是一套被反复使用 ...

  4. SpringCloud-服务注册与发现(注册中心)

    SpringCloud-服务注册与发现(注册中心) 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 注:作者使用IDEA + Gradle 注:需要有一定的java&& ...

  5. 产品管理开发之Git工作流和分支规范推荐

    前言 无论是开源项目还是内部项目,使用Git都是大势所趋,尤其是在产品管理这块,使用Git大大提高了开发效率和产品的交付频率.本篇,针对Git的工作流和分支使用,进行了一些推荐. 目录 1     产 ...

  6. MYSQL 主从复制,读写分离(8)

    Mysql 数据库的主从复制方案,是其自带的功能,并且主从复制并不是复制磁盘上的数据文件,而是通过binlog日志复制到需要同步的服务器上. 一 主从复制的原理实现 原理图解说: 数据库更改 生成数据 ...

  7. “.Net 社区大会”(dotnetConf) 2018 Day 1 主题演讲

    Miguel de Icaza.Scott Hunter.Mads Torgersen三位大咖给大家带来了 .NET Core ,C# 以及 Xamarin的精彩内容: 6月份已经发布了.NET Co ...

  8. Linux下查看文件内容的命令和工具

    1.catcat命令主要用来查看文件内容,创建文件,合并文件,追加文件等. 1.1.查看文件 格式:cat 文件名称 说明:这条命令会把文件内容全部输出到显示屏上. cat -n 文件名称:查看文件内 ...

  9. SQL Server常用函数使用方法(学习)

    1.转载至 https://www.cnblogs.com/Brambling/p/6779434.html Substring()函数,用于截取字符串方法,三个参数 参数1:用于指定要操作的字符串 ...

  10. Ubuntu16.04 部署安装Docker容器 & 注意事项

    一.部署安装Docker容器 1.1 Ubuntu下安装 crul sudo apt install curl curl是利用URL语法在命令行方式下工作的开源文件传输工具.它被广泛应用在Unix.多 ...