[orleans2.1]这是你没玩过的船新版本
不知不觉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]这是你没玩过的船新版本的更多相关文章
- 没玩过这些微信小游戏你就out了
你确定没玩过下面这些微信小游戏?是不是有点out了?赶紧添加微信号kangfuyk,回复H5马上畅玩! 当然了,扫一下二维码关注后回复H5更快捷噢! 微信小游戏列表,持续更新中 辨色大比拼!心理游戏 ...
- 好久没玩docker了,温下手
好久没玩docker了,温下手 安装 Docker Docker 软件包已经包括在默认的 CentOS-Extras 软件源里.因此想要安装 docker,只需要运行下面的 yum 命令: yum i ...
- 好久没玩laravel了,今天玩下Laravel项目迁移步骤
.在新的目录中克隆git远程版本库 .执行composer install安装依赖 .执行php artisan key:generate生成key 好久没玩laravel了,今天玩下Laravel项 ...
- 你没玩过的全新版本!Win10这些骚操作你知多少
你没玩过的全新版本!Win10这些骚操作你知多少 [PConline技巧]不知不觉,Win10与我们相伴已经整整四个年头了,从最开始的组团抗拒到现在的默默接受,个中滋味相信谁心里都有个数.近日微软开始 ...
- 好久没玩laravel了,5.6玩下(三)
好了,基础的测试通了,咱们开始增删改了 思路整理 先创建项目功能控制器 然后设置路由访问规则 然后开发项目的增删改功能 1 先创建项目的控制器 php artisan make:controller ...
- 好久没玩laravel了,5.6玩下(二)
做个项目的增删改查 第一步 把数据库的表结构建好,生成迁移 1 怎么建,当然是用php artisan命令了 使用 Artisan 命令 make:migration 来创建一个新的迁移: php ...
- 好久没玩laravel了,5.6玩下(一)
那么先到官方找到框架,然后安装下 composer安装的,composer怎么安装的 我就不说了 前置条件: PHP >= OpenSSL PHP Extension PDO PHP Exten ...
- 你没有见过的【高恪】船新版本(SX3000 NAT1 X86魔改)
最近魔改了高恪SX3000 X86,做了如下更改: 开启了SSH 集成了插件(酸酸乳.V2RXY.SMB等等) 开启了NAT1 DIY了主题 精简了官方内置的无用应用和模块 截图(建议右击图片,在新标 ...
- 万万没想到!ModelArts与AppCube组CP了
摘要:嘘,华为云内部都不知道的秘密玩法,我悄悄告诉您! 双"魔"合璧庆双节 ↑开局一张图,故事全靠编 华为云的一站式开发平台ModelArts和应用魔方AppCube居然能玩到一起 ...
随机推荐
- appium----【已解决】【Mac】安装sudo npm install -g appium-doctor总是提示“Error: EACCES: permission denied........”
[mac电脑] 问题: (1)npm install -g appium-doctor (2)sudo npm install -g appium-doctor (3)cnpm install ...
- 对图片进行索引,存入数据库sqlite3中,实现快速搜索打开
对图片进行索引,存入数据库中,实现快速搜索打开 这个任务分为两步: 第一步:建立索引 import os import shutil import sqlite3 # 扫描函数,需扫描路径目录处 ...
- 死链接检查工具:Xenu 使用教程
一.软件作用 Xenu 全称Xenu’s Link Sleuth,是一款英文软件,界面单一,功能简单,使用方法很容易掌握.虽然看起来简单,但Xenu却拥有强大的功能.Xenu可以对网站的内链进行详细的 ...
- SSRS报表服务随笔(rdl报表服务)-报表结构与样式
设计rdl报表,比设置HTML页面简单多了,Reporting报表分为页眉,页脚,主体三个部分 rdl文件实际是xml结构的文件,具体是什么语言呢,很抱歉,这点我还不能回复,在我看来,是由固定节点的x ...
- JAVA匿名内部类(Anonymous Classes)
1.前言 匿名内部类在我们JAVA程序员的日常工作中经常要用到,但是很多时候也只是照本宣科地用,虽然也在用,但往往忽略了以下几点:为什么能这么用?匿名内部类的语法是怎样的?有哪些限制?因此,最近,我在 ...
- DSAPI显示PNG异形窗体
使用DSAPI实现PNG异形窗体,注意,该窗体为层样式窗体,以PNG或32位带透明通道的图像合成到屏幕,此方法不会触发窗体的重绘,故原窗体(包括其子控件)均不会显示,如果需要更新画面,需要重新用代码等 ...
- Hibernate学习——持久化类的学习
A.概念 持久化:将内存中的对象持久化(存储)到数据库的过程.Hibernate就是持久化的框架. 持久化类:一个普通java对象与数据库的表建立了映射关系,那么这个类在Hiberna中被称为持久化类 ...
- 我学Java我傲娇
今天,终于把学习了一年多的<Java核心技术36讲>第一遍完结了,历时一年多,花出去的钱终于感觉有了第一笔回报. 这是我在极客时间的第一门付费课程,刚出来的时候,正巧自己转到全职Java开 ...
- ggsci: error while loading shared libraries: libnnz11.so
[oracle@localhost goldengate]$ ./ggsci ./ggsci: error while loading shared libraries: libnnz11.so: c ...
- VMWare安装Mac系统后无法全屏显示的问题
系统: VMTOOLs下载: 链接:https://pan.baidu.com/s/1KIzVWtPrb2vSrtokONToBw 提取码:zea3 1.虚拟机设置--显示器--监视器--指定监视器设 ...