• Learn Orleans 02


    基础概念

    Orleans的核心概念见上图。

    --https://www.cnblogs.com/sheng-jie/p/11223848.html

    --https://github.com/sheng-jie/Samples.AllInOne/tree/dev/Orleans

    Grain就是Actor,是执行的最小单位。Silo是Orleans的运行时,用于托管Grains。一组Silo能够形成分布式集群,并能够进行容错处理。

    --https://dotnet.github.io/orleans/Documentation/index.html

    Grain = 身份 + 行为 + 状态(可选)

    Grain的生命周期由运行时管理,状态变化如下图:

    Hello World

    https://dotnet.github.io/orleans/Documentation/tutorials_and_samples/tutorial_1.html

    Orleans Hello World由四个项目组成:

    1. grain interfaces
    2. grain classes
    3. Silo Host
    4. Console Client

    首先创建项目结构

    dotnet new console -n Silo
    dotnet new console -n Client
    dotnet new classlib -n GrainInterfaces
    dotnet new classlib -n Grains
    dotnet new sln -n OrleansHelloWorld
    dotnet sln add Silo Client GrainInterfaces Grains
    

    设置这四个项目的依赖关系如上图所示。

    随后添加所需的nuget包

    #silo
    dotnet add package Microsoft.Orleans.Server
    dotnet add package Microsoft.Extensions.Logging.Console
    #client
    dotnet add package Microsoft.Orleans.Client 
    dotnet add package Microsoft.Extensions.Logging.Console
    #GrainInterfaces
    dotnet add package Microsoft.Orleans.Core.Abstractions 
    dotnet add package Microsoft.Orleans.CodeGenerator.MSBuild
    #Grains
    dotnet add package Microsoft.Orleans.Core.Abstractions
    dotnet add package Microsoft.Orleans.CodeGenerator.MSBuild
    dotnet add package Microsoft.Extensions.Logging.Abstractions
    

    GrainInterface - IHello.cs

    using System.Threading.Tasks;
    
    namespace OrleansBasics
    {
        public interface IHello : Orleans.IGrainWithIntegerKey
        {
            Task<string> SayHello(string greeting);
        }
    }
    

    Grain - HelloGrain.cs

    using Microsoft.Extensions.Logging;
    using System.Threading.Tasks;
    
    namespace OrleansBasics
    {
        public class HelloGrain : Orleans.Grain, IHello
        {
            private readonly ILogger logger;
    
            public HelloGrain(ILogger<HelloGrain> logger)
            {
                this.logger = logger;
            }
    
            Task<string> IHello.SayHello(string greeting)
            {
                logger.LogInformation($"
     SayHello message received: greeting = '{greeting}'");
                return Task.FromResult($"
     Client said: '{greeting}', so HelloGrain says: Hello!");
            }
        }
    }
    

    Silo – Program.cs

    using System;
    using System.Threading.Tasks;
    using Microsoft.Extensions.Logging;
    using Orleans;
    using Orleans.Configuration;
    using Orleans.Hosting;
    
    namespace OrleansBasics
    {
        public class Program
        {
            public static int Main(string[] args)
            {
                return RunMainAsync().Result;
            }
    
            private static async Task<int> RunMainAsync()
            {
                try
                {
                    var host = await StartSilo();
                    Console.WriteLine("
    
     Press Enter to terminate...
    
    ");
                    Console.ReadLine();
    
                    await host.StopAsync();
    
                    return 0;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                    return 1;
                }
            }
    
            private static async Task<ISiloHost> StartSilo()
            {
                // define the cluster configuration
                var builder = new SiloHostBuilder()
                    .UseLocalhostClustering()
                    .Configure<ClusterOptions>(options =>
                    {
                        options.ClusterId = "dev";
                        options.ServiceId = "OrleansBasics";
                    })
                    .ConfigureApplicationParts(parts => parts.AddApplicationPart(typeof(HelloGrain).Assembly).WithReferences())
                    .ConfigureLogging(logging => logging.AddConsole());
    
                var host = builder.Build();
                await host.StartAsync();
                return host;
            }
        }
    }
    

    Client – Program.cs

    using Microsoft.Extensions.Logging;
    using Orleans;
    using Orleans.Configuration;
    using System;
    using System.Threading.Tasks;
    
    namespace OrleansBasics
    {
        public class Program
        {
            static int Main(string[] args)
            {
                return RunMainAsync().Result;
            }
    
            private static async Task<int> RunMainAsync()
            {
                try
                {
                    using (var client = await ConnectClient())
                    {
                        await DoClientWork(client);
                        Console.ReadKey();
                    }
    
                    return 0;
                }
                catch (Exception e)
                {
                    Console.WriteLine($"
    Exception while trying to run client: {e.Message}");
                    Console.WriteLine("Make sure the silo the client is trying to connect to is running.");
                    Console.WriteLine("
    Press any key to exit.");
                    Console.ReadKey();
                    return 1;
                }
            }
    
            private static async Task<IClusterClient> ConnectClient()
            {
                IClusterClient client;
                client = new ClientBuilder()
                    .UseLocalhostClustering()
                    .Configure<ClusterOptions>(options =>
                    {
                        options.ClusterId = "dev";
                        options.ServiceId = "OrleansBasics";
                    })
                    .ConfigureLogging(logging => logging.AddConsole())
                    .Build();
    
                await client.Connect();
                Console.WriteLine("Client successfully connected to silo host 
    ");
                return client;
            }
    
            private static async Task DoClientWork(IClusterClient client)
            {
                // example of calling grains from the initialized client
                var friend = client.GetGrain<IHello>(0);
                var response = await friend.SayHello("Good morning, HelloGrain!");
                Console.WriteLine("
    
    {0}
    
    ", response);
            }
        }
    }
    

    Run起来:

    先启动Silo再启动Client,结果如下:

    总结

    这个例子其实就是简单的RPC调用,通过引用相同的接口组件,Client能够直接访问Server,它更贴近面向对象的编程风格。下一篇我们来讲解Actor的无锁特性。

  • 相关阅读:
    bash 复制文件
    taro 异步请求与列表渲染
    get请求带body的formdata非json实现AsyncHttpClient解决
    vue These dependencies were not found: * corejs/modules/es.array.iterator in ./node_modules/@babe
    Java HttpClient中文乱码解决
    SpringBoot参数校验及异常捕获
    MAC在Chrome安装vue插件
    HttpClient工具类(包含请求头header设置token)
    SpringBoot解决跨域
    2021 BDCI 华为零售商品识别竞赛一等奖方案分享
  • 原文地址:https://www.cnblogs.com/wswind/p/12549822.html
Copyright © 2020-2023  润新知