【问题标题】:Start stop daemon program启动停止守护程序
【发布时间】:2012-11-21 13:50:00
【问题描述】:

我一直在使用Proc::Daemon 来尝试制作启动/停止守护程序脚本,我可以这样做:

X start
X stop
X status

等等。但是,在源代码中,Proc::Daemon 使用“pid”文件或搜索进程表。我关心这两种方法,首先是“pid”被重用,这可能会给人一种服务在实际关闭时启动的印象,其次是进程表条目很容易伪造,并且检查看起来并不特别健壮。

有没有像我描述的那样制作启动/停止守护程序脚本/程序的可靠方法,或者有人已经制作了?请注意,我没有 root 访问权限,如果这很重要,我也在 Solaris 上。

【问题讨论】:

  • 如果您既不需要 PID 文件也不需要搜索进程表,那么您就有了鸡/蛋问题。为了检查某些东西是否正在运行,您需要知道它的 PID。这必须存储在已启动的守护程序和查询程序都可以访问信息的位置。不管你这样做,该信息可以被其他进程删除(简单的rm,从数据库中删除条目,无论如何)。使用 cgroups 等 Linux 特定功能可以实现更多控制(查看 systemd 的作用)。
  • @MoritzBunkus:为了争论,假设其他进程不会删除 pid 文件等。如果他们这样做,我会遇到更大的问题。

标签: perl unix


【解决方案1】:

虽然 pid 被重用,但我相信它们会通过(大)固定大小的集合进行循环。例如在 Solaris 上,这曾经是 30,000(现在可能不同)。因此,在您的 pid 被重用之前,必须启动/完成 30,000 个进程。

Proc::Daemon 使用的方法看起来并不合理,并且是解决此问题的一种相当常见的方法。

【讨论】:

    【解决方案2】:

    我使用的一种方法是让守护进程获得一个文件的排他(写)锁。

    您可以通过尝试自己获取锁来测试是否有人持有锁,并且有多种方法可以获取持有文件锁的进程的 PID - 即 fcntl 和 /proc 中的可能内容。

    一些忠告:

    1. 使用本地文件(即非 NFS)进行锁定。
    2. 确保在守护程序启动之前存在锁定文件。
    3. 永远不要删除锁定文件。

    内核将锁与文件的 inode 号相关联,因此您始终希望锁文件始终具有相同的 inode 号。删除并重新创建锁文件将更改与锁关联的 inode。

    一个简单的保持活动机制可以实现为一个 cron 作业 - cron 作业只是尝试每 N 分钟生成一个守护进程,然后如果它无法获得排他锁,则让守护进程安静地退出。

    【讨论】:

    • 有人实现了吗?我不想重新发明*。
    最近更新 更多