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); } } }
浙公网安备 33010602011771号