使用ACE监控启动进程,进程崩溃后自动重启(windows/linux通用)
2013-09-29 11:19
489 查看
//使用ACE监控启动进程,进程崩溃后自动重启(windows/linux通用)
原理:
监护程序使用子进程的方式启动各个进程,
子进程退出时,监护程序能够得到相应的退出信号,
从而在子进程退出后,在重新启动相应的子进程。
//----------------------------------------------------------
//配置文件ProcessManager.conf格式
//./PROCESS_MANAGER 1
//./PROCESS_MANAGER 2
//----------------------------------------------------------
// main.cpp
头文件CProcessManager.h
类的定义如下
//CProcessManager.cpp类中函数的实现
//实现自动重新启动进程
原理:
监护程序使用子进程的方式启动各个进程,
子进程退出时,监护程序能够得到相应的退出信号,
从而在子进程退出后,在重新启动相应的子进程。
//----------------------------------------------------------
//配置文件ProcessManager.conf格式
//./PROCESS_MANAGER 1
//./PROCESS_MANAGER 2
//----------------------------------------------------------
// main.cpp
// main.cpp #include "CProcessManager.h" int main(int argc, char *argv[]) { // Running as a child for test. if (argc > 1) { ACE_OS::sleep(10); return 0; } // set output log file ACE_OS::setprogname("ProcessManager"); ACE_Date_Time tvTime(ACE_OS::gettimeofday()); char szLogFileName[256]; memset(szLogFileName, 0, sizeof(szLogFileName)); snprintf(szLogFileName, sizeof(szLogFileName), "log/%s_%04d%02d%02d_%02d%02d%02d.log", ACE_OS::getprogname(), (int)tvTime.year(), (int)tvTime.month(), (int)tvTime.day(), (int)tvTime.hour(), (int)tvTime.minute(), (int)tvTime.second()); ACE_OSTREAM_TYPE *pLogOutput = new ofstream(szLogFileName); ACE_LOG_MSG->msg_ostream(pLogOutput, true); ACE_LOG_MSG->set_flags(ACE_Log_Msg::OSTREAM); // Prepends timestamp and message priority to each message ACE_LOG_MSG->set_flags(ACE_Log_Msg::VERBOSE_LITE); //ACE_LOG_MSG->clr_flags(ACE_Log_Msg::STDERR); ACE_DEBUG((LM_INFO, ACE_TEXT("[%N:%l]: ---ProcessManager START---.\n"))); int nRet = 0; CProcessManager *pProcMng = new CProcessManager(); // 启动进程监控 nRet = pProcMng->ProcessMonitor(); if(nRet != 0) { ACE_DEBUG((LM_ERROR, ACE_TEXT("[%N:%l]: ---ProcessMonitor Error---\n"))); } delete pProcMng; ACE_DEBUG((LM_INFO, ACE_TEXT("[%N:%l]: ---ProcessManager STOP---.\n"))); ACE_LOG_MSG->clr_flags(ACE_Log_Msg::OSTREAM); delete pLogOutput; return 0; }
头文件CProcessManager.h
类的定义如下
//CProcessManager.h #include <stdio.h> #include <stdlib.h> #include <vector> #include <string> #include <map> using namespace std; #include "ace/OS.h" #include "ace/streams.h" #include "ace/Log_Msg.h" #include "ace/Date_Time.h" #include "ace/Event_Handler.h" #include "ace/Reactor.h" #include "ace/Process_Manager.h" // 进程监控,进程崩溃后,自动重新启动进程 class CProcessManager { public: CProcessManager(){}; virtual ~CProcessManager(){}; // 从配置文件读取进程列表信息 virtual int ReadConfigProcessInfo(char *pFileName); // 启动进程,并进行进程监控,进程崩溃后,自动重新启动进程 virtual int ProcessMonitor(); private: vector<string> m_vConfigProcessInfo; // 进程列表信息 }; // 回调事件,程序退出后,执行handle_exit函数 class CProcessExitHandler: public ACE_Event_Handler { public: CProcessExitHandler(){}; virtual ~CProcessExitHandler(){}; // 程序退出后,执行该函数 virtual int handle_exit(ACE_Process* process); };
//CProcessManager.cpp类中函数的实现
//实现自动重新启动进程
//CProcessManager.cpp #include "CProcessManager.h" ACE_Process_Manager *g_pPM; // 进程管理 map<string, pid_t> g_mapProcessInfo; // 进程ID管理列表 // 读取进程列表配置文件 int CProcessManager::ReadConfigProcessInfo(char *pFileName) { char *pTemp = NULL; char szTemp[1024]; string strTemp = ""; if(NULL == pFileName) { ACE_DEBUG((LM_ERROR, ACE_TEXT("[%N:%l]: Parameter FileName is null.\n"))); return -1; } // 文件格式 //./PROCESS_MANAGER 1 //./PROCESS_MANAGER 2 // 打开进程列表配置文件 FILE *fp = fopen(pFileName, "r"); if(NULL == fp) { ACE_DEBUG((LM_ERROR, ACE_TEXT("[%N:%l]: file open error.[%s]\n"), pFileName)); return -2; } // 循环读取进程列表配置文件 while(1) { memset(szTemp, 0, sizeof(szTemp)); pTemp = fgets(szTemp, sizeof(szTemp), fp); if(NULL == pTemp) { break; } // 去掉注释 if(szTemp[0] == '#') { continue; } strTemp = szTemp; if(strTemp.length() == 0) { continue; } // 去掉回车换行 if(strTemp[strTemp.length() - 1] == '\n') { strTemp[strTemp.length() - 1] = 0; } if(strTemp.length() == 0) { continue; } if(strTemp[strTemp.length() - 1] == '\r') { strTemp[strTemp.length() - 1] = 0; } if(strTemp.length() == 0) { continue; } // 把读取的进程信息放到[进程列表信息]全局变量 m_vConfigProcessInfo.push_back(strTemp); } // 关闭进程列表配置文件 fclose(fp); // [进程列表信息]不应该为0 if(m_vConfigProcessInfo.size() == 0) { ACE_DEBUG((LM_ERROR, ACE_TEXT("[%N:%l]: Process list is null.[%s]\n"), pFileName)); return -3; } return 0; } // 进程监控 // 根据配置文件启动进程,并注册进程退出时回调函数 int CProcessManager::ProcessMonitor() { int nRet = 0; vector<string>::iterator itrConfig; string strStartProcess; m_vConfigProcessInfo.clear(); // 读取进程列表配置文件 nRet = ReadConfigProcessInfo("ProcessManager.conf"); if(nRet != 0) { ACE_DEBUG((LM_ERROR, ACE_TEXT("[%N:%l]: ReadConfigProcessInfo[%s] error.\n"), "ProcessManager.conf")); return -1; } // Instantiate a process manager with space for 100 processes. g_pPM = new ACE_Process_Manager(ACE_Process_Manager::DEFAULT_SIZE, ACE_Reactor::instance()); CProcessExitHandler procExitHandler; // 循环配置进程列表,启动进程 for(itrConfig = m_vConfigProcessInfo.begin(); itrConfig != m_vConfigProcessInfo.end(); ++itrConfig) { strStartProcess = *itrConfig; // 启动进程 ACE_Process_Options options; options.command_line(strStartProcess.c_str()); pid_t pid = g_pPM->spawn(options); // 启动进程失败 if (pid == ACE_INVALID_PID) { ACE_DEBUG((LM_ERROR, ACE_TEXT("[%N:%l]: start a child process success(%d)%s\n"), pid, strStartProcess.c_str())); return -1; } ACE_DEBUG((LM_INFO, ACE_TEXT("[%N:%l]: start a child process success(%d)%s\n"), pid, strStartProcess.c_str())); // 注册回调(进程退出时,调用该回调) g_pPM->register_handler(&procExitHandler, pid); // 添加启动成功的进程到进程ID管理列表 g_mapProcessInfo[strStartProcess] = pid; ACE_OS::sleep(1); } // Run the reactor event loop waiting for events to occur. ACE_Reactor::instance()->run_reactor_event_loop(); //ACE_Reactor::instance()->end_reactor_event_loop(); return 0; } // 进程退出回调函数 // 程序退出后,执行该函数,重新启动进程 int CProcessExitHandler::handle_exit(ACE_Process* process) { map<string, pid_t>::iterator itrProcess; ACE_DEBUG((LM_INFO, ACE_TEXT("[%N:%l]: Process %d exited with exit code %d\n"), process->getpid (), process->return_value())); // 循环进程ID管理列表,根据进程ID找到退出的进程,重新启动进程 for(itrProcess = g_mapProcessInfo.begin(); itrProcess != g_mapProcessInfo.end(); ++itrProcess) { // 根据进程ID,查找进程名 if(itrProcess->second == process->getpid()) { // 重新启动进程 ACE_Process_Options options; options.command_line(itrProcess->first.c_str()); pid_t pid = g_pPM->spawn(options); // 重新启动进程失败 if (pid == ACE_INVALID_PID) { ACE_DEBUG((LM_ERROR, ACE_TEXT("[%N:%l]: restart a child process error(%d)%s\n"), pid, itrProcess->first.c_str())); return -1; } ACE_DEBUG((LM_INFO, ACE_TEXT("[%N:%l]: restart a child process success(%d)%s\n"), pid, itrProcess->first.c_str())); // 注册回调(进程退出时,调用该回调) g_pPM->register_handler(this, pid); // 添加启动成功的进程到进程ID管理列表 itrProcess->second = pid; break; } } return 0; }
相关文章推荐
- 使用Python的Supervisor进行进程监控以及自动启动
- 使用Python的Supervisor进行进程监控以及自动启动
- 使用Python的Supervisor进行进程监控以及自动启动
- linux shell脚本监控进程崩溃自动重启
- 使用god来自动启动崩溃的进程
- LINUX下使用Shell自动监控tomcat并且执行重启操作
- 如何管理你的常驻job,自动启动?挂掉重启?用supervisod管理你的进程吧
- linux 进程监控和自动重启的简单实现
- 使用jconsole 监控eclipse中启动的java虚拟机进程
- shell:监控进程运行状态并自动重启进程
- LINUX下使用Shell自动监控tomcat并且执行重启操作
- Linux crontab的使用方式,sh脚本的编写,sh脚本自动启动tomcat服务器,sh监控系统运行情况
- 【Shell/Python】Linux 进程自动监控bash shell脚本 监控VPS服务器负载/CPU及内存占用 自动重启
- linux 进程监控和自动重启的简单实现
- 监控redis进程,如果没有自动重启
- shell 脚本监控程序是否正在执行, 如果没有执行, 则自动启动该进程
- 监控某个进程,如果不存在就自动重启
- linux下监视进程 崩溃挂掉后自动重启的shell脚本
- Apache httpd进程监控,自动重启httpd服务shell
- 一个监控Squid运行进程数并自动重启的简洁Shell脚本分享