Example #1
0
        /// <summary>
        /// 消息接收事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private static void ConsumerOnReceived(object sender, BasicDeliverEventArgs args)
        {
            try
            {
                //获取消息
                byte[] body = args?.Body;


                if (body == null || body.Length == 0)
                {
                    NLogHelper.Warn($"接收到空消息");
                    return;
                }

                RMqMessage msg = new RMqMessage()
                {
                    Id           = Guid.NewGuid().ToString(),
                    ContentBytes = body,
                    CreateTime   = DateTime.Now
                };

                RMqMessageHandler.Add(msg);
            }
            catch (Exception e)
            {
                NLogHelper.Error($"mq处理消息失败:{e}");
            }
        }
        ///// <summary>
        ///// 移除一个数据项,移除之前会阻塞
        ///// 返回移除的数据项
        ///// </summary>
        ///// <returns></returns>
        //public T Take()
        //{
        //    return _blockingQueue.Take();
        //}

        ///// <summary>
        ///// 尝试移除一个数据项,成功移除返回true
        /////
        ///// </summary>
        ///// <param name="item"></param>
        ///// <param name="milliseconds">等待的毫秒数,或为 Infinite (-1),表示无限期等待。</param>
        ///// <returns></returns>
        //public bool TryTake(out T item,int milliseconds)
        //{
        //    return _blockingQueue.TryTake(out item, milliseconds);
        //}

        /// <summary>
        /// 停止
        /// </summary>
        public void Stop()
        {
            DateTime now = DateTime.Now;

            int       i       = 0;
            const int sleepMs = 7;//休眠时间毫秒

            while (UnHandleCount > 0)
            {
                Thread.Sleep(sleepMs);

                i++;
                if ((DateTime.Now - now).TotalSeconds > 0.93 || i * sleepMs > 1111)
                {
                    NLogHelper.Warn($"BlockingQueue存在约{UnHandleCount}条数据未处理完成");
                    break;
                }
            }

            _isRunning = false;
            //if (_blockingQueue != null)
            //{
            //    //没有必要dispose,因为程序退出
            //    //_blockingQueue.Dispose();
            //}
        }
        /// <summary>
        /// socket回调
        /// </summary>
        /// <param name="state"></param>
        private static void SocketTimerCallBack(object state)
        {
            lock (locker)
            {
                if (isRunning)
                {
                    return;
                }

                isRunning = true;
            }

            try
            {
                if (!SocketClientProxy.IsConnected)
                {
                    NLogHelper.Warn("重启socket客户端");
                    SocketClientProxy.Start();
                }
            }
            catch (Exception ex)
            {
                NLogHelper.Error("socket监控定时器异常:" + ex);
            }
            finally
            {
                lock (locker)
                {
                    isRunning = false;
                }
            }
        }
Example #4
0
 /// <summary>
 /// 连接恢复成功
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="eventArgs"></param>
 private static void ConnectionOnRecoverySucceeded(object sender, EventArgs eventArgs)
 {
     //lock (SLocker)
     //{
     //    _isAlive = true;
     //}
     NLogHelper.Warn($"OnRecoverySucceeded");
 }
 /// <summary>
 /// 连接重建事件
 /// </summary>
 private static void ConnectionOnConnectionResumedListener()
 {
     lock (locker)
     {
         _isAlive = true;
     }
     NLogHelper.Warn("ConnectionOnConnectionResumedListener连接恢复");
 }
        /// <summary>
        /// 连接关闭
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="shutdownEventArgs"></param>
        private static void ConnectionOnConnectionShutdown(object sender, ShutdownEventArgs shutdownEventArgs)
        {
            lock (SLocker)
            {
                _isAlive = false;
            }

            NLogHelper.Warn($"OnConnectionShutdown:{shutdownEventArgs?.Cause}");
        }
Example #7
0
        /// <summary>
        /// 连接关闭
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="shutdownEventArgs"></param>
        private static void ConnectionOnConnectionShutdown(object sender, ShutdownEventArgs shutdownEventArgs)
        {
            //lock (SLocker)
            //{
            //    _isAlive = false;
            //}

            NLogHelper.Warn($"OnConnectionShutdown");
        }
Example #8
0
        /// <summary>
        /// 连接恢复失败
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="connectionRecoveryErrorEventArgs"></param>
        private static void ConnectionOnConnectionRecoveryError(object sender, ConnectionRecoveryErrorEventArgs connectionRecoveryErrorEventArgs)
        {
            //lock (SLocker)
            //{
            //    _isAlive = false;
            //}

            NLogHelper.Warn($"OnConnectionRecoveryError:{connectionRecoveryErrorEventArgs?.Exception}");
        }
Example #9
0
        public void Execute(IJobExecutionContext context)
        {
            lock (locker)
            {
                if (_isRunning)
                {
                    return;
                }
                _isRunning = true;
            }

            try
            {
                if (!Directory.Exists(BackUpDir))
                {
                    Directory.CreateDirectory(BackUpDir);
                }

                //数据库名
                string dbName = EfDbContext.DbName;

                //要备份的数据库名
                string dbBackName = dbName + "_" + DateTime.Now.ToString("yyyyMMdd") + ".bak";
                //数据库全路径
                string dbFullPath = Path.Combine(BackUpDir, dbBackName);

                if (File.Exists(dbFullPath))
                {
                    //已经存在
                    NLogHelper.Warn($"数据库备份{dbFullPath}已经存在,本次备份放弃");
                    //已经存在
                    return;
                }

                string backupSql = string.Format(BackUpSql, dbName, dbFullPath);

                //不能在事务调用
                //路径中的目录必须存在,否则抛异常
                EfDbContext.ExecuteRawNonQuery(backupSql);
            }
            catch (Exception ex)
            {
                Log4netHelper.Error("备份数据库失败:" + ex);
            }
            finally
            {
                lock (locker)
                {
                    _isRunning = false;
                }
            }
        }
        /// <summary>
        /// MQ回调
        /// </summary>
        /// <param name="state"></param>
        private static void MQTimerCallBack(object state)
        {
            lock (locker)
            {
                if (_isRunning)
                {
                    return;
                }
                _isRunning = true;
            }

            try
            {
                if (!MQConsumer.IsAlive())
                {
                    Thread.Sleep(5500);
                    //延迟5s,使其能够自动恢复
                    if (!MQConsumer.IsAlive())
                    {
                        if (_isFirstTimeToStartMq)
                        {
                            _isFirstTimeToStartMq = false;

                            NLogHelper.Debug("首次尝试启动MQConsumer");
                            MQConsumer.InitConsumer();
                        }
                        else
                        {
                            NLogHelper.Warn("MQ异常,尝试重启 MQConsumer");
                            MQConsumer.InitConsumer();
                        }
                    }
                }
                else
                {
                    NLogHelper.Trace("检测MQ连接正常");
                }
            }
            catch (Exception ex)
            {
                NLogHelper.Error("MQ定时器异常:" + ex);
            }
            finally
            {
                lock (locker)
                {
                    _isRunning = false;
                }
            }
        }
        /// <summary>
        /// 注:该方法将定期按时执行,
        /// 意味着如果下一个周期到来,而上一次执行未完成,该方法开启一个新线程执行
        ///
        /// 在方法内部使用try/catch捕获所有异常
        /// </summary>
        /// <param name="context"></param>
        public void Execute(IJobExecutionContext context)
        {
            lock (_locker)
            {
                if (_isRunning)
                {
                    return;
                }
                _isRunning = true;
            }

            string jobName = string.Empty;

            try
            {
                jobName = GetType().Name;

                //获取当前进程 dispose不会关闭程序,但是会释放资源
                using (Process currentProcess = Process.GetCurrentProcess())
                {
                    //win98或win me不支持 获取当前进程分配的物理内存
                    long   workset64   = currentProcess.WorkingSet64;
                    double worksetInMb = workset64 / 1024.0 / 1024.0;

                    if (worksetInMb > MaxMemoryCanUseInMb)
                    {
                        NLogHelper.Warn(
                            $"进程{currentProcess.ProcessName}占用内存较大,约{worksetInMb.ToString("F1", CultureInfo.CurrentCulture)}Mb");
                        ErrorCode   = 1;
                        ErrorReason = $"进程{currentProcess.ProcessName}占用内存较大,建议检查或者重启该程序";
                    }
                    else
                    {
                        ErrorCode   = 0;
                        ErrorReason = string.Empty;
                    }
                }
            }
            catch (Exception ex)
            {
                NLogHelper.Error($"执行任务{jobName}异常:" + ex);
            }
            finally
            {
                lock (_locker)
                {
                    _isRunning = false;
                }
            }
        }
        public static void Main(string[] args)
        {
            //红黑树
            SortedDictionary <string, string> rbTree = new SortedDictionary <string, string>();

            DirectoryHold.ResetCurrentDir();
            NLogHelper.Info(GuidUtils.GetGuid32());
            NLogHelper.Trace("Trace");
            NLogHelper.Debug("Debug");
            NLogHelper.Info("Info");
            NLogHelper.Warn("Warn");
            NLogHelper.Error("Error");
            NLogHelper.Fatal("Fatal");
        }
        /// <summary>
        /// MQ回调
        /// </summary>
        /// <param name="state"></param>
        private static void MQTimerCallBack(object state)
        {
            lock (locker)
            {
                if (isRunning)
                {
                    return;
                }
                isRunning = true;
            }

            try
            {
                if (!MQLongConnectionProducer.IsAlive())
                {
                    //延迟5s,使其能够自动恢复
                    Thread.Sleep(5500);

                    if (!MQLongConnectionProducer.IsAlive())
                    {
                        if (_isFirstTimeToStartMq)
                        {
                            _isFirstTimeToStartMq = false;

                            NLogHelper.Debug("首次尝试启动MQProducer");
                            MQLongConnectionProducer.StartProducer();
                        }
                        else
                        {
                            NLogHelper.Warn("重启MQProducer");
                            MQLongConnectionProducer.StartProducer();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                NLogHelper.Error("MQProducer定时器异常:" + ex);
            }
            finally
            {
                lock (locker)
                {
                    isRunning = false;
                }
            }
        }
        /// <summary>
        /// 添加到消息队列
        /// </summary>
        /// <param name="message"></param>
        public static void AddToQueue(CommonMessage message)
        {
            try
            {
                if (message == null)
                {
                    return;
                }

                #region 避免queue内存溢出

                int curCount = MessageQueue.Count;

                if (curCount > MaxNumberDataInQueue)
                {
                    CommonMessage delMsg = null;

                    for (int i = 0; i < 5; i++)
                    {
                        if (MessageQueue.TryTake(out delMsg))
                        {
                            NLogHelper.Warn($"丢弃消息:{delMsg}");
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                #endregion

                MessageQueue.Add(message);
            }
            catch
            {
                //没有必要异常处理
            }
        }
        /// <summary>
        /// 不是在UI线程上执行的
        /// 接收到数据的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="serialDataReceivedEventArgs"></param>
        private void SerialPortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
        {
            try
            {
                lastCommunicateTime = DateTime.Now;

                SerialPort port = sender as SerialPort;

                if (port == null)
                {
                    NLogHelper.Warn("参数sender转换为SerialPort为null,可能出错了");
                    return;
                }

                int readCount = 0;
                lock (locker)
                {
                    //No bytes were available to read. 将会抛出TimeoutException,真的会等待readTimeout时间
                    //Thread.Sleep(50);//等待一会read可以读取所有的数据
                    readCount = port.Read(readBuffer, 0, readBuffer.Length);
                    if (readCount > 0)
                    {
                        for (int i = 0; i < readCount; i++)
                        {
                            readList.Add(readBuffer[i]);
                        }
                    }

                    //解析字符列表
                    ParseBytes(readList);
                }
            }
            catch (Exception ex)
            {
                NLogHelper.Error($"接收数据DataReceived出错:{ex}");
            }
        }
        public void Execute(IJobExecutionContext context)
        {
            lock (Slocker)
            {
                if (_isRunning)
                {
                    return;
                }

                _isRunning    = true;
                _isRestarting = true;
            }
            string jobName = "";

            try
            {
                jobName = GetType().Name;

                #region 延时重启

                Random random = new Random();
                //每次休眠时间
                const int sleepInterval = 100;
                int       totalSleepMs  = random.Next(11000, 19000);

                //i<1000是为了避免循环次数过大
                for (int i = 0; i *sleepInterval < totalSleepMs && i < 1000; i++)
                {
                    try
                    {
                        Thread.Sleep(sleepInterval);
                    }
                    catch
                    {
                        // ignored
                    }
                }

                #endregion


                //重启
                RestartHelper.Restart(failAction: failReason =>
                {
                    NLogHelper.Error($"自动重启失败:{failReason?.Description},exception={failReason?.Exception}");
                }, successAction: () =>
                {
                    //成功处理
                    // TODO

                    NLogHelper.Warn($"自动重启成功");
                }, logAction: str =>
                {
                    NLogHelper.Warn($"自动重启日志:{str}");
                });
            }
            catch (Exception e)
            {
                NLogHelper.Error($"执行任务{jobName}失败:{e}");
            }
            finally
            {
                lock (Slocker)
                {
                    _isRunning    = false;
                    _isRestarting = false;
                }
            }
        }
Example #17
0
 /// <summary>
 /// 连接畅通
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="eventArgs"></param>
 private static void ConnectionOnConnectionUnblocked(object sender, EventArgs eventArgs)
 {
     NLogHelper.Warn($"OnConnectionUnblocked");
 }
Example #18
0
 /// <summary>
 /// 连接回调错误
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="callbackExceptionEventArgs"></param>
 private static void ConnectionOnCallbackException(object sender, CallbackExceptionEventArgs callbackExceptionEventArgs)
 {
     NLogHelper.Warn($"OnCallbackException:{callbackExceptionEventArgs?.Exception}");
 }
        /// <summary>
        /// 安全调用采用了反射可能影响性能,不推荐使用
        /// 不能实现channel级别的重用
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="action"></param>
        /// <param name="exceptionHandler"></param>
        /// <returns></returns>
        public static bool SafeInvoke2 <T>(string ip, int port, Action <T> action,
                                           Action <Exception> exceptionHandler = null /*, int timeoutSeconds = 16*/) where T : ClientBase <T>
        {
            if (action == null)
            {
                return(true);
            }

            Channel channel = null;

            try
            {
                //var options = new List<ChannelOption>(capacity:3)
                //{
                //    ////Grpc不适合处理大量的数据,处理的数据级别是MB。如果需要传输大的消息,使用stream流式消息多次传输
                //    new ChannelOption(ChannelOptions.MaxSendMessageLength,8*1024*1024),//最大可以发送的消息长度
                //    new ChannelOption(ChannelOptions.MaxReceiveMessageLength,32*1024*1024),//最大允许接收的消息长度
                //    new ChannelOption(ChannelOptions.SoReuseport,1),//重用端口,默认值就是1
                //};
                //不使用加密
                //channel = new Channel(string.Format("{0}:{1}",ip,port), ChannelCredentials.Insecure);
                channel = new Channel(ip, port, ChannelCredentials.Insecure, GrpcOptions);

                //if (action != null)
                {
                    T stub = Activator.CreateInstance(typeof(T), channel) as T;

                    action(stub);


                    /*
                     *
                     *
                     * //构建client, 客户端不需要关闭
                     * var client = new Greeter.GreeterClient(channel);
                     * //客户端调用时指定deadline,如果不指定表示不超时
                     * //调用client,可以重用channel,多次调用方法
                     * //deadLine必须使用UTC时间
                     * var reply = client.SayHello(new Request() {Request_ = "Hello"},
                     *  deadline: DateTime.UtcNow.AddSeconds(timeoutSeconds));
                     *
                     *
                     */
                }

                return(true);
            }
            catch (RpcException rpcEx)
            {
                //判断是否正常
                StatusCode statusCode = rpcEx.Status.StatusCode;
                string     detail     = rpcEx.Status.Detail;

                if (statusCode == StatusCode.Unavailable)
                {
                    //服务不可用,通常是因为网络原因
                }


                if (statusCode == StatusCode.DeadlineExceeded)
                {
                    //超时
                }


                exceptionHandler?.Invoke(rpcEx);
                return(false);
            }
            catch (Exception ex)
            {
                if (exceptionHandler != null)
                {
                    exceptionHandler(ex);
                }

                return(false);
            }
            finally
            {
                if (channel != null)
                {
                    try
                    {
                        bool result = channel.ShutdownAsync().Wait(9000);
                        //channel.ShutdownAsync().Wait();
                        //安全关闭退出
                        if (result == false)
                        {
                            NLogHelper.Warn($"channel没有及时关闭");
                        }
                    }
                    catch (Exception ex)
                    {
                        NLogHelper.Error($"关闭Channel失败:{ex}");
                    }

                    //channel = null;
                }
            }
        }
 /// <summary>
 /// 不是在UI线程上执行的
 /// 串口出错的事件
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="serialErrorReceivedEventArgs"></param>
 private void SerialPortOnErrorReceived(object sender, SerialErrorReceivedEventArgs serialErrorReceivedEventArgs)
 {
     isAlive = false;
     NLogHelper.Warn($"串口出错事件ErrorReceived,事件类型:{serialErrorReceivedEventArgs?.EventType}");
 }
        /// <summary>
        /// 清除空目录
        /// </summary>
        /// <param name="topDir">顶级目录</param>
        /// <param name="currentDepth">当前递归深度</param>
        /// <returns>删除目录的个数</returns>
        private int CleanEmptyDirectory(string topDir, int currentDepth)
        {
            if (currentDepth > MaxRecursiveDepth)
            {
                NLogHelper.Warn("日志文件夹存在快捷方式导致无穷递归");
                return(0);
            }

            DirectoryInfo dirInfo = new DirectoryInfo(topDir);

            if (!dirInfo.Exists)
            {
                NLogHelper.Warn($"未找到{topDir}目录,无法清理");
                return(0);
            }


            //递归子文件夹
            DirectoryInfo[] subDirs = dirInfo.GetDirectories();//返回当前目录的子目录。如果没有子目录,则此方法返回一个空数组。 此方法不是递归的。
            //非空子目录集合
            List <DirectoryInfo> nonEmptyDirList = new List <DirectoryInfo>();


            DateTime now = DateTime.Now;

            //删除目录的个数
            int delCount = 0;

            //删除空目录
            foreach (var currentDir in subDirs)
            {
                //获取存在子目录的目录
                if (currentDir.Exists && currentDir.GetDirectories().Length != 0)
                {
                    nonEmptyDirList.Add(currentDir);
                }
                else if (currentDir.Exists && currentDir.GetFileSystemInfos().Length == 0 && (now - currentDir.CreationTime).TotalDays > 7)
                {
                    // 删除放在后面
                    //文件夹为空, 并且空目录至少3天没有使用
                    try
                    {
                        currentDir.Delete();
                        delCount++;
                        NLogHelper.Trace("删除空目录:" + currentDir.FullName);
                    }
                    catch (Exception ex)
                    {
                        NLogHelper.Warn($"删除空目录{currentDir.FullName}失败:{ex}");
                    }
                }
            }

            //递归子目录
            foreach (var subDir in nonEmptyDirList)
            {
                delCount += CleanEmptyDirectory(subDir.FullName, currentDepth + 1);
            }

            return(delCount);
        }
 /// <summary>
 /// 串口Dispose事件
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void SerialPort_Disposed(object sender, EventArgs e)
 {
     isAlive = false;
     NLogHelper.Warn("串口Disposed事件");
 }
 /// <summary>
 /// 非数据信号事件
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void SerialPort_PinChanged(object sender, SerialPinChangedEventArgs e)
 {
     NLogHelper.Warn($"串口发生非数据信号事件PinChanged,EventType={e?.EventType}");
 }
Example #24
0
        /// <summary>
        /// 消费者监听
        /// 经测试该函数是在前一个回调完成之后执行的,即回调是单线程执行的,需要自己实现多线程
        /// 消息保证是按顺序到达的,该方法不能抛异常,否则导致消息重发
        /// </summary>
        /// <param name="message"></param>
        private static void consumer_Listener(IMessage message)
        {
            //lock (locker)
            //{
            //    isAlive = true;
            //}


            try
            {
                _lastUpdateTime = DateTime.Now;

                #region 获取消息

                if (message == null)
                {
                    NLogHelper.Warn("接收到空消息");
                    return;
                }



                ////MAP消息
                ////IMapMessage mapMessage = session.CreateMapMessage();//MAP消息
                ////字节消息
                ////IBytesMessage byteMsg = session.CreateBytesMessage(new byte[] { });//字节消息
                //ITextMessage txtMsg = message as ITextMessage;
                ////避免多次调用txtMsg.Text,虽然没什么错
                //if (txtMsg == null /*|| string.IsNullOrWhiteSpace(txtMsg.Text)*/)
                //{
                //    NLogHelper.Warn("不是ITextMessage,消息类型=" + message.GetType());
                //    return;
                //}

                ////建议原样保存消息
                //string msg = StringUtils.TrimEx(txtMsg.Text);//txtMsg.Text.Trim();

                //if (string.IsNullOrEmpty(msg))
                //{
                //    NLogHelper.Warn("接收到Empty String");
                //    return;
                //}

                //NLogHelper.Info("接收到消息:" + msg);


                ////建议使用ByteMessage,结合ProtoBuffer使用
                //IBytesMessage byteMsg = message as IBytesMessage;
                //if (byteMsg == null)
                //{
                //    return;
                //}
                ////避免多次调用byteMsg.Content,访问Content导致流读完
                //byte[] byteArr = byteMsg.Content;//访问Content导致流读完
                ////此时可以对数据操作


                if (message is ITextMessage)
                {
                    ITextMessage txtMessage = message as ITextMessage;

                    string text = txtMessage.Text;

                    if (string.IsNullOrWhiteSpace(text))
                    {
                        NLogHelper.Warn("接收到Empty string");
                        return;
                    }

                    NLogHelper.Trace($"接收到消息:{text}");
                    CommonMessage commonMsg = new CommonMessage()
                    {
                        CreateTime  = DateTime.Now,
                        MessageType = CommonMessageType.Text,
                        TextMessage = text
                    };
                    MQMessageHandler.AddToQueue(commonMsg);
                }
                else if (message is IBytesMessage)
                {
                    IBytesMessage bytesMessage = message as IBytesMessage;
                    //避免多次调用byteMsg.Content,访问Content导致流读完
                    byte[] bytes = bytesMessage.Content;
                    if (bytes == null || bytes.Length == 0)
                    {
                        NLogHelper.Warn("接收到empty bytes");
                        return;
                    }

                    NLogHelper.Trace($"接收到BytesMessage消息");
                    CommonMessage commonMsg = new CommonMessage()
                    {
                        CreateTime   = DateTime.Now,
                        MessageType  = CommonMessageType.Bytes,
                        BytesMessage = bytes
                    };
                    MQMessageHandler.AddToQueue(commonMsg);
                }
                else
                {
                    NLogHelper.Warn($"未处理消息类型{message.GetType()}");
                }


                #endregion


                //#region 开始处理消息

                ////注:经测试该函数是在前一个回调完成之后执行的,即回调是单线程执行的,需要自己实现多线程
                //MQMessageHandler.AddToQueue(msg);
                //#endregion
            }
            catch (Exception ex)
            {
                NLogHelper.Error("解析处理MQ消息失败:" + ex);
            }
        }
Example #25
0
 /// <summary>
 /// 消息丢弃
 /// </summary>
 /// <param name="obj"></param>
 private static void AbandonMessageHandler(RMqMessage obj)
 {
     NLogHelper.Warn($"存在消息丢弃,消息id={obj.Id}");
 }
Example #26
0
        /// <summary>
        /// MQ回调
        /// </summary>
        /// <param name="state"></param>
        private static void MqTimerCallBack(object state)
        {
            lock (Slocker)
            {
                if (_isRunning)
                {
                    return;
                }
                _isRunning = true;
            }

            try
            {
                if (!LongRunRabbitProducer.IsAlive())
                {
                    Thread.Sleep(5500);

                    //延迟,使其能够自动恢复
                    if (!LongRunRabbitProducer.IsAlive())
                    {
                        if (_isFirstTimeToStartMq)
                        {
                            _isFirstTimeToStartMq = false;

                            NLogHelper.Debug("首次尝试启动MQConsumer");
                            LongRunRabbitProducer.Start(ex =>
                            {
                                NLogHelper.Error($"开启MQ失败:{ex}");
                            });
                        }
                        else
                        {
                            _restartCount++;
                            if (_restartCount > 10000000)
                            {
                                _restartCount = 10000;
                            }
                            NLogHelper.Warn($"MQ异常,第{_restartCount}次尝试重启 MQConsumer");
                            LongRunRabbitProducer.Start(ex =>
                            {
                                NLogHelper.Error($"开启MQ失败:{ex}");
                            });
                        }
                    }
                }
                else
                {
                    NLogHelper.Trace("检测MQ连接正常");
                }
            }
            catch (Exception ex)
            {
                NLogHelper.Error("MQ定时器异常:" + ex);
            }
            finally
            {
                lock (Slocker)
                {
                    _isRunning = false;
                }
            }
        }
        /// <summary>
        /// 清理日志
        /// </summary>
        public void CleanLog(string logDirToClean)
        {
            NLogHelper.Info("开始清理日志");
            DirectoryInfo dirInfo = new DirectoryInfo(logDirToClean);

            if (!dirInfo.Exists)
            {
                NLogHelper.Warn($"未找到{logDirToClean}日志目录,无法清理");
                return;
            }


            DateTime expireTime = DateTime.Now.Subtract(new TimeSpan(KeepDays, 0, 0, 0)).Date;//过期时间

            #region 根据当前硬盘减少保存时间
            try
            {
                if (KeepDays > KeepDaysWhenAvailableLimit)
                {
                    DriveInfo driveInfo = null;

                    foreach (DriveInfo item in DriveInfo.GetDrives())
                    {
                        if (StringUtils.EqualsEx(dirInfo.Root.Name, item.RootDirectory.Name))
                        {
                            //查找logs所在的磁盘
                            driveInfo = item;
                            break;
                        }
                    }

                    //如果磁盘空间不足,保留更少的天数
                    if (driveInfo != null && driveInfo.AvailableFreeSpace < driveInfo.TotalSize * DriveAvailableLimit)
                    {
                        //当到达硬盘利用极限时,保存的天数
                        expireTime = DateTime.Now.Subtract(new TimeSpan(KeepDaysWhenAvailableLimit, 0, 0, 0)).Date;
                    }
                }
            }
            catch (Exception ex)
            {
                //ignore
                NLogHelper.Warn($"根据硬盘当前容量判断过期时间失败:{ex}");
            }
            #endregion


            NLogHelper.Info($"清理{expireTime.ToString("yyyyMMdd HH:mm:ss", CultureInfo.InvariantCulture)}之前的{dirInfo.FullName}目录的日志");

            //清理文件
            try
            {
                int delCount = CleanFiles(logDirToClean, SearchPatternArr, expireTime, currentDepth: 0);
                NLogHelper.Info($"共删除{delCount}个文件");
            }
            catch (Exception ex)
            {
                NLogHelper.Warn($"清理文件失败:{ex}");
            }

            try
            {
                //清理空目录
                int delCount = CleanEmptyDirectory(logDirToClean, currentDepth: 0);
                NLogHelper.Info($"共删除{delCount}个目录");
            }
            catch (Exception ex)
            {
                NLogHelper.Warn($"清理空目录失败:{ex}");
            }


            NLogHelper.Info("清理日志完成");
        }
        public void Execute(IJobExecutionContext context)
        {
            lock (_locker)
            {
                if (_isRunning)
                {
                    return;
                }
                _isRunning = true;
            }

            string jobName = "";

            try
            {
                PerformanceCounter curCpuCounter = null;
                lock (_locker)
                {
                    if (_cpuCounter == null)
                    {
                        //好像只能读到一个核的cpu
                        _cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
                    }
                    curCpuCounter = _cpuCounter;
                }


                jobName = GetType().Name;

                if (curCpuCounter == null)
                {
                    return;
                }


                const int sampleCount       = 5;
                const int sleepMilliseconds = 1057;//至少应该为1s,否则有可能会读到相同的数据
                double    cpuUsed           = 0;
                double    itemValue         = 0;
                for (int i = 0; i < sampleCount + 1; i++)
                {
                    if (i == 0)
                    {
                        //第一次不统计
                        itemValue = curCpuCounter.NextValue();
                        Thread.Sleep(sleepMilliseconds);
                        continue;
                    }
                    //计算当前cpu使用的百分比 0-100的浮点数
                    itemValue = curCpuCounter.NextValue();
                    cpuUsed  += itemValue;
                    Thread.Sleep(sleepMilliseconds);
                }

                cpuUsed = cpuUsed / sampleCount;

                if (cpuUsed > MaxPercentCpuCanUse)
                {
                    NLogHelper.Warn($"cpu使用较大,约{cpuUsed.ToString("F1", CultureInfo.CurrentCulture)}%");
                    ErrorCode   = 1;
                    ErrorReason = $"该机器占用cpu较大,需人工检查";
                }
                else
                {
                    ErrorCode   = 0;
                    ErrorReason = string.Empty;
                }
            }
            catch (Exception ex)
            {
                NLogHelper.Error($"执行任务{jobName}异常:" + ex);
            }
            finally
            {
                lock (_locker)
                {
                    _isRunning = false;
                }
            }
        }
Example #29
0
 /// <summary>
 /// 连接阻塞
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="connectionBlockedEventArgs"></param>
 private static void ConnectionOnConnectionBlocked(object sender, ConnectionBlockedEventArgs connectionBlockedEventArgs)
 {
     NLogHelper.Warn($"OnConnectionBlocked:{connectionBlockedEventArgs?.Reason}");
 }
        /// <summary>
        /// 清理文件及空目录
        /// </summary>
        /// <param name="topDir">清理的顶层目录,该目录不会被删除</param>
        /// <param name="fileSearchPatternArr">
        /// 文件搜索模式 *所有文件 *.*有拓展名的文件
        /// *:表示0个或多个字符
        /// ?:表示0个或1个字符
        /// 采用*.log|*.txt格式,多个项通过|隔开,该功能是通过自己写代码实现的
        /// </param>
        /// <param name="expireTime">文件过期时间</param>
        /// <param name="currentDepth">当前递归深度</param>
        /// <returns>返回删除文件的个数</returns>
        private int CleanFiles(string topDir, string[] fileSearchPatternArr, DateTime expireTime, int currentDepth)
        {
            if (currentDepth > MaxRecursiveDepth)
            {
                //目录的快捷方式会被认为是一个文件
                NLogHelper.Warn("日志文件夹深度太大或者存在快捷方式导致无穷递归");
                return(0);
            }

            DirectoryInfo dirInfo = new DirectoryInfo(topDir);

            if (!dirInfo.Exists)
            {
                NLogHelper.Warn($"未找到{topDir}目录,无法清理");
                return(0);
            }


            //If you choose AllDirectories and the directory structure contains a link that creates a loop, the search operation enters an infinite loop.
            //FileInfo[] fileInfos = dirInfo.GetFiles(fileSearchPattern, SearchOption.AllDirectories);

            HashSet <string> fileInfos = new HashSet <string>();

            foreach (string searchPatternItem in fileSearchPatternArr)
            {
                //仅搜索当前目录,不递归
                dirInfo.GetFiles(searchPatternItem, SearchOption.TopDirectoryOnly).Select(r => r.FullName).ToList().ForEach(r => fileInfos.Add(r.Trim()));
            }

            //删除文件的个数
            int delCount = 0;

            //删除过期文件
            foreach (string fileName in fileInfos)
            {
                try
                {
                    FileInfo fileInfo = new FileInfo(fileName);
                    //文件过期
                    if (fileInfo.Exists && fileInfo.LastWriteTime < expireTime)
                    {
                        fileInfo.Delete();
                        delCount++;
                        NLogHelper.Trace("成功删除文件:" + fileInfo.FullName);
                    }
                }
                catch (Exception ex)
                {
                    NLogHelper.Warn($"删除文件{fileName}失败:{ex}");
                }
            }

            //递归子文件夹
            DirectoryInfo[] subDirs = dirInfo.GetDirectories();//返回当前目录的子目录。如果没有子目录,则此方法返回一个空数组。 此方法不是递归的。
            foreach (var subDir in subDirs)
            {
                delCount += CleanFiles(subDir.FullName, fileSearchPatternArr, expireTime, currentDepth + 1);
            }

            return(delCount);
        }