使用 launchd 运行(或仅启动)守护进程

使用 launchd 运行(或仅启动)守护进程

我正在尝试设置YouTrack在 OS X Lion Server 上,使用 启动它launchd。我已下载 YouTrack jar 文件,可以使用 成功从命令行运行java -Xmx512m -jar youtrack.jar 8080。我还将上述运行命令包装在类似于以下的 shell 脚本中youtrack start它基本上允许我使用和与活动实例进行交互youtrack stop。它将进程的进程 ID 存储java在文件中,然后退出以便能够停止正在运行的实例,只允许一个实例等。

为了在启动时运行此命令,我创建了一个简单的 launchd plist 并将其放在 /Library/LaunchDaemons 中,按照 中给出的说明进行操作man launchd.plist。使用的主要键是ProgramArguments( youtrack start) 和RunAtLoad(true)。问题是,从命令行运行时youtrack start将创建一个包含进程 pid 的文件java,我可以在top或中看到此进程ps ax。但是当 lanuchd ( ) 运行该命令时,sudo launchctl load /Library/LaunchDaemons/org.example.youtrack.plist生成的 pid 将与任何正在运行的进程的 pid 不匹配,并且 YouTrack Web 服务器将无法启动。这几乎就像 launchd 启动的 java 进程也会在 launchd 完成后终止一样。

但是,如果我直接将 java 命令放入 launchd plist 中,它就可以正常工作。我只是想了解这是为什么 - 我认为 launchd 的主要目的是启动守护进程。但这是否意味着守护进程必须在其整个生命周期内都在 launchd 中运行?有没有其他使用(或不使用)launchd 启动守护进程的方法,可以让我在启动时简单地运行一次命令?基本上就是我们在早期版本的 OS X 中@roboot使用它的方法。cron

答案1

Launchd 不只是启动程序,它还会在程序运行时对其进行监控。默认情况下,它希望程序继续运行(作为守护进程),而不是启动其他程序(/自身的后台副本/其他程序)并退出。如果程序确实退出,launchd 会执行两项操作,这可能会导致运行并退出的程序出现问题youtrack start:它将“清理”剩余的子进程(如实际的服务器进程),并且(取决于其他一些设置)可能会重试“失败”的程序。有两种方法可以解决这个问题:

  1. 按照 launchd 的方式执行:java -Xmx512m -jar youtrack.jar 8080直接运行 launchd 项(请注意,命令的每个“单词”都应是数组的单独元素ProgramArguments)。如果您将其添加<key>KeepAlive</key><true/>到 launchd .plist,则如果服务器因任何原因崩溃或退出,它将重新启动服务器(请注意,这包括被终止,因此您应该重写youtrack stop以使用launchctl unload ...并让 launchd 执行终止操作)。

  2. 告诉 launchd 不要期望它继续运行,也不要终止子进程。将此添加到 .plist 以关闭默认行为:

    <key>KeepAlive</key>
    <false/>
    <key>AbandonProcessGroup</key>
    <true/>
    

相关内容