Orleans之Hello World
接触Orleans 有一段时间了,之前也翻译了一系列官网文档,今天我们就来一个实际的例子,来看看到底如何用这个东西来开发项目,当然经典的也是醉人的,我们就从HelloWorld开始吧。
通过前面的知识准备我们知道Orleans 项目需要n个服务端(就是silohost),n个客户端(就是调用方),然后就是提供的actors(在Orleans 中成为grain),废话少说。
首先建立一个解决方案,叫做OrleansSamples
然后,增加一个模块解决方案,叫做HelloWorlds,在解决方案下增加两个类库Sample.Interfaces,Sample.Implements,其中Sample.Implements引用Sample.Interfaces,
这两个项目中引用Orleans的核心库,你可以手动一个一个引用进来,但还是老老实实的用nuget吧。
nuget的引用两种方式一种,通过图形化的方式,另一种通过命令的方式,命令:Install-Package Microsoft.Orleans.Core (注:在这里可以找到所需的包http://dotnet.github.io/orleans/NuGets)
记得引用完后如果在nuget里有更新就更新一下,对于新版本,可能里面有些库会没有进来,否则就会报错,反正我是这么做,做完这一切,项目结构如下:
在Sample.Interfaces中增加一个接口IUserService,并且继承接口IGrainWithIntegerKey(关于这个接口有姊妹接口,关于这些接口后续会陆续讲到)
代码如下:
namespace Sample.Interfaces
{
public interface IUserService:IGrainWithIntegerKey
{
Task<bool> Exist(string mobileNumber);
}
}
在Sample.Implements项目中增加实现类UserService,并且继承Grain(Grain这个基类同时也提供了相应的泛型实现Grain<>,关于他们的不同点,以及功能,后续会讲到),且实现IUserService接口
代码如下:
namespace Sample.Implements
{
public class UserService : Grain, IUserService
{
public Task<bool> Exist(string mobileNumber)
{
return Task.FromResult<bool>(mobileNumber=="");
}
}
}
好了到此为止,我们已经开发好actor虽然简单,接下来我们接着增加服务启动寄宿项(关于寄宿项,可以是控制台、windows服务、winfrom、asp.net ),这里我们采用控制台,下面我们创建一个服务控制台应用程序(Server)
引用上面创建两个项目:Sample.Implements、Sample.Interfaces。(注:其实这两个项目不一定要引用进来,只要在生成项目的目录下存在他们的编译好的dll即可,silo用来自动加载启动这个他们)
引用orleans项目中服务端的类库(使用nuget命令:Install-Package Microsoft.Orleans.Server
)
项目结构如下:
代码如下:
namespace Server
{
class Program
{
static void Main(string[] args)
{
using (var host = new SiloHost("Default"))
{
host.InitializeOrleansSilo();
host.StartOrleansSilo();
Console.WriteLine("启动成功!");
Console.ReadLine();
host.StopOrleansSilo();
}
}
}
}
好一切准备就绪,我们F5吧,
当你看到这得时候是不是觉得成功了,真的成功了吗,不一定吧!
哦对了怎么没看到日志呢,好我们在项目目录下看看日志:
果然有日志文件,一看文件名称,直接告诉我们发生错误了,好让我们打开看看吧。
从发生的异常看出,好像少了一个配置文件,在orleans 服务启动时,需要一个配置文件,这个配置文件可以是OrleansConfiguration.xml或者orleans.config或者orleans.config.xml
好知道原因了,知道该怎么做了吧,在server根目录下创建一个xml文件OrleansConfiguration.xml,将该文件的属性“复制到输出目录”值更改为"如果较新则复制"
该文件中填充配置内容,如下(详细配置请看配置一节,此处不解释)
<?xml version="1.0" encoding="utf-8" ?>
<OrleansConfiguration xmlns="urn:orleans">
<Globals>
<StorageProviders>
<Provider Type="Orleans.Storage.MemoryStorage" Name="MemoryStore" />
<Provider Type="Orleans.Storage.MemoryStorage" Name="Default" />
<!--<Provider Type="Orleans.Storage.AzureTableStorage" Name="AzureStore"/>-->
</StorageProviders>
<SeedNode Address="localhost" Port="22222"/>
<Messaging ResponseTimeout="30s"/>
</Globals>
<Defaults>
<Networking Address="localhost" Port="22222"/>
<ProxyingGateway Address="localhost" Port="40000" />
<Tracing DefaultTraceLevel="Info" TraceToConsole="false" TraceToFile="{0}-{1}.log" PropagateActivityId="false" BulkMessageLimit="1000">
<TraceLevelOverride LogPrefix="Application" TraceLevel="Info" />
<!--
<TraceLevelOverride LogPrefix="Runtime.Dispatcher" TraceLevel="Verbose" />
<TraceLevelOverride LogPrefix="AssemblyLoader.Silo" TraceLevel="Warning" />
-->
</Tracing>
<Statistics MetricsTableWriteInterval="30s" PerfCounterWriteInterval="30s" LogWriteInterval="300s" WriteLogStatisticsToTable="true" StatisticsCollectionLevel="Info"/>
</Defaults>
</OrleansConfiguration>
再次启动F5,当看到启动成功的输出时,我们再次看看生成的日志:
这次发现比之前生成的东西多了,但是当我们继续往下浏览的时候发现有个异常:
Exc level 0: System.IO.FileNotFoundException: 未能加载文件或程序集“Microsoft.Extensions.DependencyInjection.Abstractions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60”或它的某一个依赖项。系统找不到指定的文件。
在 Orleans.Runtime.Startup.ConfigureStartupBuilder.ConfigureStartup(String startupTypeName)
在 Orleans.Runtime.Startup.ConfigureStartupBuilder.Orleans.Runtime.Startup.IStartupBuilder.ConfigureStartup(String startupTypeName)
在 Orleans.Runtime.Silo..ctor(String name, SiloType siloType, ClusterConfiguration config, ILocalDataStore keyStore)
原来是少了程序集:Microsoft.Extensions.DependencyInjection
知道原因了,我们通过nuget来引用这个类库,引用成功,再次运行,然后查看日志,异常消失,但是有个问题,每次打开日志文件要看,是否有错误,或者一些关于服务的监控内容,这样是不是很麻烦,其实我们可以更改一下配置信息,让它输出到控制台,这样在开发过程中就方便多了,可以时时看到动态信息,如下:
打开OrleansConfiguration.xml 文件找到<Tracing DefaultTraceLevel="Info" TraceToConsole="false" TraceToFile="{0}-{1}.log" 这个节点,将TraceToConsole的值更改为true保存,再次运行,如下:
好了一切都完美了,接下来我们在继续开发客户端。
在解决方案下创建一个控制台应用程序Client,引用客户端相关类库:Install-Package Microsoft.Orleans.Client
引用项目:Sample.Interfaces
代码如下:
namespace Client
{
class Program
{
static void Main(string[] args)
{
System.Threading.Thread.Sleep();
GrainClient.Initialize(); while (true)
{
Console.WriteLine("请输入用户手机号:");
var mobileNumber = Console.ReadLine();
//这里由于我们采用的grain继承的是IGrainWithIntegerKey ,所以我们采用调用数值类型的key=10来创建这个grain,
//可能有人会问key是干嘛的,他是唯一标识这个grain的,当你指定一个key的时候,Orleans 会创建一个,它首先到
//你的存储介质中找(如果你配置了的话,默认采用内存存储,这种方式适合开发期,生产环境需要保持状态的,所以需要配置到能持久化存储的地方去,比如sqlserver等)
//如果找到了就直接返回,如果没找到就根据你指定的这个key然后创建一个,这个就是grain的激活,具体详细的,可以看官方问的关于Grain一章。
var userService = GrainClient.GrainFactory.GetGrain<IUserService>();
//C#的一种新的表达式语法,这样就方便多了,省的我们拼接字符串。
Console.WriteLine($"用户{mobileNumber},{(userService.Exist(mobileNumber).Result?"已经存在":"不存在")}");
} }
}
}
在client项目下记得要创建配置文件,文件名称叫做ClientConfiguration.xml
内容如下:
<?xml version="1.0" encoding="utf-8" ?>
<ClientConfiguration xmlns="urn:orleans">
<Gateway Address="localhost" Port="40000"/>
<!-- To turn tracing off, set DefaultTraceLevel="Off" and have no overrides.
For the trace log file name, {0} is replaced by "Client" and {1} is the current time. -->
<Tracing DefaultTraceLevel="Info" TraceToConsole="false" TraceToFile="{0}-{1}.log" BulkMessageLimit="1000">
<TraceLevelOverride LogPrefix="Runtime" TraceLevel="Info" />
<TraceLevelOverride LogPrefix="Application" TraceLevel="Info" />
<TraceLevelOverride LogPrefix="AssemblyLoader" TraceLevel="Warning" />
</Tracing>
<Statistics MetricsTableWriteInterval="300s" PerfCounterWriteInterval="30s" LogWriteInterval="300s" WriteLogStatisticsToTable="true" StatisticsCollectionLevel="Info"/>
<Messaging ResponseTimeout="30s" ClientSenderBuckets="8192" MaxResendCount="0"/>
</ClientConfiguration>
注:要记得更改文件属性哦
一切准备就绪,下来让改一下启动方式为多项目启动,然后就F5等待飞吧!
终于看到胜利的果实了,哈哈!接下来我们接着说说另外一种开发方式以及发布方式。
上面的这种开发方式为了说明开发的那些具体步骤,需要引用那些类库,以及客户端如何去调用,步骤比较麻烦,尤其是服务端的开发、引用类库,也没有相应的单元测试,接下来我们看看另外一种服务端的开发方式。
跟上面的大体步骤一样
1.创建接口类库
2.创建实现类库
3.开发测试服务寄宿程序
在开始之前首先要确认一下你是否安装了Orleans的vs模版插件,如果安装了那么如下图:
如果没有安装,赶紧去下载一个吧地址在:http://dotnet.github.io/orleans/NuGets
找到这一节,如下图:
点开里面有你想要的插件,然后安装重启vs
1.创建接口类库
2.创建实现类库
3.创建服务寄宿程序
服务创建完之后,发现下面有自动生成的一个类OrleansHostWrapper,并且在Program下自动生成了很多代码,代码的大体意思就是,将服务端启动程序的逻辑封装在OrleansHostWrapper,然后启动是单独创建一个应用程序域,增加一些测试例子代码,方便多了吧,我们不需要写任何服务端的服务启动代码,在实际开发过程中我们只需要关心业务模块
即接口创建,接口实现,方便多了吧。
将相应的代码贴入进去,还记得上面出现的那个异常吗,记得要将Microsoft.Extensions.DependencyInjection类库引用进来哦,F5吧。
一切如预期所料,成功!
接下来我们创建一个单元测试程序库,方便服务端的程序单元测试Sample.Test
引用项目Sample.Implements、Sample.Interfaces
引用Orleans测试包 PM> Install-Package Microsoft.Orleans.TestingHost
我们创建一个测试类就叫UserServiceTest,继承自Orleans 测试库TestingSiloHost
[ClassCleanup]
public static void ClassCleanup()
{
// Optional.
// By default, the next test class which uses TestignSiloHost will
// cause a fresh Orleans silo environment to be created.
StopAllSilosIfRunning();
}
测试代码如下:
namespace Sample.Test
{
[TestClass]
public class UserServiceTest: TestingSiloHost
{
[ClassCleanup]
public static void ClassCleanup()
{
// Optional.
// By default, the next test class which uses TestignSiloHost will
// cause a fresh Orleans silo environment to be created.
StopAllSilosIfRunning();
} [TestMethod]
public async void TestExist()
{
var grain = GrainFactory.GetGrain<IUserService>();
bool bo = await grain.Exist("");
Assert.IsTrue(bo);
}
}
}
记得增加两个配置文件,
ClientConfigurationForTesting.xml
<?xml version="1.0" encoding="utf-8" ?>
<ClientConfiguration xmlns="urn:orleans">
<Gateway Address="localhost" Port="40000"/>
<!-- To turn tracing off, set DefaultTraceLevel="Off" and have no overrides.
For the trace log file name, {0} is replaced by "Client" and {1} is the current time. -->
<Tracing DefaultTraceLevel="Info" TraceToConsole="false" TraceToFile="{0}-{1}.log" BulkMessageLimit="1000">
<TraceLevelOverride LogPrefix="Runtime" TraceLevel="Info" />
<TraceLevelOverride LogPrefix="Application" TraceLevel="Info" />
<TraceLevelOverride LogPrefix="AssemblyLoader" TraceLevel="Warning" />
</Tracing>
<Statistics MetricsTableWriteInterval="300s" PerfCounterWriteInterval="30s" LogWriteInterval="300s" WriteLogStatisticsToTable="true" StatisticsCollectionLevel="Info"/>
<Messaging ResponseTimeout="30s" ClientSenderBuckets="8192" MaxResendCount="0"/>
</ClientConfiguration>
OrleansConfigurationForTesting.xml
<?xml version="1.0" encoding="utf-8"?>
<OrleansConfiguration xmlns="urn:orleans">
<Globals>
<StorageProviders>
<Provider Type="Orleans.Storage.MemoryStorage" Name="MemoryStore" />
<Provider Type="Orleans.Storage.MemoryStorage" Name="Default" />
<!--<Provider Type="Orleans.Storage.AzureTableStorage" Name="AzureStore"/>-->
</StorageProviders>
<SeedNode Address="localhost" Port="22222"/>
<Messaging ResponseTimeout="30s"/>
</Globals>
<Defaults>
<Networking Address="localhost" Port="22222"/>
<ProxyingGateway Address="localhost" Port="40000" />
<Tracing DefaultTraceLevel="Info" TraceToConsole="false" TraceToFile="{0}-{1}.log" PropagateActivityId="false" BulkMessageLimit="1000">
<TraceLevelOverride LogPrefix="Application" TraceLevel="Info" />
<!--
<TraceLevelOverride LogPrefix="Runtime.Dispatcher" TraceLevel="Verbose" />
<TraceLevelOverride LogPrefix="AssemblyLoader.Silo" TraceLevel="Warning" />
-->
</Tracing>
<Statistics MetricsTableWriteInterval="30s" PerfCounterWriteInterval="30s" LogWriteInterval="300s" WriteLogStatisticsToTable="true" StatisticsCollectionLevel="Info"/>
</Defaults>
</OrleansConfiguration>
更改xml文件属性为:如果较新则复制
测试项目结构大体如下:
好,测试编写完成,如何操作你懂得,这里就不废话了。
接下来说一下部署,部署吧,各有各的妙招,控制台、winform、windows服务等等,这里我说一个框架自带的一个部署控制台怎么用
记得Orleans 里面有这么一个程序OrleansHost.exe,他是干什么用的呢,对了就是用来部署的。
我们来看看他的源码,弄清楚他到底是做了一件什么事情
如下图:
打开这个文件,可以发现这个文件跟上面我们通过模版创建的server中的文件OrleansHostWrapper很相似,对了,这个就是为了保持开发部署的一致性,所以这个就可以用来直接部署了
我们在server的Debug下找到相应的程序,将程序复制到某个盘符比如D:\demo下面
如下图:
然后将配置文件拷贝进来OrleansConfiguration.xml
一切准备就绪,我们运行把,双击StartOrleans.cmd服务启动
运行成功.
你会发现这个服务部署于我们的开发互不影响,当我们开发好一个grain的时候,直接编译丢到这个部署目录下,别的地方就可以访问了,可以让我们重点关注业务逻辑,而不需要关心那些复杂的配置或者服务的开启关闭等等。 实例代码
Orleans之Hello World的更多相关文章
- .NET的Actor模型:Orleans
Orleans是微软推出的类似Scala Akka的Actor模型,Orleans是一个建立在.NET之上的,设计的目标是为了方便程序员开发需要大规模扩展的云服务, 可用于实现DDD+EventSou ...
- 一种基于Orleans的分布式Id生成方案
基于Orleans的分布式Id生成方案,因Orleans的单实例.单线程模型,让这种实现变的简单,贴出一种实现,欢迎大家提出意见 public interface ISequenceNoGenerat ...
- ORLEANS REMOTE DEPLOYMENT
Orleans Remote Deployment Table of Contents Overview: 1 Prerequisites. 2 Deployment Steps. 2 Orleans ...
- Microsoft Orleans 之 入门指南
Microsoft Orleans 在.net用简单方法构建高并发.分布式的大型应用程序框架. 原文:http://dotnet.github.io/orleans/ 在线文档:http://dotn ...
- orleans/Documentation
福利 奥尔良的主要好处是︰开发人员工作效率,甚至为非专家程序员;和默认的透明可伸缩性与程序员没有特别努力.我们扩大每个下面这些好处. 开发人员的生产力 奥尔良的编程模型通过提供以下关键的抽象. 担保和 ...
- github.com/dotnet/orleans
Orleans is a framework that provides a straight-forward approach to building distributed high-scale ...
- 微软分布式云计算框架Orleans(1):Hello World
自从写了RabbitHub框架系列后的一段时间内一直在思索更加轻量简便,分布式高并发的框架(RabbitHub学习成本较高),无意间在网上级联看到了很多新框架:从helios到Akka.NET在到Or ...
- 微软分布式云计算框架Orleans(2):容灾与集群(1)
在上一篇:微软分布式云计算框架Orleans(1):Hello World,我们大概了解了Orleans如何运用,当然上一篇的例子可以说是简单且无效的,因为用了Orleans不可能只写一个Hello ...
- Orleans是什么 (一)
官网:http://dotnet.github.io/orleans/ 文档:http://dotnet.github.io/orleans/What's-new-in-Orleans 源码:http ...
- Orleans 高级特性-目录
这里将介绍一些Orleans的高级特性,适合对Orleans已经有不少了解的用户,先列出一个索引,博客文章慢慢补充 1.使用Immutable 优化复制 2.自定义序列化 (待完成) 3.可重入 Gr ...
随机推荐
- js判断密码强度
html代码: <form name="form1" action=""> 密码:<input type="password&quo ...
- Node.js 在 PayPal实战
之前有过一个谈了很多关于PayPal移动到node.js的一个应用平台.作为设置我的免费用户界面的第1部分的延续,我很高兴地说,这些传言是真的,我们的Web应用程序正在从Java迁移到JavaScri ...
- IOS开发 应用程序图标数字角标
其实实现这个功能很简单,只要调用UIApplication即可. 用法用例:[UIApplication sharedApplication].applicationIconBadgeNumber ...
- Intellij IDEA 14的注册机
将以下代码保存成keygen.java import java.math.BigInteger; import java.util.Date; import java.util.Random; imp ...
- 将w3cplus网站中的文章页面提取并导出为pdf文档
最近在看一些关于CSS3方面的知识,主要是平时看到网页中有很多用CSS3实现的很炫的效果,所以就打算系统的学习一下.在网上找到很多的文章,但都没有一个好的整理性,比较凌乱.昨天看到w3cplus网站中 ...
- [转载] Redis
转载:http://snowolf.iteye.com/blog/1630697 大约一年多前,公司同事开始使用Redis,不清楚是配置,还是版本的问题,当时的Redis经常在使用一段时间后,连接爆满 ...
- 随机抽样一致性算法(RANSAC)示例及源代码
作者:王先荣 大约在两年前翻译了<随机抽样一致性算法RANSAC>,在文章的最后承诺写该算法的C#示例程序.可惜光阴似箭,转眼许久才写出来,实在抱歉.本文将使用随机抽样一致性算法来来检测直 ...
- 安装vs2013以后,链接数据库总是报内存损坏,无法写入的错误
安装vs2013以后,链接数据库总是报内存损坏,无法写入的错误 这个错误几个月以前解决过一次,但是到又碰到的时候,竟然完全忘记当时怎么解决的了, 看来上了年纪记忆真是越来越不行了... 解决方案很简单 ...
- 配置算法(第4版)的Java编译环境
1. 下载 1.1 JDK http://www.oracle.com/technetwork/java/javase/downloads/index.html选择“Windows x64 180.5 ...
- 【转】--在Android源码树中添加userspace I2C读写工具(i2c-util)
通过/dev/i2c-n节点,用户可以在userspace直接访问板上的i2c外设寄存器,主要是透过I2C_RDWR这个IO控制命令将i2c_msg数组传递给kernel去执行.下面的代码可以完成这个 ...