示例#1
0
        private void OnChanged(ZooyardOption value, string name)
        {
            Logger().LogInformation($"{name} has changed:{ value}");
            Console.WriteLine($"{name} has changed:{ value}");

            this.Address = URL.ValueOf(value.RegisterUrl);

            foreach (var item in value.Clients)
            {
                var list = item.Value.Urls.Select(w => URL.ValueOf(w).AddParameterIfAbsent("interface", item.Value.Service.FullName)).ToList();
                //优先移除被隔离了的URL
                if (this.BadUrls.ContainsKey(item.Key))
                {
                    var removeUrls = new List <BadUrl>();
                    foreach (var badUrl in this.BadUrls[item.Key])
                    {
                        var exitsUrl = list.FirstOrDefault(w => w.ToIdentityString() == badUrl.Url.ToIdentityString());
                        if (exitsUrl == null)
                        {
                            removeUrls.Add(badUrl);
                        }
                    }
                    foreach (var url in removeUrls)
                    {
                        this.BadUrls[item.Key].Remove(url);
                    }
                }

                if (this.Urls.ContainsKey(item.Key))
                {
                    //移除注销的提供者
                    var removeUrls = new List <URL>();
                    foreach (var url in this.Urls[item.Key])
                    {
                        var exitsUrl = list.FirstOrDefault(w => w.ToIdentityString() == url.ToIdentityString());
                        if (exitsUrl == null)
                        {
                            removeUrls.Add(url);
                        }
                    }
                    foreach (var url in removeUrls)
                    {
                        this.Urls[item.Key].Remove(url);
                    }

                    //发现新的提供者
                    foreach (var i in list)
                    {
                        URL exitsUrl = null;
                        if (this.Urls.TryGetValue(item.Key, out IList <URL> urlList))
                        {
                            exitsUrl = urlList.FirstOrDefault(w => w.ToIdentityString() == i.ToIdentityString());
                        }
                        BadUrl exitsBadUrl = null;
                        if (BadUrls.TryGetValue(item.Key, out IList <BadUrl> badUrlList))
                        {
                            badUrlList.FirstOrDefault(w => w.Url.ToIdentityString() == i.ToIdentityString());
                        }
                        if (exitsUrl == null && exitsBadUrl == null)
                        {
                            this.Urls[item.Key].Add(i);
                        }
                    }
                }
                else
                {
                    this.Urls.TryAdd(item.Key, list);
                }
            }
        }
示例#2
0
        public static void AddZoolandClient(this IServiceCollection services, IConfiguration config, string zooyard = "zooyard")
        {
            services.AddSingleton <IDictionary <string, IClientPool> >((serviceProvder) =>
            {
                var option = serviceProvder.GetService <IOptionsMonitor <ZooyardOption> >().CurrentValue;
                var result = new Dictionary <string, IClientPool>();

                foreach (var item in option.Clients)
                {
                    var pool = serviceProvder.GetService(Type.GetType(item.Value.PoolType)) as IClientPool;
                    result.Add(item.Value.Service.FullName, pool);
                }
                return(result);
            });

            services.AddSingleton <ILoadBalance, ConsistentHashLoadBalance>();
            services.AddSingleton <ILoadBalance, LeastActiveLoadBalance>();
            services.AddSingleton <ILoadBalance, RandomLoadBalance>();
            services.AddSingleton <ILoadBalance, RoundRobinLoadBalance>();


            services.AddSingleton <ICluster, BroadcastCluster>();
            services.AddSingleton <ICluster, FailbackCluster>();
            services.AddSingleton <ICluster, FailfastCluster>();
            services.AddSingleton <ICluster, FailoverCluster>();
            services.AddSingleton <ICluster, FailsafeCluster>();
            services.AddSingleton <ICluster, ForkingCluster>();


            services.AddSingleton <ArrayMerger>();
            services.AddSingleton <BooleanArrayMerger>();
            services.AddSingleton <ByteArrayMerger>();
            services.AddSingleton <CharArrayMerger>();
            services.AddSingleton <DoubleArrayMerger>();
            services.AddSingleton <FloatArrayMerger>();
            services.AddSingleton <ShortArrayMerger>();
            services.AddSingleton <IntArrayMerger>();
            services.AddSingleton <LongArrayMerger>();
            services.AddSingleton(typeof(ListMerger <>));
            services.AddSingleton(typeof(DictionaryMerger <,>));
            services.AddSingleton(typeof(SetMerger <>));

            services.AddSingleton <IDictionary <Type, IMerger> >((serviceProvder) =>
            {
                var result = new Dictionary <Type, IMerger>
                {
                    { typeof(Array), serviceProvder.GetService <ArrayMerger>() },
                    { typeof(bool), serviceProvder.GetService <BooleanArrayMerger>() },
                    { typeof(byte), serviceProvder.GetService <ByteArrayMerger>() },
                    { typeof(char), serviceProvder.GetService <CharArrayMerger>() },
                    { typeof(double), serviceProvder.GetService <DoubleArrayMerger>() },
                    { typeof(float), serviceProvder.GetService <FloatArrayMerger>() },
                    { typeof(short), serviceProvder.GetService <ShortArrayMerger>() },
                    { typeof(int), serviceProvder.GetService <IntArrayMerger>() },
                    { typeof(long), serviceProvder.GetService <LongArrayMerger>() },
                    { typeof(IEnumerable <>), serviceProvder.GetService(typeof(ListMerger <>)) as IMerger },
                    { typeof(IDictionary <,>), serviceProvder.GetService(typeof(DictionaryMerger <,>)) as IMerger },
                    { typeof(ISet <>), serviceProvder.GetService(typeof(SetMerger <>)) as IMerger }
                };
                return(result);
            });
            services.AddSingleton <IDictionary <string, IMerger> >((serviceProvder) =>
            {
                var option = serviceProvder.GetService <IOptionsMonitor <ZooyardOption> >().CurrentValue;
                var result = new Dictionary <string, IMerger>();

                foreach (var item in option.Mergers)
                {
                    var merger = serviceProvder.GetService(Type.GetType(item.Value)) as IMerger;
                    result.Add(item.Key, merger);
                }
                return(result);
            });

            services.AddSingleton <MergeableCluster>();


            var caches = new Dictionary <string, Type>
            {
                { "local", typeof(LocalCache) },
                { "lru", typeof(LruCache) },
                { "threadlocal", typeof(ThreadLocalCache) },
            };

            services.AddSingleton <IZooyardPools>((serviceProvder) =>
            {
                var option      = serviceProvder.GetService <IOptionsMonitor <ZooyardOption> >();
                var clientPools = serviceProvder.GetService <IDictionary <string, IClientPool> >();

                var loadbalanceList = serviceProvder.GetServices <ILoadBalance>();
                var loadBalances    = new Dictionary <string, ILoadBalance>();
                foreach (var item in loadbalanceList)
                {
                    loadBalances.Add(item.Name, item);
                }
                ;

                var clusterList = serviceProvder.GetServices <ICluster>();
                var clusters    = new Dictionary <string, ICluster>();
                foreach (var item in clusterList)
                {
                    clusters.Add(item.Name, item);
                }

                var zooyardPools = new ZooyardPools(clientPools, loadBalances, clusters, caches, option);
                return(zooyardPools);
            });

            var optionData = new ZooyardOption();

            config.Bind(zooyard, optionData);

            foreach (var item in optionData.Clients)
            {
                var serviceType = Type.GetType(item.Value.ServiceType);
                if (serviceType == null)
                {
                    var msg = $"waring {zooyard} not find type {item.Value.ServiceType}";
                    Logger().LogWarning(msg);
                    Console.WriteLine(msg);
                    continue;
                }

                var genericType = typeof(ZooyardFactory <>);
                var factoryType = genericType.MakeGenericType(new [] { serviceType });
                services.AddSingleton(factoryType, (serviceProvder) =>
                {
                    var pools          = serviceProvder.GetService <IZooyardPools>();
                    var zooyardFactory = factoryType.GetConstructor(new[] { typeof(IZooyardPools), typeof(string), typeof(string) })
                                         .Invoke(new object[] { pools, item.Key, item.Value.Version });
                    return(zooyardFactory);
                });


                services.AddTransient(serviceType, (serviceProvder) =>
                {
                    var factory = serviceProvder.GetService(factoryType);
                    var result  = factory.GetType().GetMethod("CreateYard").Invoke(factory, null);
                    return(result);
                });
            }
        }