当所需单元停止时,systemd 单元会停止,但当所需单元启动时,systemd 单元不会再次启动

当所需单元停止时,systemd 单元会停止,但当所需单元启动时,systemd 单元不会再次启动

我有一个单元,我将调用它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

让我看看我是否理解了用例:

  1. 启动eth-service时应同时启动eth-servereth-service
  2. 启动eth-server时应同时启动eth-servereth-service
  3. 停止eth-server应该同时停止eth-servereth-service
  4. 停止eth-service应该仅仅是停止eth-service并保持eth-server运行。

您可以通过添加WantedBy=eth-server.service到文件的 [Install] 部分eth-service.serviceWants=eth-service.service[Unit] 部分来实现它eth-server.service

根据systemd 文档 Wants是 的弱化版本Requires,似乎如果Wanted单元停止,请求它的单元不会受到影响。但此设置可能会产生不良副作用,即eth-server无论是否eth-service启动失败, 都会启动。

单元文件示例

以下示例单元文件可以保存在主目录( )中并与参数~/.config/systemd/user一起使用。systemctl --user

这些单元文件描述的服务不执行任何操作,但强制RemainAfterExit=yessystemd 假定该服务仍在运行,即使/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 会认为服务正在运行,直到它们被停止serverserviceexited

$> 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

相关内容