关于Linux中通过 Systemd Path Unit 监听配置文件更新自动重启服务的一些笔记

在路上,我们永远年轻,永远热泪盈眶。 ——杰克·凯鲁亚克

写在前面


  • stackoverflow.comUnix & Linux 社区 看到有小伙伴提出相关的问题。
  • 这里整理分享给小伙伴,博文内容涉及:
    • SystemdPath Units常用命令手册学习
    • Path Units 的应用
    • 通过httpd服务演示监听配置文件自动重启服务
  • 食用方式:需要了解一点 Systemd
  • 理解不足小伙伴帮忙指正

在路上,我们永远年轻,永远热泪盈眶。 ——杰克·凯鲁亚克


了解 SystemdPath Units

在这之前,需要简单的了解一下 SystemdPath Units ,大概熟悉下是什么,Path Units 和我们经常讲的服务 Service units(sshd.service) 同属于 Systemd 的 Units。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
┌──[root@vms83.liruilongs.github.io]-[~]
└─$systemctl status sshd.service
● sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
Active: active (running) since 一 2022-10-24 09:41:59 CST; 1 day 2h ago
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 984 (sshd)
Memory: 4.5M
CGroup: /system.slice/sshd.service
└─984 /usr/sbin/sshd -D

10月 24 09:41:58 vms83.liruilongs.github.io systemd[1]: Starting OpenSSH server daemon...
10月 24 09:41:59 vms83.liruilongs.github.io sshd[984]: Server listening on 0.0.0.0 port 22.
10月 24 09:41:59 vms83.liruilongs.github.io sshd[984]: Server listening on :: port 22.
10月 24 09:41:59 vms83.liruilongs.github.io systemd[1]: Started OpenSSH server daemon.
..........

Service Units 用于封装一个后台服务进程,而 Path Units 用于根据文件或目录变化来启动其他服务,类似一个监听器,面向对象里的观察者设计模式。这里他的通知对象时一个服务(service units)

常用命令

看一些常用的命令,查看当前 Systemd 的所有 Path Units

1
2
3
4
5
6
7
8
9
┌──[root@vms83.liruilongs.github.io]-[~]
└─$systemctl list-unit-files -t path
UNIT FILE STATE
brandbot.path disabled
systemd-ask-password-console.path static
systemd-ask-password-plymouth.path static
systemd-ask-password-wall.path static

4 unit files listed.

查看单元配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
┌──[root@vms83.liruilongs.github.io]-[~]
└─$systemctl cat brandbot.path
# /usr/lib/systemd/system/brandbot.path
[Unit]
Description=Flexible branding

[Path]
PathExists=/var/lib/rhsm/branded_name
PathChanged=/var/lib/rhsm/branded_name

[Install]
WantedBy=multi-user.target
┌──[root@vms83.liruilongs.github.io]-[~]
└─$

正向依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
┌──[root@vms83.liruilongs.github.io]-[~]
└─$systemctl list-dependencies brandbot.path
brandbot.path
● ├─-.mount
● └─sysinit.target
● ├─dev-hugepages.mount
.........
● ├─sys-kernel-debug.mount
● ├─systemd-ask-password-console.path
.......
● ├─local-fs.target
● │ ├─-.mount
● │ ├─rhel-import-state.service
● │ ├─rhel-readonly.service
● │ └─systemd-remount-fs.service
● └─swap.target

反向依赖

1
2
3
4
5
6
7
┌──[root@vms83.liruilongs.github.io]-[~]
└─$systemctl list-dependencies brandbot.path --reverse
brandbot.path
● └─multi-user.target
● └─graphical.target
┌──[root@vms83.liruilongs.github.io]-[~]
└─$

单元状态信息

1
2
3
4
5
6
7
8
9
10
┌──[root@vms83.liruilongs.github.io]-[~]
└─$systemctl status brandbot.path
● brandbot.path - Flexible branding
Loaded: loaded (/usr/lib/systemd/system/brandbot.path; disabled; vendor preset: disabled)
Active: active (waiting) since 一 2022-10-24 09:41:53 CST; 1 day 2h ago

10月 24 09:41:53 vms83.liruilongs.github.io systemd[1]: Started Flexible branding.
10月 24 09:41:53 vms83.liruilongs.github.io systemd[1]: Starting Flexible branding.
┌──[root@vms83.liruilongs.github.io]-[~]
└─$

手册中的介绍

1
2
3
4
5
6
7
┌──[root@vms83.liruilongs.github.io]-[~]
└─$man systemd | grep -A 2 "Path units"
10. Path units may be used to activate other services when file system objects change or are modified. See
systemd.path(5).

┌──[root@vms83.liruilongs.github.io]-[~]
└─$

path 单元。 用于根据文件系统上特定对象的变化来启动其他服务。参见 systemd.path(5) 手册。看下具体的手册

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
┌──[root@vms83.liruilongs.github.io]-[~]
└─$man systemd.path | cat
SYSTEMD.PATH(5) systemd.path SYSTEMD.PATH(5)
。。。。
NAME
systemd.path - Path unit configuration

SYNOPSIS
path.path

DESCRIPTION
# 以 ".path" 为后缀的单元文件, 封装了一组由 systemd 监视的文件系统路径,以支持基于路径的启动。
A unit configuration file whose name ends in ".path" encodes information about a path monitored by systemd, for
path-based activation.

# 本手册列出了所有专用于此类单元的 配置选项(亦称"配置指令"或"单元属性")。 systemd.unit(5) 中描述了通用于所有单元类型的配置选项,
# 它们位于 [Unit] 与 [Install] 小节。此类单元专用的配置选项 位于 [Path] 小节。
This man page lists the configuration options specific to this unit type. See systemd.unit(5) for the common options of
all unit configuration files. The common configuration items are configured in the generic [Unit] and [Install]
sections. The path specific configuration options are configured in the [Path] section.


# 每个路径单元都必须有一个与其匹配的单元, 以用于在路径发生变化时启动。 匹配的单元可以通过 Unit= 选项(见下文)明确指定。
# 若未指定,则默认是与该单元名称相同的 .service 单元(不算后缀)。 例如 foo.path 默认匹配 foo.service 单元。
For each path file, a matching unit file must exist, describing the unit to activate when the path changes. By default,
a service by the same name as the path (except for the suffix) is activated. Example: a path file foo.path activates a
matching service foo.service. The unit to activate may be controlled by Unit= (see below).

# 因为在单元内部实际上使用内核的 inotify(7) 函数监视文件系统的变化, 所以,受制于 inotify 的缺陷,
# 只能监视本机文件系统的变化, 而不能监视远程网络文件系统的变化。
Internally, path units use the inotify(7) API to monitor file systems. Due to that, it suffers by the same limitations
as inotify, and for example cannot be used to monitor files or directories changed by other machines on remote NFS file
systems.

If a path unit is beneath another mount point in the file system hierarchy, a dependency between both units is created
automatically.

# 除非明确设置了 DefaultDependencies=no ,否则 path 单元将会自动添加下列依赖关系:

#Before=paths.target, After=sysinit.target, Requires=sysinit.target, Conflicts=shutdown.target, Before=shutdown.target ,
# 以确保该单元在关机前可以被干净的关闭。 只有那些在系统启动早期就必须启动的路径,以及那些必须在关机流程结尾才能停止的路径才需要设置

Unless DefaultDependencies=false is used, path units will implicitly have dependencies of type Conflicts= and Before=
on shutdown.target. These ensure that path units are terminated cleanly prior to system shutdown. Only path units
involved with early boot or late system shutdown should disable this option.

OPTIONS
# 路径单元文件必须包含一个 [Path] 部分,其中包含有关它监视的一个或多个路径的信息。
# 特定于路径单元的 [Path] 部分的选项如下:
Path files must include a [Path] section, which carries information about the path(s) it monitors. The options specific
to the [Path] section of path units are the following:

PathExists=, PathExistsGlob=, PathChanged=, PathModified=, DirectoryNotEmpty=
# 定义监视哪种类型的路径变化:
# PathExists= 监视指定的路径是否存在, 若存在则启动匹配单元。
# PathExistsGlob= 监视是否存在至少一个与模式匹配的路径,若存在则启动匹配单元。
# PathChanged= 监视指定路径的写入句柄是否恰好被关闭, 若存在写入句柄且恰好被关闭, 则启动匹配单元。
# PathModified= 监视指定路径的最后修改时间是否发生变化, 若发生变化则启动匹配单元。
# DirectoryNotEmpty= 监视指定的文件夹是否非空,若包含至少一个文件或子目录, 则启动匹配单元。

Defines paths to monitor for certain changes: PathExists= may be used to watch the mere existence of a file or
directory. If the file specified exists, the configured unit is activated. PathExistsGlob= works similar, but
checks for the existence of at least one file matching the globbing pattern specified. PathChanged= may be used to
watch a file or directory and activate the configured unit whenever it changes. It is not activated on every write
to the watched file but it is activated if the file which was open for writing gets closed. PathModified= is
similar, but additionally it is activated also on simple writes to the watched file. DirectoryNotEmpty= may be
used to watch a directory and activate the configured unit whenever it contains at least one file.

# 所有这些选项的值 都必须是绝对路径。
The arguments of these directives must be absolute file system paths.

# 可以多次使用这些选项 以监控多个路径。 如果为某个选项指定了一个空字符串, 则表示清空该选项 之前设置的所有监视路径。
Multiple directives may be combined, of the same and of different types, to watch multiple paths. If the empty
string is assigned to any of these options, the list of paths to watch is reset, and any prior assignments of these
options will not have any effect.


# 如果在启动 path 单元时, 指定的路径已经存在(对于 PathExists= 与 PathExistsGlob= 来说)
# 或者 指定的目录非空(对于 DirectoryNotEmpty= 来说), 那么将会立即同时启动匹配单元。 不过,
# 对于 PathChanged= 与 PathModified= 来说,并不遵守这个规则。
If a path already exists (in case of PathExists= and PathExistsGlob=) or a directory already is not empty (in case
of DirectoryNotEmpty=) at the time the path unit is activated, then the configured unit is immediately activated as
well. Something similar does not apply to PathChanged= and PathModified=.


# 如果没有权限监视指定的路径, 那么 systemd 将会 一直等待权限满足之后 才会开始监视。
If the path itself or any of the containing directories are not accessible, systemd will watch for permission

changes and notice that conditions are satisfied when permissions allow that.

Unit=
# 该路径单元的匹配单元, 也就是被路径的变化启动的单元。 参数是一个不以 ".path" 结尾的单元名。
# 默认值是与此路径单元同名的服务单元(见上文)。
# 建议将路径单元的名字 与被该路径启动的匹配单元的名字 保持一致 (也就是仅单元后缀名不同)。
The unit to activate when any of the configured paths changes. The argument is a unit name, whose suffix is not
".path". If not specified, this value defaults to a service that has the same name as the path unit, except for the
suffix. (See above.) It is recommended that the unit name that is activated and the unit name of the path unit are
named identical, except for the suffix.

MakeDirectory=
# 接受一个布尔值。 设为 yes 表示如果指定的目录不存在则首先创建它然后再监视它。 此选项对 PathExists= 无效。 默认值为 no
Takes a boolean argument. If true, the directories to watch are created before watching. This option is ignored for
PathExists= settings. Defaults to false.

DirectoryMode=
# 选项指定在 MakeDirectory= 时新建目录的权限(八进制表示法)。 默认值是 0755
If MakeDirectory= is enabled, use the mode specified here to create the directories in question. Takes an access
mode in octal notation. Defaults to 0755.

SEE ALSO
systemd(1), systemctl(1), systemd.unit(5), systemd.service(5), inotify(7), systemd.directives(7)



systemd 219 SYSTEMD.PATH(5)
┌──[root@vms83.liruilongs.github.io]-[~]
└─$

OK,很全面的一个帮助文档,如果希望了解 Path Units ,需要耐心的看完它

Path Units 的应用

监控文件变化发送告警邮件

看一个Demo:

这里我们通过 监听 /etc/passwd 的变化来创建一个 update-user-info.path Path Units, 实现这文件变化时,发送告警邮件,所以我们需要一个可以发送告警的服务 update-user-info.service Services Units 。用于 Path unids 启动。

需要做下面一些工作:

  • 创建一个 服务单元 update-user-info.service
  • 创建服务调用的脚本:email-alert.sh
  • 创建一个 路径单元:update-user-info.path

发送邮件,如果没有邮件服务器,可能需要搭建一个空客户端的邮件服务器,如果有的可以忽略这部分,这里主要用到 postfixmailx

安装 postfix 邮件服务器

1
2
┌──[root@vms82.liruilongs.github.io]-[/var/spool/mail]
└─$yum -y install postfix

相关配置,下面是没有DNS服务器的配置

1
2
3
4
5
6
7
8
9
10
11
┌──[root@vms82.liruilongs.github.io]-[~]
└─$postconf mynetworks
mynetworks = 127.0.0.0/8 [::1]/128
┌──[root@vms82.liruilongs.github.io]-[~]
└─$postconf -e 'inet_interfaces = loopback-only'
┌──[root@vms82.liruilongs.github.io]-[~]
└─$postconf -e ' relayhost = [smtp.vms82.liruilongs.github.io]'
┌──[root@vms82.liruilongs.github.io]-[~]
└─$postconf -e 'mydestination = vms82.liruilongs.github.io'
┌──[root@vms82.liruilongs.github.io]-[~]
└─$systemctl restart postfix

处理邮件需要的工具

1
2
┌──[root@vms82.liruilongs.github.io]-[~]
└─$yum -y install mailx

测试一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
┌──[root@vms82.liruilongs.github.io]-[~]
└─$mail -s 'init test' tom@vms82.liruilongs.github.io
test
.
EOT
┌──[root@vms82.liruilongs.github.io]-[~]
└─$cat /var/spool/mail/tom
From root@vms82.liruilongs.github.io Mon Oct 24 15:39:25 2022
Return-Path: <root@vms82.liruilongs.github.io>
X-Original-To: tom@vms82.liruilongs.github.io
Delivered-To: tom@vms82.liruilongs.github.io
Received: by vms82.liruilongs.github.io (Postfix, from userid 0)
id C7A2A1002EF2A; Mon, 24 Oct 2022 15:39:25 +0800 (CST)
Date: Mon, 24 Oct 2022 15:39:25 +0800
To: tom@vms82.liruilongs.github.io
Subject: init test
User-Agent: Heirloom mailx 12.5 7/5/10
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-Id: <20221024073925.C7A2A1002EF2A@vms82.liruilongs.github.io>
From: root@vms82.liruilongs.github.io (root)

test

OK,测试没有问题的话,我们需要编写一个脚本,这里需要非交互式的方式来发送告警邮件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
┌──[root@vms82.liruilongs.github.io]-[~]
└─$mail --help
mail: illegal option -- -
Usage: mail -eiIUdEFntBDNHRVv~ -T FILE -u USER -h hops -r address -s SUBJECT -a FILE -q FILE -f FILE -A ACCOUNT -b USERS -c USERS -S OPTION users
┌──[root@vms82.liruilongs.github.io]-[~]
└─$vim email-alert.sh
┌──[root@vms82.liruilongs.github.io]-[~]
└─$cat email-alert.sh
#!/bin/bash

#@File : bash.sh
#@Time : 2022/10/25 20:47:04
#@Author : Li Ruilong
#@Version : 1.0
#@Desc : None
#@Contact : 1224965096@qq.com

# -s :指定邮件主题

mail -s "ETC PASSWD CHANGED ON $(hostname) $(date '+%x %X')" tom@vms82.liruilongs.github.io < /etc/passwd
┌──[root@vms82.liruilongs.github.io]-[~]
└─$mv email-alert.sh /usr/local/bin/
┌──[root@vms82.liruilongs.github.io]-[~]
└─$

创建服务单元文件以执行脚本, 唯一需要关注的是 ExecStart=/usr/local/bin/email-alert.sh 指定启动进程的命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌──[root@vms82.liruilongs.github.io]-[~]
└─$cd /usr/lib/systemd/system/
┌──[root@vms82.liruilongs.github.io]-[/usr/lib/systemd/system]
└─$vim update-user-info.service
┌──[root@vms82.liruilongs.github.io]-[/usr/lib/systemd/system]
└─$cat /usr/lib/systemd/system/update-user-info.service

[Unit]
Description="Run script to send email alert"
After=network-online.target

[Service]
ExecStart=/usr/local/bin/email-alert.sh
ExecStop=/bin/kill -WINCH ${MAINPID}


[Install]
WantedBy=multi-user.target
┌──[root@vms82.liruilongs.github.io]-[/usr/lib/systemd/system]
└─$

创建路径单元文件,具体的参数小伙伴可以看上面的帮助文档,简单说明:PathModified 指定监控的文件,Unit指定激活的服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
┌──[root@vms82.liruilongs.github.io]-[/usr/lib/systemd/system]
└─$fg
vim update-user-info.path
┌──[root@vms82.liruilongs.github.io]-[/usr/lib/systemd/system]
└─$cat /usr/lib/systemd/system/update-user-info.path
[Unit]
Description="Monitor the /etc/passwd file for changes"

[Path]
PathModified=/etc/passwd
Unit=update-user-info.service

[Install]
WantedBy=multi-user.target
┌──[root@vms82.liruilongs.github.io]-[/usr/lib/systemd/system]
└─$

文件语法校验

1
2
3
4
5
6
7
8
9
┌──[root@vms82.liruilongs.github.io]-[/usr/lib/systemd/system]
└─$systemd-analyze verify /usr/lib/systemd/system/update-user-info.*
update-user-info.service: command /usr/local/bin/email-alert.sh is not executable: 权限不够
┌──[root@vms82.liruilongs.github.io]-[/usr/lib/systemd/system]
└─$chmod +x /usr/local/bin/email-alert.sh
┌──[root@vms82.liruilongs.github.io]-[/usr/lib/systemd/system]
└─$systemd-analyze verify /usr/lib/systemd/system/update-user-info.*
┌──[root@vms82.liruilongs.github.io]-[/usr/lib/systemd/system]
└─$

启动 update-user-info.path 并设置开启自启

1
2
3
┌──[root@vms82.liruilongs.github.io]-[/usr/lib/systemd/system]
└─$systemctl enable update-user-info.path --now
Created symlink from /etc/systemd/system/multi-user.target.wants/update-user-info.path to /usr/lib/systemd/system/update-user-info.path.

添加用户测试

1
2
3
4
┌──[root@vms82.liruilongs.github.io]-[/usr/lib/systemd/system]
└─$useradd shanheyiwuyang
┌──[root@vms82.liruilongs.github.io]-[/usr/lib/systemd/system]
└─$

查看服务路径启动情况

1
2
3
4
5
┌──[root@vms82.liruilongs.github.io]-[/usr/lib/systemd/system]
└─$journalctl -u update-user-info.path
-- Logs begin at 一 2022-10-24 09:41:47 CST, end at 二 2022-10-25 17:57:25 CST. --
10月 25 16:37:42 vms82.liruilongs.github.io systemd[1]: Started "Monitor the /etc/passwd file for chang
10月 25 16:37:42 vms82.liruilongs.github.io systemd[1]: Starting "Monitor the /etc/passwd file for chan
1
2
3
4
5
┌──[root@vms82.liruilongs.github.io]-[/usr/lib/systemd/system]
└─$journalctl -u update-user-info.service
-- Logs begin at 一 2022-10-24 09:41:47 CST, end at 二 2022-10-25 17:57:31 CST. --
10月 25 16:38:26 vms82.liruilongs.github.io systemd[1]: Started "Run script to send email alert".
10月 25 16:38:26 vms82.liruilongs.github.io systemd[1]: Starting "Run script to send email alert"...

邮件发送情况

1
2
3
4
5
6
┌──[root@vms82.liruilongs.github.io]-[/usr/lib/systemd/system]
└─$tail -n 5 /var/mail/tom
tomcat:x:53:53:Apache Tomcat:/usr/share/tomcat:/sbin/nologin
sy:x:1004:1004::/home/sy:/bin/bash
shanhewuyang:x:1005:1005::/home/shanhewuyang:/bin/bash
shanheyiwuyang:x:1006:1006::/home/shanheyiwuyang:/bin/bash

监听配置文件自动重启服务

来看另一个 path units 的应用,对于监听配置文件跟新自动重启服务来讲,只需要两个操作:

  • 创建一个监听配置文件的 路径单元
  • 创建一个重启指定服务的服务单元

这里我们以httpd服务为Demo

服务准备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
┌──[root@vms152.liruilongs.github.io]-[~]
└─$rpm -q httpd
package httpd is not installed
┌──[root@vms152.liruilongs.github.io]-[~]
└─$yum -y install httpd
┌──[root@vms152.liruilongs.github.io]-[~]
└─$systemctl start httpd
┌──[root@vms152.liruilongs.github.io]-[~]
└─$systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: active (running) since 二 2022-10-25 17:12:10 CST; 4s ago
Docs: man:httpd(8)
man:apachectl(8)
Main PID: 6264 (httpd)
Status: "Processing requests..."
CGroup: /system.slice/httpd.service
├─6264 /usr/sbin/httpd -DFOREGROUND
├─6265 /usr/sbin/httpd -DFOREGROUND
├─6266 /usr/sbin/httpd -DFOREGROUND
├─6267 /usr/sbin/httpd -DFOREGROUND
├─6268 /usr/sbin/httpd -DFOREGROUND
└─6269 /usr/sbin/httpd -DFOREGROUND

10月 25 17:12:09 vms152.liruilongs.github.io systemd[1]: Starting The Apache HTTP Server...
10月 25 17:12:10 vms152.liruilongs.github.io systemd[1]: Started The Apache HTTP Server.
┌──[root@vms152.liruilongs.github.io]-[~]
└─$ss -nutlpa | grep http
tcp LISTEN 0 128 :::80 :::* users:(("httpd",pid=6269,fd=4),("httpd",pid=6268,fd=4),("httpd",pid=6267,fd=4),("httpd",pid=6266,fd=4),("httpd",pid=6265,fd=4),("httpd",pid=6264,fd=4))
┌──[root@vms152.liruilongs.github.io]-[~]
└─$

创建路径单元

需要监听的配置文件 /etc/httpd/conf/httpd.conf,需要通知的服务httpd-restart.service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
┌──[root@vms152.liruilongs.github.io]-[~]
└─$fg
vim /usr/lib/systemd/system/httpd-restart.path
┌──[root@vms152.liruilongs.github.io]-[~]
└─$cat /usr/lib/systemd/system/httpd-restart.path
[Unit]
Description="change httpd conf"
After=network-online.target

[Path]
Unit=httpd-restart.service
PathChanged=/etc/httpd/conf/httpd.conf

[Install]
WantedBy=multi-user.target
┌──[root@vms152.liruilongs.github.io]-[~]
└─$

创建服务单元

重启服务单元: httpd-restart.service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
┌──[root@vms152.liruilongs.github.io]-[~]
└─$vim /usr/lib/systemd/system/httpd-restart.service
┌──[root@vms152.liruilongs.github.io]-[~]
└─$cat /usr/lib/systemd/system/httpd-restart.service
[Unit]
Description= update httpd config , restart httpd service
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl restart httpd.service

[Install]
WantedBy=multi-user.target
┌──[root@vms152.liruilongs.github.io]-[~]
└─$

测试单元文件

1
2
3
4
┌──[root@vms152.liruilongs.github.io]-[~]
└─$systemd-analyze verify /usr/lib/systemd/system/httpd-restart.*
┌──[root@vms152.liruilongs.github.io]-[~]
└─$

查看当前服务进程ID

1
2
3
4
5
6
7
8
9
10
┌──[root@vms152.liruilongs.github.io]-[~]
└─$systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: active (running) since 二 2022-10-25 17:12:10 CST; 1h 19min ago
Docs: man:httpd(8)
man:apachectl(8)
Main PID: 6264 (httpd)
Status: "Total requests: 9; Current requests/sec: 0; Current traffic: 0 B/sec"
10月 25 17:12:10 vms152.liruilongs.github.io systemd[1]: Started The Apache HTTP Server.

修改配置文件,替换端口

1
2
3
4
5
┌──[root@vms152.liruilongs.github.io]-[~]
└─$sed 's/^Listen 80/Listen 8023/g' /etc/httpd/conf/httpd.conf | grep ^Listen
Listen 8023
┌──[root@vms152.liruilongs.github.io]-[~]
└─$sed 's/^Listen 80/Listen 8023/g' /etc/httpd/conf/httpd.conf -i

再次查看,PID发生变化,说明重启成功

1
2
3
4
5
6
7
8
9
10
11
┌──[root@vms152.liruilongs.github.io]-[~]
└─$systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: active (running) since 二 2022-10-25 18:32:55 CST; 2s ago
Docs: man:httpd(8)
man:apachectl(8)
Process: 6420 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited, status=0/SUCCESS)
Main PID: 6425 (httpd)
10月 25 18:32:55 vms152.liruilongs.github.io systemd[1]: Starting The Apache HTTP Server...
10月 25 18:32:55 vms152.liruilongs.github.io systemd[1]: Started The Apache HTTP Server.

查看新建单元的日志

1
2
3
4
5
6
7
8
9
10
11
┌──[root@vms152.liruilongs.github.io]-[~]
└─$journalctl -u httpd-restart.path
-- Logs begin at 三 2022-10-19 16:32:20 CST, end at 二 2022-10-25 18:32:55 CST. --
10月 25 18:32:40 vms152.liruilongs.github.io systemd[1]: Started "change httpd conf".
10月 25 18:32:40 vms152.liruilongs.github.io systemd[1]: Starting "change httpd conf".
┌──[root@vms152.liruilongs.github.io]-[~]
└─$journalctl -u httpd-restart.service
-- Logs begin at 三 2022-10-19 16:32:20 CST, end at 二 2022-10-25 18:32:55 CST. --
10月 25 18:32:54 vms152.liruilongs.github.io systemd[1]: Starting update httpd config , restart httpd s10月 25 18:32:55 vms152.liruilongs.github.io systemd[1]: Started update httpd config , restart httpd se
┌──[root@vms152.liruilongs.github.io]-[~]
└─$

博文引用的资源


systemd.path 中文手册:译者:金步国 :http://www.jinbuguo.com/systemd/systemd.path.html

systemd.path — Path unit configuration :https://www.freedesktop.org/software/systemd/man/systemd.path.html

Using systemd Path Units to Monitor Files and Directories :https://www.putorius.net/systemd-path-units.html

How to automatically restart systemd service if file is changed? :https://unix.stackexchange.com/questions/722209/how-to-automatically-restart-systemd-service-if-file-is-changed/722223#722223

关于Linux中通过 Systemd Path Unit 监听配置文件更新自动重启服务的一些笔记

https://liruilongs.github.io/2022/10/24/Linux/关于Linux中通过 Systemd Path Unit 监听配置文件自动重启服务的一些笔记/

发布于

2022-10-24

更新于

2023-06-21

许可协议

评论
Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×