예제 #1
0
        /// <summary>
        /// 加载节点
        /// </summary>
        /// <param name="input">"name=dc1,ip=192.168.X.X,port=6659,timeout=3000,weight=5"</param>
        public bool Add(Dictionary <string, string> input)
        {
            lock (LockAdd)
            {
                try
                {
                    var ip = GetValidIp(input["ip"], Convert.ToInt32(input["port"]));
                    if (ip == string.Empty)
                    {
                        return(false);
                    }
                    ServiceInfo ips = new ServiceInfo
                    {
                        Timeout  = input["timeout"] == null ? TimeOut : Convert.ToInt32(input["timeout"]),
                        Name     = input["name"],
                        NickName = input["nickname"],
                        Ip       = ip,
                        Port     = Convert.ToInt32(input["port"])
                    };
                    int weight = input["weight"] == null ? 1 : (int)Convert.ToDecimal(input["weight"]);
                    ips.Weight = weight;
                    #region 原有服务
                    var oldService = ServiceInfoList.FirstOrDefault(t => ips.Ip == t.Ip && ips.Port == t.Port);
                    #endregion

                    ServiceInfoList.RemoveAll(t => ips.Ip == t.Ip && ips.Port == t.Port);
                    for (int w = 0; w < weight; w++) //权重
                    {
                        ServiceInfoList.Add(ips);
                    }

                    Log.WriteLine($"{ips.Ip}:{ips.Port}", ConsoleColor.DarkGreen);
                    ips.Name.Split(',').ToList().ForEach(f =>
                    {
                        Log.WriteLine($"{f}", ConsoleColor.DarkGreen);
                    });
                    Log.WriteLine($"{"权重:" + ips.Weight}", ConsoleColor.DarkGreen);
                    Log.WriteLine($"{ips.NickName}已登记!", ConsoleColor.DarkGreen);
                    Log.WriteLineNoDate($"-----------------------------------------------------------------------------");
                    #region  线和变更通知
                    if (OnlineNotice != null && oldService == null)
                    {
                        OnlineNotice.Invoke(ips, NoticeType.OnLine);
                    }
                    else if (ChangeNotice != null && oldService != null)
                    {
                        ChangeNotice.Invoke(ips, oldService);
                    }
                    #endregion
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                    return(false);
                }
                finally
                {
                    Save();
                }
            }
            return(true);
        }
예제 #2
0
        /// <summary>
        /// 健康检查,如果连接不上 每秒做一次尝试。
        /// 尝试 errorCount 次失败,软删除。
        /// 60次失败,永久删除。
        /// </summary>
        /// <param name="service">被检测主机信息</param>
        /// <param name="errorCount">尝试 errorCount 次失败,软删除</param>
        /// <returns></returns>
        public static void HealthCheck(ServiceInfo service, int errorCount = 3)
        {
            int hc = 60; //检查次数

hCheck:                  //再次  心跳检测
            TTransport transport = new TSocket(service.Ip, service.Port, 3000);

            try
            {
                service.Checking = true;
                transport.Open();
                if (transport.IsOpen)
                {
                    if (hc != 60)
                    {
                        Console.ForegroundColor = ConsoleColor.DarkGreen;
                        Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}: ");
                        Console.WriteLine($"{service.Ip}:{service.Port}");
                        foreach (var f in service.Name.Split(','))
                        {
                            Console.WriteLine($"{f}");
                        }
                        Console.WriteLine($"{"w:" + service.Weight}");
                        Console.WriteLine($"恢复正常!");
                        Console.ResetColor();
                        Console.WriteLine($"----------------------------------------------------------------- ");
                    }
                    if (hc <= (60 - errorCount))
                    {
                        CheckNotice?.Invoke(service, NoticeType.RecoverHealth);
                    }
                    transport.Flush();
                    transport.Close();
                    lock (LockHelper) //防止高并发下 影响权重
                    {
                        if (!Tc.ServiceInfoList.Exists(s => s.Ip == service.Ip && s.Port == service.Port))
                        {
                            //已存在不再添加 不存在则添加
                            for (int i = 0; i < service.Weight; i++)
                            {
                                Tc.ServiceInfoList.Add(service);
                            }
                        }
                    }
                }

                transport.Dispose();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error Info:{service.Ip}:{service.Port} {ex.Message}");
                if (hc == 60)
                {
                    Console.ForegroundColor = ConsoleColor.DarkYellow;
                    Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}: ");
                    Console.WriteLine($"{service.Ip}:{service.Port}");
                    foreach (var f in service.Name.Split(','))
                    {
                        Console.WriteLine($"{f}");
                    }
                    Console.WriteLine($"{"w:" + service.Weight}");
                    Console.WriteLine($"检测中···{hc}!");
                    Console.ResetColor();
                    Console.WriteLine($"----------------------------------------------------------------- ");
                }
                else if (hc == (60 - errorCount))
                {
                    Console.ForegroundColor = ConsoleColor.DarkYellow;
                    Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}: ");
                    Console.WriteLine($"{service.Ip}:{service.Port}");
                    foreach (var f in service.Name.Split(','))
                    {
                        Console.WriteLine($"{f}");
                    }
                    Console.WriteLine($"{"w:" + service.Weight}");
                    Console.WriteLine($"故障恢复中···{hc}!");
                    Console.ResetColor();
                    Console.WriteLine($"----------------------------------------------------------------- ");
                }
                else if (hc == 0) //硬删除
                {
                    Console.ForegroundColor = ConsoleColor.DarkRed;
                    Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}:");
                    Console.WriteLine($"{service.Ip}:{service.Port}");
                    foreach (var f in service.Name.Split(','))
                    {
                        Console.WriteLine($"{f}");
                    }
                    Console.WriteLine($"{"w:" + service.Weight}");
                    Console.WriteLine($"永久移除!");
                    Console.ResetColor();
                    Console.WriteLine($"----------------------------------------------------------------- ");
                    CheckNotice?.Invoke(service, NoticeType.OffLine);
                }

                if (hc == (60 - errorCount)) //三次失败之后 临时移除 ,防止更多请求转发给此服务节点
                {
                    //临时移除 并不从配置文件移除
                    Tc.ServiceInfoList.RemoveAll(i => i.Ip == service.Ip && i.Port == service.Port);
                    CheckNotice?.Invoke(service, NoticeType.NotHealth);
                }
                else if (hc == 0) //硬删除
                {
                    Dictionary <string, string> rp = new Dictionary <string, string>
                    {
                        { "ip", service.Ip },
                        { "port", service.Port.ToString() }
                    };
                    Tc.Remove(rp);
                    return;
                }

                Thread.Sleep(1000); //间隔一秒 健康检查
                hc--;
                transport.Dispose();
                goto hCheck;
            }
            finally
            {
                if (transport.IsOpen)
                {
                    transport.Flush();
                    transport.Close();
                }
                transport.Dispose();
                service.Checking = false;
            }
        }
예제 #3
0
        /// <summary>
        /// 变更服务信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public bool ChangeMicroServiceWeight(Dictionary <string, string> input)
        {
            lock (LockAdd)
            {
                try
                {
                    if (!input.ContainsKey("ip") || !input.ContainsKey("port") || (!input.ContainsKey("weight") && !input.ContainsKey("timeout")))
                    {
                        return(false);
                    }
                    var ip = input["ip"];
                    int.TryParse(input["port"], out int port);
                    var hasWeight = false;
                    int weight    = 0;
                    int timeout   = 0;
                    if (input.ContainsKey("weight"))
                    {
                        hasWeight = int.TryParse(input["weight"], out weight);
                    }
                    var hasTimeOut = false;
                    if (input.ContainsKey("timeout"))
                    {
                        hasTimeOut = int.TryParse(input["timeout"], out timeout);
                    }
                    #region 原有服务
                    var oldService = ServiceInfoList.FirstOrDefault(t => ip == t.Ip && port == t.Port);
                    if (oldService == null)
                    {
                        return(false);
                    }
                    #endregion
                    ServiceInfo serviceInfo = new ServiceInfo()
                    {
                        Timeout  = oldService.Timeout,
                        Name     = oldService.Name,
                        NickName = oldService.NickName,
                        Ip       = oldService.Ip,
                        Port     = oldService.Port,
                        Weight   = oldService.Weight
                    };
                    if (hasTimeOut)
                    {
                        serviceInfo.Timeout = timeout;
                    }
                    if (hasWeight)
                    {
                        serviceInfo.Weight = weight;
                    }

                    ServiceInfoList.RemoveAll(t => ip == t.Ip && port == t.Port);

                    for (int w = 0; w < weight; w++) //权重
                    {
                        ServiceInfoList.Add(serviceInfo);
                    }

                    /*
                     * 至少保留一条服务信息数据
                     */
                    if (weight <= 0)
                    {
                        ServiceInfoList.Add(serviceInfo);
                    }

                    StringBuilder stringBuilder = new StringBuilder();
                    stringBuilder.AppendLine($"{serviceInfo.Ip}:{serviceInfo.Port}");
                    foreach (var f in serviceInfo.Name.Split(','))
                    {
                        stringBuilder.AppendLine($"{f}");
                    }
                    stringBuilder.AppendLine($"{"权重:" + serviceInfo.Weight}");
                    stringBuilder.AppendLine($"{serviceInfo.NickName}已登记!");
                    Log.Anno(stringBuilder.ToString(), typeof(ThriftConfig));

                    #region  线和变更通知
                    if (ChangeNotice != null && oldService != null)
                    {
                        ChangeNotice.Invoke(serviceInfo, oldService);
                    }
                    #endregion
                }
                catch (Exception ex)
                {
                    Log.Anno(ex, typeof(ThriftConfig));
                    return(false);
                }
                finally
                {
                    Save();
                }
            }
            return(true);
        }
예제 #4
0
        /// <summary>
        /// 加载节点
        /// </summary>
        /// <param name="input">"name=dc1,ip=192.168.X.X,port=6659,timeout=3000,weight=5"</param>
        public bool Add(Dictionary <string, string> input)
        {
            lock (LockAdd)
            {
                try
                {
                    var ip = GetValidIp(input["ip"], Convert.ToInt32(input["port"]));
                    if (ip == string.Empty)
                    {
                        return(false);
                    }
                    ServiceInfo ips = new ServiceInfo
                    {
                        Timeout  = input["timeout"] == null ? TimeOut : Convert.ToInt32(input["timeout"]),
                        Name     = input["name"],
                        NickName = input["nickname"],
                        Ip       = ip,
                        Port     = Convert.ToInt32(input["port"])
                    };
                    int weight = input["weight"] == null ? 1 : (int)Convert.ToDecimal(input["weight"]);
                    ips.Weight = weight;
                    #region 原有服务
                    var oldService = ServiceInfoList.FirstOrDefault(t => ips.Ip == t.Ip && ips.Port == t.Port);
                    #endregion

                    ServiceInfoList.RemoveAll(t => ips.Ip == t.Ip && ips.Port == t.Port);
                    for (int w = 0; w < weight; w++) //权重
                    {
                        ServiceInfoList.Add(ips);
                    }

                    StringBuilder stringBuilder = new StringBuilder();
                    stringBuilder.AppendLine($"{ips.Ip}:{ips.Port}");
                    foreach (var f in ips.Name.Split(','))
                    {
                        stringBuilder.AppendLine($"{f}");
                    }
                    stringBuilder.AppendLine($"{"权重:" + ips.Weight}");
                    stringBuilder.AppendLine($"{ips.NickName}已登记!");
                    Log.Anno(stringBuilder.ToString(), typeof(ThriftConfig));

                    #region  线和变更通知
                    if (OnlineNotice != null && oldService == null)
                    {
                        OnlineNotice.Invoke(ips, NoticeType.OnLine);
                    }
                    else if (ChangeNotice != null && oldService != null)
                    {
                        ChangeNotice.Invoke(ips, oldService);
                    }
                    #endregion
                }
                catch (Exception ex)
                {
                    Log.Anno(ex, typeof(ThriftConfig));
                    return(false);
                }
                finally
                {
                    Save();
                }
            }
            return(true);
        }
예제 #5
0
        /// <summary>
        /// 加载节点
        /// </summary>
        /// <param name="input">"name=dc1,ip=192.168.X.X,port=6659,timeout=3000,weight=5"</param>
        public bool Add(Micro input)
        {
            lock (LockAdd)
            {
                try
                {
                    var ip = GetValidIp(input.Ip, input.Port);
                    if (ip == string.Empty)
                    {
                        return(false);
                    }
                    ServiceInfo ips = new ServiceInfo
                    {
                        Timeout  = input.Timeout,
                        Name     = input.Name,
                        NickName = input.Nickname,
                        Ip       = ip,
                        Port     = input.Port
                    };
                    int weight = input.Weight <= 0 ? 1 : input.Weight;
                    ips.Weight = weight;
                    #region  线和变更通知
                    var oldService = ServiceInfoList.FirstOrDefault(t => ips.Ip == t.Ip && ips.Port == t.Port);
                    if (OnlineNotice != null && oldService == null)
                    {
                        OnlineNotice.Invoke(ips, NoticeType.OnLine);
                    }
                    else if (ChangeNotice != null && oldService != null)
                    {
                        ChangeNotice.Invoke(ips, oldService);
                    }
                    #endregion
                    ServiceInfoList.RemoveAll(t => ips.Ip == t.Ip && ips.Port == t.Port);
                    for (int w = 0; w < weight; w++) //权重
                    {
                        ServiceInfoList.Add(ips);
                    }

                    Console.ForegroundColor = ConsoleColor.DarkGreen;
                    Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
                    Console.WriteLine($"{ips.Ip}:{ips.Port}");
                    ips.Name.Split(',').ToList().ForEach(f =>
                    {
                        Console.WriteLine($"{f}");
                    });
                    Console.WriteLine($"{"w:" + ips.Weight}");
                    Console.WriteLine($"{ips.NickName}已登记!");
                    Console.ResetColor();
                    Console.WriteLine($"----------------------------------------------------------------- ");
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                    return(false);
                }
                finally
                {
                    Save();
                }
            }
            return(true);
        }
예제 #6
0
        /// <summary>
        /// 健康检查,如果连接不上 每秒做一次尝试。
        /// 尝试 errorCount 次失败,软删除。
        /// 60次失败,永久删除。
        /// </summary>
        /// <param name="service">被检测主机信息</param>
        /// <param name="errorCount">尝试 errorCount 次失败,软删除</param>
        /// <returns></returns>
        public static void HealthCheck(ServiceInfo service, int errorCount = 3)
        {
            try
            {
                int hc = 60;//检查次数
                service.Checking = true;
                while (hc > 0)
                {
                    var client = new BrokerService.BrokerServiceClient(new Channel($"{service.Ip}:{service.Port}", ChannelCredentials.Insecure));
                    if (Alive(client))
                    {
                        if (hc == 60)
                        {
                            break;
                        }
                        else
                        {
                            if (hc < (60 - errorCount))
                            {
                                WriteHealthCheck(service, hc, "恢复正常");
                            }
                            if (service.IsTemporaryRemove) //如果服务已被临时移除则找回
                            {
                                lock (LockHelper)          //防止高并发下 影响权重
                                {
                                    if (!Tc.ServiceInfoList.Exists(s => s.Ip == service.Ip && s.Port == service.Port))
                                    {
                                        //已存在不再添加 不存在则添加
                                        for (int i = 0; i < service.Weight; i++)
                                        {
                                            Tc.ServiceInfoList.Add(service);
                                        }
                                    }
                                }
                                CheckNotice?.Invoke(service, NoticeType.RecoverHealth);
                            }
                        }
                        break;
                    }
                    else
                    {
                        hc--;
                        if (hc < (60 - errorCount) && (hc % errorCount == 0))
                        {
                            Log.Anno($"Error Info:{service.Ip}:{service.Port} not alive {hc}", typeof(Distribute));
                        }
                        if (hc == (60 - errorCount))//三次失败之后 临时移除 ,防止更多请求转发给此服务节点
                        {
                            //临时移除 并不从配置文件移除
                            Tc.ServiceInfoList.RemoveAll(i => i.Ip == service.Ip && i.Port == service.Port);
                            service.IsTemporaryRemove = true;
                            CheckNotice?.Invoke(service, NoticeType.NotHealth);

                            WriteHealthCheck(service, hc, "故障恢复中");
                        }
                        else if (hc == 0) //硬删除
                        {
                            Dictionary <string, string> rp = new Dictionary <string, string>
                            {
                                { "ip", service.Ip },
                                { "port", service.Port.ToString() }
                            };
                            Tc.Remove(rp);
                            CheckNotice?.Invoke(service, NoticeType.OffLine);

                            WriteHealthCheck(service, hc, "永久移除");
                            break;
                        }
                        Task.Delay(1000).Wait();//间隔一秒 健康检查
                    }
                }
            }
            finally
            {
                service.Checking = false;
            }
        }
예제 #7
0
        /// <summary>
        /// 健康检查,如果连接不上 每秒做一次尝试。
        /// 尝试 errorCount 次失败,软删除。
        /// 60次失败,永久删除。
        /// </summary>
        /// <param name="service">被检测主机信息</param>
        /// <param name="errorCount">尝试 errorCount 次失败,软删除</param>
        /// <returns></returns>
        public static void HealthCheck(ServiceInfo service, int errorCount = 3)
        {
            int hc = 60; //检查次数

hCheck:                  //再次  心跳检测
            var client = new BrokerService.BrokerServiceClient(new Channel($"{service.Ip}:{service.Port}", ChannelCredentials.Insecure));

            try
            {
                service.Checking = true;
                if (!client.Ping(new Empty()).Reply)
                {
                    if (hc != 60)
                    {
                        Console.ForegroundColor = ConsoleColor.DarkGreen;
                        Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}: ");
                        Console.WriteLine($"{service.Ip}:{service.Port}");
                        Console.WriteLine($"{service.Name}");
                        foreach (var f in service.Name.Split(','))
                        {
                            Console.WriteLine($"{f}");
                        }
                        Console.WriteLine($"{"w:" + service.Weight}");
                        Console.WriteLine($"恢复正常!");
                        Console.ResetColor();
                        Console.WriteLine($"----------------------------------------------------------------- ");
                    }
                    lock (LockHelper) //防止高并发下 影响权重
                    {
                        if (!Tc.ServiceInfoList.Exists(s => s.Ip == service.Ip && s.Port == service.Port))
                        {
                            //已存在不再添加 不存在则添加
                            for (int i = 0; i < service.Weight; i++)
                            {
                                Tc.ServiceInfoList.Add(service);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error Info:{service.Ip}:{service.Port} {ex.Message}");
                if (hc == 60)
                {
                    Console.ForegroundColor = ConsoleColor.DarkYellow;
                    Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}: ");
                    Console.WriteLine($"{service.Ip}:{service.Port}");
                    foreach (var f in service.Name.Split(','))
                    {
                        Console.WriteLine($"{f}");
                    }
                    Console.WriteLine($"{"w:" + service.Weight}");
                    Console.WriteLine($"检测中···{hc}!");
                    Console.ResetColor();
                    Console.WriteLine($"----------------------------------------------------------------- ");
                }
                else if (hc == (60 - errorCount))
                {
                    Console.ForegroundColor = ConsoleColor.DarkYellow;
                    Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}: ");
                    Console.WriteLine($"{service.Ip}:{service.Port}");
                    foreach (var f in service.Name.Split(','))
                    {
                        Console.WriteLine($"{f}");
                    }
                    Console.WriteLine($"{"w:" + service.Weight}");
                    Console.WriteLine($"故障恢复中···{hc}!");
                    Console.ResetColor();
                    Console.WriteLine($"----------------------------------------------------------------- ");
                }
                else if (hc == 0) //硬删除
                {
                    Console.ForegroundColor = ConsoleColor.DarkRed;
                    Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}:");
                    Console.WriteLine($"{service.Ip}:{service.Port}");
                    foreach (var f in service.Name.Split(','))
                    {
                        Console.WriteLine($"{f}");
                    }
                    Console.WriteLine($"{"w:" + service.Weight}");
                    Console.WriteLine($"永久移除!");
                    Console.ResetColor();
                    Console.WriteLine($"----------------------------------------------------------------- ");
                }

                if (hc == (60 - errorCount)) //三次失败之后 临时移除 ,防止更多请求转发给此服务节点
                {
                    //临时移除 并不从配置文件移除
                    Tc.ServiceInfoList.RemoveAll(i => i.Ip == service.Ip && i.Port == service.Port);
                }
                else if (hc == 0) //硬删除
                {
                    Dictionary <string, string> rp = new Dictionary <string, string>
                    {
                        { "ip", service.Ip },
                        { "port", service.Port.ToString() }
                    };
                    Tc.Remove(rp);
                    return;
                }

                Thread.Sleep(1000); //间隔一秒 健康检查
                hc--;
                goto hCheck;
            }
            finally
            {
                service.Checking = false;
            }
        }