我创建了一个 linux c++ 服务(它基本上是一个应用程序,但它经常通过 TCP/IP 处理请求)。
我想知道如果出现问题(如崩溃)或服务器重新启动,是否有任何简单的方法让它“自动重启”?
我不确定如何甚至是否应该将其设置为服务或设置 rc.d 脚本,我不是 100% 熟悉如何在 linux 上执行此操作(如果重要,我的服务器正在运行 ubuntu )。
任何建议将不胜感激!
〜乔什
这里的很多答案都建议有一个“父应用程序”来做这件事,但你最终会遇到与父应用程序相同的问题——它一直是乌龟。
在许多 unix 类型系统中(尤其是历史上),init 进程是第一个执行的进程,并将执行(并自动重新启动)在 /etc/inittab 中定义的进程。
因此,与其编写自己的看门狗或进程来自动重启 - 您可以使用它自动为您完成这项工作,并且由于它是 init 进程,如果它死了,系统比您的服务更需要担心.
@doron 建议另一种好方法,如果您的服务应该为每个传入连接生成一个新进程,并且只有在它有传入连接时才起作用。
最后,这些天来,在 Ubuntu 类型系统上的 init 进程(和 /etc/inittab)已被替换为 upstart - http://upstart.ubuntu.com/ - 一个更灵活的系统,用于同样的事情。
在我的产品中,我创建了看门狗进程,该进程在单独的进程中分叉和执行服务进程,并等待其终止。如果由于某种原因进程终止,看门狗进程将创建另一个线程并再次启动进程。
如评论中所述,您应该检查它崩溃的原因。首先,您可以读取程序退出值。
这是让您入门的简单程序:
#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
脚本并附加命令以运行您的看门狗进程。
在 *NIX 上编写自动重启子进程的父应用程序的最简单方法是使用 shell 脚本:
#!/bin/sh
while true;
do
run_my_program;
done
您可以选择拥有此重定向输出,在后台运行自身等。这并没有首先解决启动进程的问题,但与在 C++ 中编写父进程相比,它的工作量更少(对于完全相同的结果)。
您可能想看看使用Inet Daemon。每次有新请求进入时,inet 守护进程都会启动一个新进程。因此,如果您的服务器发生崩溃,它只会在下一个请求进入时重新启动。