我有一个单元,我将调用它eth-service
,它需要另一个单元,我将调用它eth-server
。在单元文件中,eth-service
我有
Requires=eth-server.service
After=eth-server.service
现在,当我运行 时systemctl stop eth-server
,它eth-service
也会停止,这是理所当然的。但是,稍后当我运行 时systemctl start eth-server
,不幸的eth-service
是它仍处于非活动状态,所以我必须记得重新启动它。
我正在尝试使我的单元文件设置尽可能简单 (尤其是对我自己而言) - 是否可以设置我的单元文件,以便当服务器启动时,服务也会启动?如果我将以下内容放入我的eth-server
单元文件中:
Requires=eth-service.service
Before=eth-service.service
这样它们就互相需要,这会导致服务在服务器启动时启动,但这也意味着当我运行时它systemctl stop eth-service
也会eth-server
停止,因为它现在需要该服务,这是不可取的。
答案1
让我看看我是否理解了用例:
- 启动
eth-service
时应同时启动eth-server
和eth-service
。 - 启动
eth-server
时应同时启动eth-server
和eth-service
。 - 停止
eth-server
应该同时停止eth-server
和eth-service
。 - 停止
eth-service
应该仅仅是停止eth-service
并保持eth-server
运行。
您可以通过添加WantedBy=eth-server.service
到文件的 [Install] 部分eth-service.service
或Wants=eth-service.service
[Unit] 部分来实现它eth-server.service
。
根据systemd 文档 Wants
是 的弱化版本Requires
,似乎如果Wanted
单元停止,请求它的单元不会受到影响。但此设置可能会产生不良副作用,即eth-server
无论是否eth-service
启动失败, 都会启动。
单元文件示例
以下示例单元文件可以保存在主目录( )中并与参数~/.config/systemd/user
一起使用。systemctl --user
这些单元文件描述的服务不执行任何操作,但强制RemainAfterExit=yes
systemd 假定该服务仍在运行,即使/bin/true
命令执行后没有挂起。
etc-service.service
[Unit]
Description=eth Service
Requires=eth-server.service
[Service]
Type=oneshot
ExecStart=/bin/true
RemainAfterExit=yes
[Install]
WantedBy=eth-server.service
eth-server.服务
[Unit]
Description=eth Server
[Service]
Type=oneshot
ExecStart=/bin/true
RemainAfterExit=yes
使用 启用eth-service.service
模块systemctl --user enable eth-service.service
。
以下是启动/停止服务测试的输出:
初始状态
$> systemctl --user status eth-service
● eth-service.service - eth Service
Loaded: loaded (/home/ektich/.config/systemd/user/eth-service.service; enabled; vendor preset: enabled)
Active: inactive (dead)
$> systemctl --user status eth-server
● eth-server.service - eth Server
Loaded: loaded (/home/ektich/.config/systemd/user/eth-server.service; static; vendor preset: enabled)
Active: inactive (dead)
在执行下面两段命令之前系统返回初始状态。
systemctl --user 启动 eth-service.service
和都已启动(忽略以下行:服务器和服务都是 /bin/true 的执行,一旦完成就会退出,但单元文件已写入,因此 systemd 会认为服务正在运行,直到它们被停止server
)service
exited
$> systemctl --user start eth-service.service
$> systemctl --user status eth-service
● eth-service.service - eth Service
Loaded: loaded (/home/ektich/.config/systemd/user/eth-service.service; enabled; vendor preset: enabled)
Active: active (exited) since Tue 2018-05-29 20:50:01 IST; 28s ago
Process: 1578 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 1578 (code=exited, status=0/SUCCESS)
$> systemctl --user status eth-server
● eth-server.service - eth Server
Loaded: loaded (/home/ektich/.config/systemd/user/eth-server.service; static; vendor preset: enabled)
Active: active (exited) since Tue 2018-05-29 20:50:01 IST; 2min 59s ago
Process: 1579 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 1579 (code=exited, status=0/SUCCESS)
systemctl --user 启动 eth-server.service
两个服务都启动了:
$> systemctl --user start eth-server.service
$> systemctl --user status eth-service
● eth-service.service - eth Service
Loaded: loaded (/home/ektich/.config/systemd/user/eth-service.service; enabled; vendor preset: enabled)
Active: active (exited) since Tue 2018-05-29 20:56:03 IST; 7s ago
Process: 1681 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 1681 (code=exited, status=0/SUCCESS)
$> systemctl --user status eth-server
● eth-server.service - eth Server
Loaded: loaded (/home/ektich/.config/systemd/user/eth-server.service; static; vendor preset: enabled)
Active: active (exited) since Tue 2018-05-29 20:56:03 IST; 12s ago
Process: 1680 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 1680 (code=exited, status=0/SUCCESS)
以下两节中的命令在两个服务均运行时执行:
systemctl --user 停止 eth-server.service
$> systemctl --user status eth-service
● eth-service.service - eth Service
Loaded: loaded (/home/ektich/.config/systemd/user/eth-service.service; enabled; vendor preset: enabled)
Active: inactive (dead)
$> systemctl --user status eth-server
● eth-server.service - eth Server
Loaded: loaded (/home/ektich/.config/systemd/user/eth-server.service; static; vendor preset: enabled)
Active: inactive (dead)
您可以看到两个服务都已停止
systemctl --user 停止 eth 服务
$> systemctl --user stop eth-service
$> systemctl --user status eth-service
● eth-service.service - eth Service
Loaded: loaded (/home/ektich/.config/systemd/user/eth-service.service; enabled; vendor preset: enabled)
Active: inactive (dead) since Tue 2018-05-29 21:05:25 IST; 34s ago
Process: 1800 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 1800 (code=exited, status=0/SUCCESS)
May 29 21:04:23 ektich systemd[479]: Starting eth Service...
May 29 21:04:23 ektich systemd[479]: Started eth Service.
May 29 21:05:25 ektich systemd[479]: Stopped eth Service.
$> systemctl --user status eth-server
● eth-server.service - eth Server
Loaded: loaded (/home/ektich/.config/systemd/user/eth-server.service; static; vendor preset: enabled)
Active: active (exited) since Tue 2018-05-29 21:04:23 IST; 2min 58s ago
Process: 1799 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 1799 (code=exited, status=0/SUCCESS)
May 29 21:04:23 ektich systemd[479]: Starting eth Server...
May 29 21:04:23 ektich systemd[479]: Started eth Server.
您可以看到eth-service
已停止 ( Active: inactive (dead)
) 但eth-server
仍在“运行”( Active: active
)
与其他情况相比, status 命令etc-service
产生的输出更多,我猜是因为“事务”尚未完成(etc-server
仍在运行)。额外的行journalctl
显示,就 systemd 而言,其中一个服务已停止,另一个仍在运行。
PS根据systemd 主页它的拼写systemd, 不是系统D(只是吹毛求疵)
答案2
一般而言systemctl start xxx
不会恢复先前 的效果systemctl stop xxx
。
管理人员需要在其职业生涯中以某种方式学习这一点。好消息是,这真的很容易学习,因为反馈是即时的。
恢复手动停止和手动启动的一种方法是:
systemctl default
但这种方法并非万无一失,因为它停止不已启用,例如在各种集群下运行的服务(特别是起搏器甚至不将其视为问题/故障并且不会对其做出反应 - 它将其视为预期的管理操作)。
作为服务的作者,你能做些什么来让它万无一失?其他程序员的处理方式是避免任何依赖关系,并倾向于将多个进程打包到单个伞状服务中。在默认的 RHEL7 安装中,没有服务依赖关系根本. 例如后缀:
$ systemctl status postfix
[...] Tasks: 3
CGroup: /system.slice/postfix.service
├─1288 /usr/libexec/postfix/master -w
├─1290 qmgr -l -t unix -u
└─7340 pickup -l -t unix -u
$ cat /usr/lib/systemd/system/postfix.service
[Unit]
Description=Postfix Mail Transport Agent
After=syslog.target network.target
Conflicts=sendmail.service exim.service
[Service]
Type=forking
PIDFile=/var/spool/postfix/pid/master.pid
EnvironmentFile=-/etc/sysconfig/network
ExecStartPre=-/usr/libexec/postfix/aliasesdb
ExecStartPre=-/usr/libexec/postfix/chroot-update
ExecStart=/usr/sbin/postfix start
ExecReload=/usr/sbin/postfix reload
ExecStop=/usr/sbin/postfix stop
[Install]
WantedBy=multi-user.target