linux監控程式-程式自動重啟方法

來源:互聯網
上載者:User

 

轉自:http://www.cnblogs.com/zhy113/archive/2013/03/15/2960910.html

 

家在寫server的時候,不管server寫的是多麼健壯,還是經常出現core dump等程式異常退出的,但是一般情況下需要在無人為幹預情況下,能夠自動重新啟動,保證server程式能夠服務使用者。這時就需要一個監控程式來實現 能夠讓程式自動重新啟動,現在筆者在寫portmap就遇到了這個問題,通過網上尋找資料,找到了一個相對靠譜的exec+fork解決方案。

使用指令碼實現自動重啟

首先想到的最簡單的使用shell指令碼,大概思路:

ps -ef | grep “$1″ | grep -v “grep” | wc –l 是擷取 $1 ($1 代表進程的名字)的進程數,指令碼根據進程數來決定下一步的操作。通過一個死迴圈,每隔 1 秒檢查一次系統中的指定程式的進程數,這裡也可使用crontab來實現。

這種方法比較土,還是可以基本解決問題,但是有1s的延遲,筆者在應用中未採用這種方法,有關這個shell指令碼,請參看文章後面的附件代碼。

exec+fork方式

筆者最終採用的exec+fork方式來實現的,具體思想如下:

1,exec函數把當前進程替換為一個新的進程,新進程由path或file參數指定。可以使用exec函數將程式的執行從一個程式切換到另一個程式;

2,fork函數是建立一個新的進程,在進程表中建立一個新的表項,而建立者(即父進程)按原來的流程繼續執行,子進程執行自己的控制流程程;

3,wait 當fork啟動一個子進程時,子進程就有了它自己的生命週期並將獨立運行,我們可以在父進程中調用wait函數讓父進程等待子進程的結束;

相信介紹到這裡,讀者已經能夠想到解決方案了:1)首先使用fork系統調用,建立子進程,2)在子進程中使用exec函數,執行需要自動重啟的程式,3) 在父進程中執行wait等待子進程的結束,然後重新建立一個新的子進程。

使用方法:

#./portmap 需要監控的程式的路徑#args portmap 需要的參數$ ./supervisor ./portmap  args.....

代碼如下:

/** * * supervisor  * * author: liyangguang (liyangguang@software.ict.ac.cn) * * date: 2011-01-21 21:04:01 * * changes * 1, execl to execv */#include <stdio.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <sys/wait.h>#include <stdlib.h>int main(int argc, char **argv){    int ret, i, status;    char *child_argv[100] = {0};    pid_t pid;    if (argc < 2) {        fprintf(stderr, "Usage:%s <exe_path> <args...><strong>n</strong>", argv[0]);        return -1;    }    for (i = 1; i < argc; ++i) {        child_argv[i-1] = (char *)malloc(strlen(argv[i])+1);        strncpy(child_argv[i-1], argv[i], strlen(argv[i]));        child_argv[i-1][strlen(argv[i])] = '<strong>0</strong>';    }    while(1){        pid = fork();         if (pid == -1) {            fprintf(stderr, "fork() error.errno:%d error:%s<strong>n</strong>", errno, strerror(errno));        }        if (pid == 0) {            ret = execv(child_argv[0], (char **)child_argv);            if (ret < 0) {                fprintf(stderr, "execv ret:%d errno:%d error:%s<strong>n</strong>", ret, errno, strerror(errno));                continue;            }            exit(0);        }if (pid > 0) {            pid = wait(&status);            fprintf(stdout, "wait return");        }    }return 0;}

 

shell指令碼方式的代碼如下:

# 函數: CheckProcess# 功能: 檢查一個進程是否存在# 參數: $1 --- 要檢查的進程名稱# 返回: 如果存在返回0, 否則返回1.#------------------------------------------------------------------------------CheckProcess(){  # 檢查輸入的參數是否有效  if [ "$1" = "" ];  then    return 1  fi   #$PROCESS_NUM擷取指定進程名的數目,為1返回0,表示正常,不為1返回1,表示有錯誤,需要重新啟動  PROCESS_NUM=`ps -ef | grep "$1" | grep -v "grep" | wc -l`   if [ $PROCESS_NUM -eq 1 ];  then    return 0  else    return 1  fi}     # 檢查test執行個體是否已經存在while [ 1 ] ; do CheckProcess "test" CheckQQ_RET=$? if [ $CheckQQ_RET -eq 1 ]; then   # 殺死所有test進程,可換任意你需要執行的操作     killall -9 test  exec ./test &   fi sleep 1done

轉自:http://www.cnblogs.com/zhy113/archive/2013/03/15/2960910.html

 

家在寫server的時候,不管server寫的是多麼健壯,還是經常出現core dump等程式異常退出的,但是一般情況下需要在無人為幹預情況下,能夠自動重新啟動,保證server程式能夠服務使用者。這時就需要一個監控程式來實現 能夠讓程式自動重新啟動,現在筆者在寫portmap就遇到了這個問題,通過網上尋找資料,找到了一個相對靠譜的exec+fork解決方案。

使用指令碼實現自動重啟

首先想到的最簡單的使用shell指令碼,大概思路:

ps -ef | grep “$1″ | grep -v “grep” | wc –l 是擷取 $1 ($1 代表進程的名字)的進程數,指令碼根據進程數來決定下一步的操作。通過一個死迴圈,每隔 1 秒檢查一次系統中的指定程式的進程數,這裡也可使用crontab來實現。

這種方法比較土,還是可以基本解決問題,但是有1s的延遲,筆者在應用中未採用這種方法,有關這個shell指令碼,請參看文章後面的附件代碼。

exec+fork方式

筆者最終採用的exec+fork方式來實現的,具體思想如下:

1,exec函數把當前進程替換為一個新的進程,新進程由path或file參數指定。可以使用exec函數將程式的執行從一個程式切換到另一個程式;

2,fork函數是建立一個新的進程,在進程表中建立一個新的表項,而建立者(即父進程)按原來的流程繼續執行,子進程執行自己的控制流程程;

3,wait 當fork啟動一個子進程時,子進程就有了它自己的生命週期並將獨立運行,我們可以在父進程中調用wait函數讓父進程等待子進程的結束;

相信介紹到這裡,讀者已經能夠想到解決方案了:1)首先使用fork系統調用,建立子進程,2)在子進程中使用exec函數,執行需要自動重啟的程式,3) 在父進程中執行wait等待子進程的結束,然後重新建立一個新的子進程。

使用方法:

#./portmap 需要監控的程式的路徑#args portmap 需要的參數$ ./supervisor ./portmap  args.....

代碼如下:

/** * * supervisor  * * author: liyangguang (liyangguang@software.ict.ac.cn) * * date: 2011-01-21 21:04:01 * * changes * 1, execl to execv */#include <stdio.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <sys/wait.h>#include <stdlib.h>int main(int argc, char **argv){    int ret, i, status;    char *child_argv[100] = {0};    pid_t pid;    if (argc < 2) {        fprintf(stderr, "Usage:%s <exe_path> <args...><strong>n</strong>", argv[0]);        return -1;    }    for (i = 1; i < argc; ++i) {        child_argv[i-1] = (char *)malloc(strlen(argv[i])+1);        strncpy(child_argv[i-1], argv[i], strlen(argv[i]));        child_argv[i-1][strlen(argv[i])] = '<strong>0</strong>';    }    while(1){        pid = fork();         if (pid == -1) {            fprintf(stderr, "fork() error.errno:%d error:%s<strong>n</strong>", errno, strerror(errno));        }        if (pid == 0) {            ret = execv(child_argv[0], (char **)child_argv);            if (ret < 0) {                fprintf(stderr, "execv ret:%d errno:%d error:%s<strong>n</strong>", ret, errno, strerror(errno));                continue;            }            exit(0);        }if (pid > 0) {            pid = wait(&status);            fprintf(stdout, "wait return");        }    }return 0;}

 

shell指令碼方式的代碼如下:

# 函數: CheckProcess# 功能: 檢查一個進程是否存在# 參數: $1 --- 要檢查的進程名稱# 返回: 如果存在返回0, 否則返回1.#------------------------------------------------------------------------------CheckProcess(){  # 檢查輸入的參數是否有效  if [ "$1" = "" ];  then    return 1  fi   #$PROCESS_NUM擷取指定進程名的數目,為1返回0,表示正常,不為1返回1,表示有錯誤,需要重新啟動  PROCESS_NUM=`ps -ef | grep "$1" | grep -v "grep" | wc -l`   if [ $PROCESS_NUM -eq 1 ];  then    return 0  else    return 1  fi}     # 檢查test執行個體是否已經存在while [ 1 ] ; do CheckProcess "test" CheckQQ_RET=$? if [ $CheckQQ_RET -eq 1 ]; then   # 殺死所有test進程,可換任意你需要執行的操作     killall -9 test  exec ./test &   fi sleep 1done
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.