2

我创建了一个 linux c++ 服务(它基本上是一个应用程序,但它经常通过 TCP/IP 处理请求)。

我想知道如果出现问题(如崩溃)或服务器重新启动,是否有任何简单的方法让它“自动重启”?

我不确定如何甚至是否应该将其设置为服务或设置 rc.d 脚本,我不是 100% 熟悉如何在 linux 上执行此操作(如果重要,我的服务器正在运行 ubuntu )。

任何建议将不胜感激!

〜乔什

4

5 回答 5

4

这里的很多答案都建议有一个“父应用程序”来做这件事,但你最终会遇到与父应用程序相同的问题——它一直是乌龟。

在许多 unix 类型系统中(尤其是历史上),init 进程是第一个执行的进程,并将执行(并自动重新启动)在 /etc/inittab 中定义的进程。

因此,与其编写自己的看门狗或进程来自动重启 - 您可以使用它自动为您完成这项工作,并且由于它是 init 进程,如果它死了,系统比您的服务更需要担心.

@doron 建议另一种好方法,如果您的服务应该为每个传入连接生成一个新进程,并且只有在它有传入连接时才起作用。

最后,这些天来,在 Ubuntu 类型系统上的 init 进程(和 /etc/inittab)已被替换为 upstart - http://upstart.ubuntu.com/ - 一个更灵活的系统,用于同样的事情。

于 2012-11-16T03:36:07.397 回答
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脚本并附加命令以运行您的看门狗进程。

于 2012-08-03T13:46:50.310 回答
3
  • 创建一个控制应用程序,在必要时启动并重新启动它。
  • 在您的应用程序中执行此操作 - 派生一个孩子,在那里运行程序,捕获停止/崩溃并在必要时派生新的孩子。一些工作代码可以在这里找到:monitoring the main app in c
于 2012-08-03T13:46:13.337 回答
0

在 *NIX 上编写自动重启子进程的父应用程序的最简单方法是使用 shell 脚本:

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

您可以选择拥有此重定向输出,在后台运行自身等。这并没有首先解决启动进程的问题,但与在 C++ 中编写父进程相比,它的工作量更少(对于完全相同的结果)。

于 2012-08-03T15:00:27.263 回答
0

您可能想看看使用Inet Daemon。每次有新请求进入时,inet 守护进程都会启动一个新进程。因此,如果您的服务器发生崩溃,它只会在下一个请求进入时重新启动。

于 2012-08-03T14:39:08.570 回答