systemd服务启动问题

13

这是我第一次使用systemd,对某些事情有点不确定。

我设置了一个服务(用于在tomcat下运行geoserver):

[Unit]
Description=Geoserver
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/geoserver/bin/startup-optis.sh
ExecStop=/usr/local/geoserver/bin/shutdown-optis.sh
User=geoserver

[Install]
WantedBy=multi-user.target

启动脚本使用exec运行java/tomcat。从命令行启动服务似乎可以工作:

 sudo systemctl start geoserver

然而,该命令在我按下ctrl-c之前不会返回,这对我来说似乎不正确。但是Java进程在此之后仍在运行,并正常工作。我不愿意重新启动计算机来测试它,以防这会在初始化期间造成问题,因为它是一台远程计算机,让别人解决会很麻烦。

1个回答

22

你需要在"Service"部分设置正确的"Type":

[Service]
...
Type=simple
...

Type

配置此服务单元的进程启动类型。可以是 simple、forking、oneshot、dbus、notify 或 idle 中的一个。

如果设置为 simple(既未指定 Type= 和 BusName=,也未指定 ExecStart=,则为默认值),则期望通过 ExecStart= 配置的进程是服务的主进程。在此模式下,如果该进程向系统中的其他进程提供功能,则它的通信渠道应在守护程序启动之前安装(例如,systemd 通过套接字激活设置的套接字),因为 systemd 将立即开始启动后续单元。

如果设置为 forking,则期望通过 ExecStart= 配置的进程在启动时调用 fork()。当启动完成并且所有通信渠道都已设置时,父进程预计会退出。子进程将继续作为主要守护进程运行。这是传统 UNIX 守护进程的行为。如果使用此设置,则建议还使用 PIDFile= 选项,以便 systemd 可以识别守护进程的主进程。在父进程退出后,systemd 将继续启动后续单元。

oneshot 的行为类似于 simple;但是,预计进程必须在 systemd 启动后续单元之前退出。RemainAfterExit= 对于此类型的服务尤其有用。如果既未指定 Type= 也未指定 ExecStart=,则这是隐含的默认值。

dbus 的行为类似于 simple;但是,期望守护进程在 D-Bus 总线上获取名称,如 BusName= 配置所示。当 D-Bus 总线名称被获取后,systemd 将继续启动后续单元。使用此选项配置的服务单元隐式获得对 dbus.socket 单元的依赖关系。如果指定了 BusName=,则该类型是默认值。

notify 的行为类似于 simple;但是,预计守护进程在完成启动时通过 sd_notify(3) 或等效调用发送通知消息。发送此通知消息后,systemd 将继续启动后续单元。如果使用此选项,则应将 NotifyAccess=(请参见下文)设置为打开对 systemd 提供的通知套接字的访问权限。如果未设置 NotifyAccess=,则将隐式设置为 main。请注意,如果与 PrivateNetwork=yes 组合使用,当前不支持 Type=notify。

idle 的行为与 simple 非常相似;但是,服务二进制文件的实际执行被延迟到所有作业都被分派之后。这可以用来避免 shell 服务的输出与控制台上的状态输出交错。


非常感谢,它管用了。我以为我尝试过了(和许多其他排列方式),可能我忘记重新加载了。 - vickirk

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