编写一个 Linux 守护进程

5

什么是在Linux下编写/配置应用程序的正确方式,以便它始终运行并提供外部请求(TCP、数据库、文件系统等)。

我特别不称其为守护进程,因为在Linux环境中它可能意味着我不想要的东西。

我已经阅读了多个主题,包括:

Linux daemonize

best way to write a linux daemon

Best practice to run Linux service as a different user

但它们都没有提供关于使用哪种方法的全面比较。

我看到以下选项:

  • 编写应用程序,它forks,调用setpid、umask等,但这需要应用程序自己执行许多步骤(由init.d自动启动?)
  • 使用daemon() init.d函数,它为您执行了大部分这些步骤(但它是否可移植到所有/许多Linux发行版)
  • 在后台运行应用程序,并相信它能够在后台运行

但它们中哪一个才是正确的方法。如果它们都可以使用,那么什么构成了Linux中的守护进程?

我正在寻找在Windows下将应用程序作为服务运行的等效方法(使用sc可以自动创建任何.exe文件以作为服务运行)。


我的要求如下:

  • 开机后自动启动
  • 特定的用户身份运行(非root)
  • 可以访问整个文件系统(/),但创建/修改文件时使用应用程序所在用户的身份
  • 可以通过service startservice stop进行控制
  • 可能在崩溃或被杀后自动重启
  • 可以写入syslog
  • 在RHEL7下运行

我是该应用程序的作者,但希望不更改它来处理守护进程。

我的猜测是编写自定义init.d脚本,然后从/etc/init.d/functions调用daemon()函数。 我对吗?

2个回答

10

RHEL7使用systemd作为其初始化系统,它将处理大部分您的要求。您应该为您的守护程序编写一个systemd单元文件(在systemd术语中称为服务)。然后它可以:

  • 自动启动:是的,使用systemctl enable yourservice
  • 作为特定用户运行:是的,在您的单元文件中设置User键。
  • 可以访问整个文件系统:是的,它将拥有您配置的用户具有的所有权限,并创建该用户的文件。
  • 可以通过service start进行控制:是的,或者通过systemctl start进行控制。
  • 在崩溃后自动重启:是的,在您的单元文件中设置Restart键(例如,on-failurealways)。
  • 写入syslog:您的程序写入标准输出的任何输出都将写入systemd日志,可以使用journalctl查看和/或根据需要写入syslog。

当在现代 init 系统下运行时,您的应用程序不需要(也不应该)将自己变成守护进程。这不仅适用于 systemd,也适用于 upstart,以及像 runit、daemontools、supervisord 和大多数其他监管者。守护进程化有点棘手,容易出错。只需像平常一样编写您的应用程序,让 init 系统处理即可。


2
如果我理解正确的话,特别是关于RHEL 7的要求,Systemd Unit是您的好帮手。如果您因某种原因尝试过或放弃了它,请进一步阐述。

我考虑过这个问题,但我试图找到更便携的方式,特别是在不同的Linux发行版之间。 - Mios
@Mios,你的要求之一是在RHEL7下运行,而不是其他Linux发行版。 - CDahn
1
我绝对不想卷入 SystemD 的争论中,但是... 你们追求哪些发行版?有许多没有使用 Systemd的发行版,但如果你不算 BSD、嵌入式和旧版本,那么剩下的选择就不多了。即使 Debian 也转向了 SystemD。 - Michal Karm Babacek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接