1. 程式人生 > >Orleans 初接觸(一) 入門例子

Orleans 初接觸(一) 入門例子

方法 ket sys pre 直接 .cn rain ros sqlserve

【返回導航】

  在簡單了解了Orleans 之後我們可以通過幾個例子去加深印象

一、Orleans入門例子

  這個例子是跟著《Orleans入門例子》(https://www.cnblogs.com/gaopang/articles/7379802.html)

  1.創建

  首先創建一個四個項目的解決方案,如圖所示

  技術分享圖片

  四個項目分別是:

  1. Client:這個顯而易見,裏面就是要運行GrainClient的。它要和Host通信,這就要求它引用IGrains項目。這是個控制臺項目
  2. Host:這個也是顯而易見,裏面就是要運行Silo的。它應該引用Grains項目以及IGrains項目,因為它要承載Grain(這就要求引用Grains類),並且需要Grain實例間的通信(這就要求引用IGrains項目),這是個控制臺項目
  3. Grains:這個裏面實現所有IGrain載明的接口,實現所有的Grain類,包括它們的方法以及字段。(它要求引用IGrain。。。廢話)這是個類庫項目
  4. 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 初接觸(一) 入門例子