新文章 网摘 文章 随笔 日记

Orleans 3.1.5 使用数据库作服务发现

Silo:

using Microsoft.Extensions.Logging;
using Orleans.Configuration;
using Orleans.Hosting;
using System;
using System.Threading.Tasks;
using FabricDemo.Orleans.ServiceProvider;
using FabricDemo.Grains;
using Orleans;
using Microsoft.Extensions.Configuration;
using System.IO;
using FabricDemo.Common;
using FabricDemo.Models;
using Topshelf;

namespace FabricDemo.Silo
{
    class Program
    {
        public static IConfiguration configuration;
        private static IDbConfig dbConfig;
        static void Main(string[] args)
        {
            //创建配置
            configuration = new ConfigurationBuilder()
           .SetBasePath(Directory.GetCurrentDirectory())
           .AddJsonFile("appsettings.json", true, true)
           .AddJsonFile("appsettings.Development.json", true, true)
           .Build();

            dbConfig = configuration.GetConfig<DbConfig>("ConnectingStrings:OrleanClusterDb");
            int result;

            //使用topself运行服务
            HostFactory.Run(x =>
            {
                result = RunMainAsync().Result;
            });

            //return RunMainAsync().Result;
        }
        private static async Task<int> RunMainAsync()
        {
            try
            {
                var host = await StartSilo();
                Console.WriteLine("\n\n Press Enter to terminate...\n\n");

                var input = Console.ReadLine();
                //输入 "quit"时退出
                while (input != "quit")
                {
                    input = 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()
                .Configure<ClusterOptions>(options =>
                {
                    options.ClusterId = "Cluster42";
                    options.ServiceId = "MyAwesomeService";
                })
                .UseAdoNetClustering(options =>
                {
                    options.ConnectionString = dbConfig.ConnectionString;
                    options.Invariant = dbConfig.ProviderName;
                })
                .ConfigureEndpoints(siloPort: 11111, gatewayPort: 30000)

                //注入服务
                .ConfigureServices(services => services.AddHostServices(configuration))
                //加入晶粒
                .ConfigureApplicationParts(parts => parts.AddApplicationPart(typeof(UserGrain).Assembly).WithReferences())
                .ConfigureLogging(builder => builder.SetMinimumLevel(LogLevel.Warning).AddConsole());
            var host = builder.Build();
            await host.StartAsync();
            return host;
        }
    }
}

Soli配置appsettings.json:

{
  "ConnectingStrings": {
    //  "OrleanClusterDb": {
    //    "ConnectionStringName": "OrleanClusterDb",
    //    "ConnectionString": "server=.;database=MVCDemo;uid=sa;password=****",
    //    "ProviderName": "System.Data.SqlClient"

    //  },
    "OrleanClusterDb": {
      "ConnectionStringName": "OrleanClusterDb",
      "ConnectionString": "server=***;database=****;uid=****;pwd=****",
      "ProviderName": "System.Data.SqlClient"

    },
    //"UserServiceDb": {
    //  "ConnectionStringName": "UserServiceDb",
    //  "ConnectionString": "server=.;database=****;uid=sa;password=****",
    //  "ProviderName": "System.Data.SqlClient"
    //},
    "UserServiceDb": {
      "ConnectionStringName": "UserServiceDb",
      "ConnectionString": "server=****;database=****;uid=****;pwd=****",
      "ProviderName": "System.Data.SqlClient"
    }
  }
}

FabricDemo.Orleans.ServiceProvider:

using FabricDemo.Common;
using FabricDemo.Models;
using FabricDemo.Services.UserService;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Phoenix.Modules.Common.Infrastructure.Ado;

namespace FabricDemo.Orleans.ServiceProvider
{
    public static class HostServiceRegister
    {
        public static void AddHostServices(this IServiceCollection services, IConfiguration configuration)
        {
            //数据库配置
            //services.AddConfiguration<UserServiceDbConfig>(configuration, "ConnectingStrings:UserServiceDb");
            var userServiceDbConfig = configuration.GetConfig<DbConfig>("ConnectingStrings:UserServiceDb");
            services.AddTransient<IUserService>(x => new Services.UserService.UserService(new SqlDbHelper(userServiceDbConfig)));
        }


        public static void AddDatabases(this IServiceCollection services, IConfiguration configuration)
        {
        }
    }
}

FabricDemo.OrleanClient:

using FabricDemo.Models;
using Microsoft.Extensions.Logging;
using Orleans;
using Orleans.Configuration;
using Orleans.Hosting;
using System;
using System.Threading.Tasks;

namespace FabricDemo.OrleanClient
{
    public static class OrleanClient
    {
        public static async Task<IClusterClient> Connect(IDbConfig dbConfig)
        {
            var attempt = 0;
            var maxAttempts = 100;
            var delay = TimeSpan.FromSeconds(1);
            IClusterClient client;
            client = new ClientBuilder()
                .Configure<ClusterOptions>(options =>
                {
                    options.ClusterId = "Cluster42";
                    options.ServiceId = "MyAwesomeService";
                })
                .UseAdoNetClustering(options =>
                {
                    options.ConnectionString = dbConfig.ConnectionString;
                    options.Invariant = dbConfig.ProviderName;
                })
                .ConfigureLogging(builder => builder.SetMinimumLevel(LogLevel.Warning).AddConsole())
                .Build();
            await client.Connect(async error =>
            {
                //如果发生连接错误,执行以下重连
                if (++attempt < maxAttempts)
                {
                    Console.WriteLine($"{error.Message},Failed to connect to Orleans cluster on attempt {attempt} of {maxAttempts}.");
                    try
                    {
                        await Task.Delay(delay);
                    }
                    catch (OperationCanceledException)
                    {
                        return false;
                    }
                    return true;
                }
                else
                {
                    Console.WriteLine($"{error.Message},Failed to connect to Orleans cluster on attempt {attempt} of {maxAttempts}.");
                    return false;
                }
            });
            Console.WriteLine("Client successfully connected to silo host \n");
            return client;
        }
    }
}

 

调用:

        OrleanClusterDbConfig _orleanClusterDbConfig;
        Guid _clientId = Guid.Parse("69F0FA8A-5228-423A-A388-46676DC00EF8");

 

                using (var client = await OrleanClient.OrleanClient.Connect(_orleanClusterDbConfig))
                {
                    // 从初始化的客户端调用谷物的示例
                    //如果是销售商品,可以使用商品Id作为grain的Id传入,因为每个Id的Grain是唯一的
                    //保证了单线程
                    var userGrain = client.GetGrain<IUserGrain>(_clientId);
                    var userProfile = await userGrain.GetUserProfileAsync(id);
                    if (userProfile == null)
                    {
                        return Ok("用户不存在");
                    }
                    else
                    {
                        return Ok(userProfile);
                    }

                }

Model:

IDbConfig:

namespace FabricDemo.Models
{
    public interface IDbConfig
    {
        string ConnectionStringName { get; }
        string ConnectionString { get; }
        string ProviderName { get; }

    }
}

DbConfig:

namespace FabricDemo.Models
{
    public class DbConfig : IDbConfig
    {
        public string ConnectionStringName { get; set; }
        public string ConnectionString { get; set; }
        public string ProviderName { get; set; }
    }
}

IOrleanClusterDbConfig:

namespace FabricDemo.Models
{
    public interface IOrleanClusterDbConfig : IDbConfig
    {
    }
}
IUserServiceDbConfig :
namespace FabricDemo.Models
{
    public interface IUserServiceDbConfig : IDbConfig
    {
    }
}

OrleanClusterDbConfig:

namespace FabricDemo.Models
{
    public class OrleanClusterDbConfig : DbConfig, IOrleanClusterDbConfig
    {
        public OrleanClusterDbConfig() : base()
        {

        }
    }
}

UserServiceDbConfig:

namespace FabricDemo.Models
{
    public class UserServiceDbConfig : DbConfig, IUserServiceDbConfig
    {
        public UserServiceDbConfig() : base()
        {
        }
    }
}

依赖注入:

            //注入服務 
            // OrleanClusterDbConfig orleanClusterDbConfig = new OrleanClusterDbConfig();
            services.AddConfiguration<OrleanClusterDbConfig>(Configuration,"ConnectingStrings:OrleanClusterDb");

 Grains:

using FabricDemo.Models;
using Orleans;
using System;
using System.Threading.Tasks;

namespace FabricDemo.IGrains
{
    public interface IUserGrain : IGrainWithGuidKey
    {
        Task<UserModel> GetUserProfileAsync(Guid userId);
    }
}
using FabricDemo.IGrains;
using FabricDemo.Models;
using FabricDemo.Services.UserService;
using Orleans;
using System;
using System.Threading.Tasks;

namespace FabricDemo.Grains
{
    public class UserGrain : Grain, IUserGrain
    {
        private readonly IUserService _userService;
        public UserGrain(IUserService userService)
        {
            _userService = userService;
        }
        public async Task<UserModel> GetUserProfileAsync(Guid userId)
        {
           return await _userService.GetUserProfile(userId);
        }
    }
}

 

posted @ 2020-10-08 15:55  岭南春  阅读(157)  评论(0)    收藏  举报