Orleans 初接觸(一) 入門例子
【返回導航】
在簡單了解了Orleans 之後我們可以通過幾個例子去加深印象
一、Orleans入門例子
這個例子是跟著《Orleans入門例子》(https://www.cnblogs.com/gaopang/articles/7379802.html)
1.創建
首先創建一個四個項目的解決方案,如圖所示
四個項目分別是:
- Client:這個顯而易見,裏面就是要運行GrainClient的。它要和Host通信,這就要求它引用IGrains項目。這是個控制臺項目
- Host:這個也是顯而易見,裏面就是要運行Silo的。它應該引用Grains項目以及IGrains項目,因為它要承載Grain(這就要求引用Grains類),並且需要Grain實例間的通信(這就要求引用IGrains項目),這是個控制臺項目
- Grains:這個裏面實現所有IGrain載明的接口,實現所有的Grain類,包括它們的方法以及字段。(它要求引用IGrain。。。廢話)這是個類庫項目
- IGrains:這裏放置所有Grains類要擴展的接口。這是個類庫項目。
然後使用NuGet引用Microsoft.Orleans.Server
接著使用NuGet引用Microsoft.Orleans.Client
2.編碼
IGrains.IBasic
public interface IBasic : IGrainWithIntegerKey { Task<string> SayHello(string hellostr); }
Grains.BasicGrain
public class BasicGrain : Grain, IGrains.IBasic { public Task<string> SayHello(string hellostr) { Console.WriteLine("{0} : {1}", DateTime.Now.ToString("HH:mm:ss.fff"), hellostr); return Task.FromResult<string>("done"); } }
Host.Program
class Program { static void Main(string[] args) { //獲得一個配置實例 //他需要兩個端口,第一個端口2334是用來silo與silo之間的通信的,第二個1234是用於監聽client的請求的 var config = Orleans.Runtime.Configuration.ClusterConfiguration.LocalhostPrimarySilo(2234, 1234); //初始化一個silohost,這裏使用了Orleans提供的silohost而不是silo,其中silo的名字命名為Ba; SiloHost siloHost = new SiloHost("Ba", config); //初始化倉儲 siloHost.InitializeOrleansSilo(); //啟動 siloHost.StartOrleansSilo(); //檢查一下 if (siloHost.IsStarted) { Console.WriteLine("silohost 啟動成功"); } else { Console.WriteLine("啟動失敗"); } Console.ReadKey(); } }
class Program { static void Main(string[] args) { //等待服務端啟動完畢 Console.ReadKey(); //然後我聰明的敲擊了回車鍵 Run(); Console.ReadKey(); } static async void Run() { //利用內置方法獲得一個配置類,這個類指明服務端的端口是1234 //可以利用配置文件,不過這裏我就先用這個簡單的配置類 var config = Orleans.Runtime.Configuration.ClientConfiguration.LocalhostSilo(1234); //初始化一個GrainClient GrainClient.Initialize(config); //從silo處,獲得了一個BasicGrain的接口 IGrains.IBasic agrain = GrainClient.GrainFactory.GetGrain<IGrains.IBasic>(314); //調用裏面的方法,等待它返回 string result = await agrain.SayHello("還好"); Console.WriteLine(result); } }
3.運行
但是在運行Client的時候導致了一個問題
還不知道怎麽解決,就卡在這裏了。
後續解決:
在博客園獲得了博主大大的提示,仔細檢查之後,發現原來是我的host項目沒有引用引用Grains項目以及IGrains項目。在引用之後,整個項目就能完整的運行下來了。
二、快速入門示例
這個例子是跟著《Microsoft Orleans 之 入門指南》(https://www.cnblogs.com/endv/p/6147976.html)中的快速入門示例做的
1.創建
同樣,是先創建一個四個項目的解決方案,這裏把它命名為OrleansSamples
項目的結構和上一個例子一樣,同樣是引用Microsoft.Orleans.Server(服務端包)和Microsoft.Orleans.Client(客戶端包)
不一樣的是這個例子使用了和上一個例子不一樣的接口
2.編碼
IUserService
public interface IUserService : IGrainWithIntegerKey { Task<bool> Exist(string mobileNumber); }
UserService
public class UserService : Grain, IUserService { public Task<bool> Exist(string mobileNumber) { return Task.FromResult<bool>(mobileNumber == "15665699774"); } }
Server
class Program { static void Main(string[] args) { using (var host = new SiloHost("Default")) { host.InitializeOrleansSilo(); host.StartOrleansSilo(); Console.WriteLine("啟動成功!"); Console.ReadLine(); host.StopOrleansSilo(); } } }
Client
class Program { static void Main(string[] args) { System.Threading.Thread.Sleep(15000); 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>(10); //C#的一種新的表達式語法,這樣就方便多了,省的我們拼接字符串。 Console.WriteLine($"用戶{mobileNumber},{(userService.Exist(mobileNumber).Result ? "已經存在" : "不存在")}"); } } }
3.運行
想要將這個Orleans 運行起來,還需要做件事
在Server目錄下添加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="true" 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>
在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>
並且對這兩個xml文件設置屬性-高級-復制到輸出目錄-如果較新則復制
將Server(服務端)和Client(客戶端)分別運行後,即可得到效果
至此一個簡單的單服務的Orleans就已經完成了,從這個例子裏能簡單的理解一下Orleans。但是究竟一個分布式的集群服務器應該怎麽搭建,還是毫無頭緒,然我們繼續學習西區
Orleans 初接觸(一) 入門例子