zoukankan      html  css  js  c++  java
  • C# 实现守护进程

    这段时间在做一个关于数据交互的项目。接收到客户发送过来的文件后,通过Windows服务将文件按一定的规则分发到不同的MQ消息队列,然后再由不同的处理程序处理。虽然在编码中尽可能的考虑到了异常以及记录了详细的日志,但是服务还是偶尔抽风停掉了,这样就造成了文件堆积,客户请求得不到及时的响应。所以需要一个守护进程来保证服务始终是启动状态的。

    首先,要保证需要监控的进程可配置,以及指定日志的保存位置。在App.config中配置日志保存路径以及需监控进程和对应的exe可执行程序的位置(之前考虑是如果没有该服务,则使用exe安装服务)。

      <appSettings>
        <add key="LogPath" value="D:Study"/>
        <add key="YTGDataExchangeProcess" value="d:StudyYTGDataExchangeProcess.exe"/>
      </appSettings>
    public class ServiceSearch
        {
            static List<ServiceProcessInfo> _ServiceList = new List<ServiceProcessInfo>();
            static object _logLocker = new Object();
            //日志记录位置 
            static readonly string _logPath;
    
            static ServiceSearch()
            {
                try
                {
                    string[] appSettingsKeys = ConfigurationManager.AppSettings.AllKeys;
    
                    foreach (string item in appSettingsKeys)
                    {
                        string value = ConfigurationManager.AppSettings[item].Trim();
                        //日志配置
                        if (item == "LogPath")
                        {
                            if (!string.IsNullOrEmpty(value))
                            {
                                _logPath = string.Format("{0}\ProcessMonitorLog", value);
                                if (!Directory.Exists(_logPath))
                                {
                                    Directory.CreateDirectory(_logPath);
                                }
                            }
                        }
                        else
                        {
                            if (!string.IsNullOrEmpty(value))
                            {
                                //应用程序是否存在 
                                if (File.Exists(value))
                                {
                                    _ServiceList.Add(new ServiceProcessInfo
                                    {
                                        ServiceExePath = value,
                                        ServiceName = item
                                    });
                                }
                            }
    
                        }
    
                    }
                }
                catch (Exception ex)
                {
                    WriteLog(ex.Message);
                }
            }
    
            public static void StartMonitor()
            {
                if (_ServiceList.Count != 0)
                {
                    foreach (ServiceProcessInfo info in _ServiceList)
                    {
                        string sevName = info.ServiceName;
                        string sevExePath = info.ServiceExePath;
    
                        if (!string.IsNullOrEmpty(sevExePath))
                        {
                            //校验exe文件是否存在
                            if (File.Exists(sevExePath))
                            {
                                ScanServiceManager(sevName, sevExePath);
                            }
                        }
                    }
                }
                else
                {
                    WriteLog("没有配置需要监控的服务!");
                }
            }
    
            /// <summary>
            /// 查找服务的进程
            /// 有则判断进程是否运行,非运行状态则启动
            /// </summary>
            public static void ScanServiceManager(string serviceName, string serviceExePath)
            {
                try
                {
                    ServiceController sevCtrler = new ServiceController(serviceName);
                    //该服务已存在
                    //如果服务状态不为启动
                    if (sevCtrler.Status != ServiceControllerStatus.Running)
                    {
                        sevCtrler.Start();
                    }
                    //创建监控线程
                    WatchService(serviceName);
                }
                catch (Exception ex)
                {
                    //该服务不存在
                    WriteLog(string.Format(ex.Message));
                }
            }
    
            /// <summary>
            /// 为配置的进程添加监控进程
            /// </summary>
            /// <param name="pro"></param>
            /// <param name="processAddress"></param>
            public static void WatchService(string ServiceName)
            {
                ServiceMonitor monitor = new ServiceMonitor(ServiceName);
                Thread thread = new Thread(new ThreadStart(monitor.Monitor));
                thread.IsBackground = true;
                thread.Start();
            }
    
            /// <summary>
            /// 写日志 
            /// </summary>
            /// <param name="errMessage"></param>
            public static void WriteLog(string errMessage)
            {
                string logPath = _logPath;
                //没有配置日志目录,不记录
                if (!string.IsNullOrEmpty(logPath))
                {
                    lock (_logLocker)
                    {
                        string fullName = string.Format("{0}\{1}.log", logPath, DateTime.Now.ToString("yyyy-MM-dd"));
                        if (!File.Exists(fullName))
                        {
                            File.Create(fullName).Close();
                        }
                        using (StreamWriter sw = new StreamWriter(fullName, true, Encoding.UTF8))
                        {
                            sw.WriteLine(String.Format("[{0}]{1}", DateTime.Now.ToString("hh:mm:ss fff"), errMessage));
                            sw.Close();
                        }
                    }
                }
            }
    
            public class ServiceProcessInfo
            {
                /// <summary>
                /// 服务名称
                /// </summary>
                public string ServiceName
                {
                    get;
                    set;
                }
                /// <summary>
                /// 应用程序位置
                /// </summary>
                public string ServiceExePath
                {
                    get;
                    set;
                }
            }
    
    
        }

    上面ScanServiceManager方法中,使用serviceName实例化ServiceController对象,并启用一个单独的线程对其轮询,监控其状态;否则只会对第一个服务进行监控后阻塞。

        public class ServiceMonitor
        {
            /// <summary>
            /// 服务名称
            /// </summary>
            private string _ServiceName;
    
            public string ServiceName
            {
                get { return _ServiceName; }
                set { _ServiceName = value; }
            }
    
            public ServiceMonitor(string ServiceName)
            {
                this._ServiceName = ServiceName;
            }
    
            /// <summary>
            /// 监听服务
            /// </summary>
            public void Monitor()
            {
                while (true)
                {
                    try
                    {
                        ServiceController ctrler = new ServiceController(_ServiceName);
                        if (ctrler.Status != ServiceControllerStatus.Running)
                        {
                            ServiceSearch.WriteLog(string.Format("正在启动服务{0}...", _ServiceName));
                            ctrler.Start();
                            ServiceSearch.WriteLog(string.Format("服务{0}启动成功!", _ServiceName));
                        }
                    }
                    catch (Exception ex)
                    {
                        ServiceSearch.WriteLog(string.Format("服务{0}启动失败,错误原因:{1}", _ServiceName, ex.Message));
                    }
                    Thread.Sleep(1000 * 40);
                }
            }
    
        }
  • 相关阅读:
    HTTP协议
    MySQL建立主-从服务器双机热备配置
    centOS7安装配置mysql5.7.21
    修改docker镜像的默认存储目录
    docker--学习笔记
    MySQL数据库操作
    zabbix注意事项和常用命令
    CnentOS6.5安装zabbix2.2
    如何查询一个进程下面的线程数(进程和线程区别)
    OSPF与ACL实例
  • 原文地址:https://www.cnblogs.com/lideqiang/p/4700550.html
Copyright © 2011-2022 走看看