我刚刚从 14.04 服务器切换到 16.04 服务器。使用 Upstart 时,我曾经使用 /etc/rcS.d 中名为 M95 的文件启动服务器。M95 由 /etc/rc.local 调用。现在使用 systemd,我在 /etc/systemd/system 中写入了一个名为 my.service 的文件。它看起来像这样:
[Unit]
Description=MyService
[Service]
WorkingDirectory=/etc
ExecStart=/bin/sh rc.local
[Install]
WantedBy=multi-user.target
当我在命令行中输入“/bin/sh rc.local”时,我的服务器确实启动了。当我尝试通过执行“systemctl start my.service”来启动服务时,什么也没发生。
journalctl -b 中的相关行是:
Started MyService.
eth0 ...(basically the info I see from ifconfig)
root : TTY=unknown ; PWD=/etc ; USER=root ; COMMAND=/etc/rcS.d/M95
pam_unix(sudo:session): session opened for user root by (uid=0)
$File not found:: /new/den-routes
udhcpd already running
pam_unix(sudo:session): session closed for user root
/bin/rm: cannot remove '/var/log/rewriting-net-rules': No such file or directory.
在 rc.local 中它看起来像:
#!/bin/sh -e
...
sudo /etc/rcS.d/M95
/bin/rm /var/log/rewriting-net-rules
exit 0
在 M95 中,它启动 udhcpd(“udhcpd 已在运行”消息就是从这里来的),最后通过以下命令启动服务器:
cd /new
/bin/sh StartServer&
看来它确实到达了 M95,因为消息正在从它那里记录下来,但服务器没有启动。当我在命令行中运行这些文件时,它可以工作,但作为服务它不起作用。我对 systemd 非常不熟悉,所以我不知道我是否做得正确。一个星期以来,我一直在阅读它的示例和教程,但我仍然不确定它是如何工作的,以及应该如何编写服务文件。
编辑:这是我的 StartServer 文件:
#!/bin/bash
nohup /jre/jdk1.8.0_101/jre/bin/myserver -Xrs -Xmx1000m -jar /new/MyServer.jar nowd &
当我从命令行启动它时,它运行良好。当我从 my.service 调用它时,它运行良好。我输入了一些 echo 来查看它是否遍历了整个文件,但 myserver 和 MyServer.jar 出于某种原因没有启动。
答案1
天哪,这里有很多事情不对劲。
- 您不是直接运行服务;而是您的服务单元运行
rc.local
在工作目录中解释的 shell/etc
。尽管 systemd 有一个预先提供的服务单元可供运行(/etc/rc.local
如果您真的想要的话)。(rc.local
这种机制在 Ubuntu 上被取代了三次,首先是 van Smoorenburgrc
,然后是 upstart,然后是 systemd。) - 但
/etc/rc.local
也没有运行你的服务。相反,它正在调用sudo
,尽管它是已经以超级用户身份运行。 /etc/rcS.d
尽管该目录是一个符号链接场,不应该包含实际的rc
脚本文件,但这反过来又运行了(第二个)脚本。- 该脚本由 systemd 手动守护进程运行,而 systemd 显然已经将其作为实际服务运行。
- 它认为工作目录
/new
不应该是/etc
。 - 但即使这样也不是你的服务。相反,它正在分叉一个 shell 来解释名为的第三个脚本
StartServer
。 - 它不用于
exec
覆盖自身。 - 它用于
&
异步运行该 shell。 - 然后,第四个脚本分叉并运行 Java 程序。
- 它也不用于
exec
覆盖自身。 - 锦上添花的是还用于
&
异步运行该 Java 程序。
这些都没有必要。
而且,您似乎毫无理由地将它放在了克隆虚拟机中重新设置 MAC 地址的机制中间。
[单元] 文档=https://askubuntu.com/a/831314/43344 之后=udhcpd.service [服务] 工作目录=/new ExecStart=/jre/jdk1.8.0_101/jre/bin/myserver -Xrs -Xmx1000m -jar /new/MyServer.jar nowd [安装] WantedBy=多用户.目标
显然,After=
无论它是什么,都需要添加一些内容来写出den-routes
您的守护进程所期望的文件;但是,您没有提供任何信息来确定它是什么。
进一步阅读
- 乔纳森·德·博因·波拉德(2015年)。 systemd 恐怖屋. 常见问题答案。
- https://askubuntu.com/a/674133/43344
- https://unix.stackexchange.com/a/194653/5132
- https://askubuntu.com/a/626858/43344
- 沃伦·麦克沃伊(2010-10-24)。如何在不改变 70-persistent-net.rules 的情况下克隆 Ubuntu 虚拟机?。
- Chris Stuccio(2011-12-03)。 克隆 Ubuntu VM 时出现网络问题。
答案2
原来问题出在 rc.local 中的一段代码上。有人试图删除文件时输入的一行会产生错误,如果文件不存在,程序就会退出。我不确定为什么我在命令行中运行它时没有产生这个错误,但是当使用服务运行时,它停止了一切工作。
我通过添加 if 语句来修复此问题,以便在尝试删除该文件之前检查该文件是否存在。