2012-08-03 13 views
2

我創建了一個linux C++服務(它基本上是一個應用程序,但它經常通過TCP/IP處理請求)。C++ Linux服務 - 如何使用init.d + auto restart?

我想知道是否有任何簡單的方法讓它「自動重啓」,如果出現問題(如崩潰)或服務器重新啓動?

我不知道應該如何設置它作爲服務或設置一個rc.d腳本,我不是100%熟悉w /如何在Linux上執行此操作(我的服務器正在運行Ubuntu的,如果它的事)。

任何意見將不勝感激!

〜約什

回答

3
  • 創建其啓動並在必要時重新啓動它的控制應用程序。
  • 在您的應用程序中執行此操作 - 分叉一個孩子,在那裏運行程序,如果有必要,抓住停止/崩潰併爲新孩子分岔。一些工作代碼可以在這裏找到:monitoring the main app in c
+0

你知道任何可以實現這個目標的開源示例嗎?我真的不知道從哪裏開始如何創建這個 – Geesu 2012-08-03 14:02:31

+0

http://stackoverflow.com/questions/4126401/designing-a-monitor-process-for-monitoring-and-restarting-processes和http:// stackoverflow.com/questions/11514703/monitoring-the-main-app-in-c – 2012-08-03 23:27:11

4

在我的產品中,我創建了看門狗進程,它在單獨的進程中分叉和執行服務進程,並等待其終止。如果出於某種原因,進程終止,看門狗進程將創建另一個線程,並且它將再次開始進程。

正如評論中指出的,你應該檢查它爲什麼崩潰。首先,您可以閱讀程序退出值。

下面是簡單的程序,讓您開始:

#include <stdio.h> 
#include <unistd.h> 
#include <sys/wait.h> 

int main() 
{ 
    create_process(); 
    return 0; 
} 

void create_process() 
{ 
    int exit_code; 
    if(fork() == 0) 
    { 
     exec("./your_service"); 
    } 
    else 
    { 
     wait(&exit_code); 
     if(WIFEXITED(exit_code)) 
     { 
      /* Program terminated with exit */ 
      /* If you want, you could decode exit code here using 
       WEXITSTATUS and you can start program again. 
      */ 
      return; 
     } 
     else 
`  { 
       /* Program didn't terminated with exit, restart */ 
      create_process(); 
     } 

    } 
} 

爲了啓動在系統啓動時的服務,只需編輯/etc/rc.local腳本並運行你的監視進程追加命令。

+1

a *線程*聽起來不對..它可能會損壞內存看門狗線程,並防止重新啓動.. – 2012-08-03 13:48:15

+0

是的,你是正確 - 它永遠不會出現在我的腦海裏(這是非常簡單的服務)。它應該使用'system()'嗎? – 2012-08-03 13:52:19

+1

你還應該得到一些診斷爲什麼它崩潰。並且還要在重新啓動之前(例如3秒)離開。你可能會遇到程序試圖重啓,崩潰,重啓的問題 - 而且作爲開發人員你無法重新控制,因爲硬盤正在峯值以及CPU等。 – 2012-08-03 14:08:45

0

你可能想看看使用Inet Daemon。每次有新的請求進入時,inet守護進程都會啓動一個新進程。因此,如果服務器出現故障,當下一個請求進入時它會重新啓動。

+0

此假定請求可以被獨立地處理,並且沒有共享的狀態。它也會爲每個請求創建一個新的過程。 – 2012-08-03 23:32:10

0

編寫父應用程序的最簡單方法是自動-restarts一個子進程,在* NIX,只是使用shell腳本:

#!/bin/sh 
while true; 
do 
    run_my_program; 
done 

您可以選擇這個輸出重定向,在後臺運行本身等 這並沒有解決開始的進程,但是與C++編寫父進程相比,它的工作量更少(與完全相同的結果)。

4

這裏有很多答案建議有一個「父應用程序」來完成它,但是最終會遇到與父應用程序相同的問題 - 它會一直向下拖曳。

在很多unix類型的系統(特別是歷史上)中,init進程是第一個執行進程的進程,它將執行(並自動重啓)/ etc/inittab中定義的進程。

因此,不要編寫自己的看門狗或進程來自動重啓 - 您可以使用這個爲您自動完成這項工作的進程,並且由於它是初始化進程,如果它死了,系統還有很多事情需要擔心關於你的服務。

@doron表示另一種好方法,如果你的服務應該爲每個傳入連接產生一個新的進程,並且只有當它有一個傳入連接時才能工作。

最後,現在init進程(和/ etc/inittab)已經在Ubuntu類型系統上被upstart替代 - http://upstart.ubuntu.com/ - 對於同樣的事情更靈活的系統。

+0

我假設你低估了我的答案併發布了你自己的答案。簡而言之:它並不是一路下來的。父應用程序非常小,因此,完全可靠,所以它不會崩潰。沒有必要爲父應用程序提供控制應用程序。此外,很多事情都可能出錯,崩潰只是其中之一,但您的解決方案只能處理崩潰。例如:如果您想檢查服務器是否仍在處理請求或凍結,該怎麼辦? – 2012-11-16 10:31:22

+1

儘管我同意看門狗方法並不困難(一個shell腳本可以完成同樣的工作),但我堅決認爲,編寫自己的方案對於使用系統的初始化或服務進程管理系統來說是一個很差的選擇。 – 2012-11-18 00:29:59

+0

如果有附加檢查的要求,那麼我認爲系統啓動/服務管理系統啓動的進程可以完成這些工作,並監視由同一系統啓動的第二個服務進程或它所分派的第二個服務進程。 – 2012-11-18 00:39:45