예제 #1
0
        private static bool ServiceIsRunning(string serviceName)
        {
            lock (_LockRunningNode)
            {
                var temp = FailOverNodes.Where(s => s.ServiceName == serviceName && (string.IsNullOrWhiteSpace(s.Address) || s.Address == "*")).SingleOrDefault();

                if (temp == null)
                {
                    return(false);
                }

                if (temp.Status == NodeStatus.Running)
                {
                    return(true);
                }

                //return FailOverNodes.Where(s => s.ServiceName == serviceName && (string.IsNullOrWhiteSpace(s.Address) || s.Address == "*")).SingleOrDefault()?.Status == NodeStatus.Running ? true : false;
            }
            return(false);
        }
예제 #2
0
        static SocketFailOverEngine()
        {
            ServicesCreated  = new List <string>();
            _LastCheckStatus = DateTime.MinValue;
            _IPAddress       = IPAddress.Any;// _IPHostEntry.AddressList[0];
            _IPEndPoint      = new IPEndPoint(_IPAddress, 11000);
            _Socket          = new Socket(_IPAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                _Socket.Bind(_IPEndPoint);
                _Socket.Listen(30);
                //_Socket.ReceiveTimeout = 10;

                FailOverResponser = Task.Factory.StartNew(() =>
                {
                    while (true)
                    {
                        byte[] bytes = new Byte[1024];
                        Socket handler;
                        try
                        {
                            handler = _Socket.Accept();
                        }
                        catch (Exception e)
                        {
                            continue;
                        }

                        try
                        {
                            int bytesRec            = handler.Receive(bytes);
                            byte[] serviceNamebytes = new Byte[1023];
                            byte code = bytes[0];
                            bytes.CopyTo(serviceNamebytes, 1);
                            string serviceName = Encoding.ASCII.GetString(bytes);
                            byte[] msg         = new byte[1];
                            // msg 100: Command Not Exist
                            // msg 101: Internal Server Error
                            // msg 0 => StandBy
                            // msg 1 => Running
                            // msg 2 => This Service Not Exist In This Node
                            switch (code)
                            {
                            // Check Status
                            case 0:
                                if (ServiceIsRunning(serviceName))
                                {
                                    msg[0] = 1;
                                }
                                else
                                {
                                    msg[0] = 0;
                                }
                                break;

                            default:
                                msg[0] = 100;
                                break;
                            }

                            handler.Send(msg);
                        }
                        catch (Exception)
                        {
                            var msg = new byte[1];
                            msg[0]  = 100;
                            handler.Send(msg);
                        }
                        finally
                        {
                            handler.Shutdown(SocketShutdown.Both);
                            handler.Close();
                        }
                    }
                });

                NodeStatusChecker = Task.Factory.StartNew(() =>
                {
                    do
                    {
                        if (_LastCheckStatus == DateTime.MinValue || _LastCheckStatus < _LastCheckStatus.AddSeconds(20))
                        {
                            lock (_LockServicesCreated)
                            {
                                foreach (var service in ServicesCreated)
                                {
                                    //var IsServiceRunning = ServiceIsRunning(service);
                                    var temp      = FailOverNodes.Where(s => s.ServiceName == service).OrderBy(s => s.Priority).ToArray();
                                    var localNode = temp.Where(s => IsLocalService(s)).SingleOrDefault();

                                    if (localNode == null)
                                    {
                                        continue;
                                    }

                                    var failOverCount = temp.Count();

                                    for (int i = 0; i < failOverCount; i++)
                                    {
                                        byte status = CheckServiceStatus(temp[i]);

                                        switch (status)
                                        {
                                        case 0:     //StandBy
                                            if (temp[i].Status != NodeStatus.StandBy)
                                            {
                                                lock (_LockRunningNode)
                                                {
                                                    temp[i].Status           = NodeStatus.StandBy;
                                                    temp[i].LastUpdateStatus = DateTime.Now;
                                                }
                                            }
                                            break;

                                        case 1:     //Running
                                            if (temp[i].Status != NodeStatus.Running)
                                            {
                                                lock (_LockRunningNode)
                                                {
                                                    temp[i].Status           = NodeStatus.Running;
                                                    temp[i].LastUpdateStatus = DateTime.Now;
                                                }
                                            }
                                            break;

                                        case 2:    //This Service Not Exist In This Node
                                        case 102:  //Not Response Recive Or Faild Check Status
                                            if (temp[i].Status != NodeStatus.Stop)
                                            {
                                                lock (_LockRunningNode)
                                                {
                                                    temp[i].Status           = NodeStatus.Stop;
                                                    temp[i].LastUpdateStatus = DateTime.Now;
                                                }
                                            }
                                            break;

                                        case 100:    //Command Not Exist
                                        case 101:    //Internal Server Error
                                        default:
                                            if (temp[i].Status != NodeStatus.Unknown)
                                            {
                                                lock (_LockRunningNode)
                                                {
                                                    temp[i].Status           = NodeStatus.Unknown;
                                                    temp[i].LastUpdateStatus = DateTime.Now;
                                                }
                                            }
                                            if (temp[i].LastUpdateStatus.AddSeconds(60) < DateTime.Now)
                                            {
                                                lock (_LockRunningNode)
                                                {
                                                    temp[i].Status           = NodeStatus.Stop;
                                                    temp[i].LastUpdateStatus = DateTime.Now;
                                                }
                                            }
                                            break;
                                        }
                                    }

                                    bool isShouldRun = false;
                                    bool isAllNodesWithUperPriorityStoped = false;
                                    for (int i = 0; i < failOverCount; i++)
                                    {
                                        if (temp[i].Status == NodeStatus.Running)
                                        {
                                            if (IsLocalService(temp[i]))
                                            {
                                                isShouldRun = true;
                                            }
                                            else
                                            {
                                                isShouldRun = false;
                                            }

                                            break;
                                        }
                                        else if (IsLocalService(temp[i]))
                                        {
                                            if (isAllNodesWithUperPriorityStoped)
                                            {
                                                isShouldRun = true;
                                            }
                                            else
                                            {
                                                isShouldRun = false;
                                            }
                                        }
                                        else if (temp[i].Status == NodeStatus.Stop)
                                        {
                                            isAllNodesWithUperPriorityStoped = true;
                                        }
                                        else if (temp[i].Status == NodeStatus.StandBy || temp[i].Status == NodeStatus.Unknown)
                                        {
                                            isAllNodesWithUperPriorityStoped = false;
                                        }
                                    }

                                    var newNodeStatus = isShouldRun ? NodeStatus.Running : NodeStatus.StandBy;
                                    if (localNode.Status != newNodeStatus)
                                    {
                                        lock (_LockRunningNode)
                                        {
                                            localNode.Status = newNodeStatus;
                                        }
                                    }
                                }
                                _LastCheckStatus = DateTime.Now;
                            }
                        }
                        Task.Delay(100).Wait();
                    } while (true);
                });
            }
            catch (Exception e)
            {
                throw new Exception($"Faild Launch FailOverEngine On { _IPEndPoint }", e);
            }
        }