运行 - 或仅启动 - 使用 launchd 的守护进程

Sim*_*mon 2 launchd process daemon launchctl macos

我正在尝试在 OS X Lion Server 上设置YouTrack并使用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创建一个包含java进程pid 的文件,我可以在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 启动守护程序的方法,这将允许我在启动时简单地运行一次命令?基本上我们用用做@robootcron早期版本的OS X

Gor*_*son 6

Launchd 不只是启动程序,它还在它们运行时监视它们。默认情况下,它希望程序继续运行(作为守护进程),而不是启动其他程序(/他们自己的背景副本/任何东西)并退出。如果程序确实退出,launchd 会做两件事,这可能会导致运行和退出程序出现问题,例如youtrack start:它会“清理”剩余的子进程(例如实际的服务器进程),并且(取决于其他一些设置)也许重试“失败”的程序。有两种方法可以解决这个问题:

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

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

    <key>KeepAlive</key>
    <false/>
    <key>AbandonProcessGroup</key>
    <true/>
    
    Run Code Online (Sandbox Code Playgroud)