
前言 链接到标题
本文主要包含内容如下:
-
Systemd是什么? -
Systemd常用命令。 -
Systemd系统资源Unit(单位)。 -
Systemd系统资源管理 - 动手配置,实现开机自启动 Node.js 服务。
一,Systemd 概述 链接到标题
1.1. 基本介绍 链接到标题
Systemd (System Daemon),根据 Linux 命名惯例,字母 d 是守护进程 daemon 的缩写。如 Systemd 名字的含义一样,它作为 PID 1 进程,守护整个系统。Systemd 是一系列工具的集合,其作用也远远不仅是启动操作系统,它还接管了后台服务、结束、状态查询,以及日志归档、设备管理、电源管理、定时任务等许多职责。
systemd 由 Lennart Poettering 带头开发,并在 LGPL 2.1 及其后续版本许可证下开源发布。systemd 已纳入众多 Linux 发行版的软件源中。
1.2. 特点介绍 链接到标题
缺点是体系庞大,非常复杂。
Systemd的优点是功能强大,使用方便。其优点介绍如下:
更少的进程
Systemd提供了服务按需启动的能力。允许更多的进程并行启动 在
SysV-init时代,将每个服务项目编号依次执行启动脚本。而Systemd通过 Socket 缓存、DBus 缓存和建立临时挂载点等方法进一步解决了启动进程之间的依赖,做到了所有系统服务并发启动。使用
CGroup跟踪和管理进程的生命周期Systemd提供通过CGroup跟踪进程关系。CGroup不仅能够实现服务之间访问隔离,限制特定应用程序对系统资源的访问配额,还能更精确地管理服务的生命周期。统一管理服务日志
Systemd提供了一个专用的系统日志管理服务:Journald。其使用二进制格式保存所有的日志信息,因而日志内容很难被手工伪造。
1.3. 架构图 链接到标题
下图 是 Systemd 的架构图(来自网络)

二,Systemd 常用命令 链接到标题
Systemd 并不是一个命令,而是一组命令,涉及到系统管理的方方面面,是一系列工具的集合。
2.1. systemctl 链接到标题
systemctl 是 Systemd 的主要命令,用于系统与服务管理。点击查看命令描述文档
- 命令语法
$ systemctl [OPTIONS...] COMMAND [UNIT...]
- 常用命令
下述命令以 Unit
nginx.service为列,后续会详细介绍 Unit。
# 重启系统
$ systemctl reboot
# 启用一个或多个单元或单元实例
$ systemctl enable nginx.service
# 禁用一个或多个单位
$ systemctl disable nginx.service
# 重新启用一个或多个单位
$ systemctl reenable nginx.service
# 重新载入 unit 配置
$ systemctl daemon-reload
# 启动 unit 资源
$ systemctl start nginx.service
# 重启一个服务
$ systemctl restart nginx.service
# 重新加载一个服务的配置文件
$ systemctl reload nginx.service
# 停止 unit 资源
$ systemctl stop nginx.service
# 查看 unit 资源 状态
$ systemctl status nginx.service
# 杀死一个服务的所有子进程
$ systemctl kill nginx.service
# 命令行输出 unit 配置
$ systemctl cat nginx.service
# 显示 systemd Manager 环境块
$ systemctl show-environment
# 列出 systemd 当前在内存中的 unit
$ systemctl list-units
# 查看 Unit 存在依赖关系
$ systemctl list-dependencies nginx.service
# 显示某个 Unit 的所有底层参数
$ systemctl show nginx.service
2.2. systemd-analyze 链接到标题
systemd-analyze 分析和调试系统管理。点击查看命令描述文档
- 命令语法
$ systemd-analyze [OPTIONS...] [time]
$ systemd-analyze [OPTIONS...] blame
$ systemd-analyze [OPTIONS...] critical-chain [UNIT...]
- 常用命令
# 查看启动耗时
$ systemd-analyze time
# 查看每个服务的启动耗时
$ systemd-analyze blame
# 显示瀑布状的启动过程流
$ systemd-analyze critical-chain
# 显示指定服务的启动流
$ systemd-analyze critical-chain atd.service
2.3. hostnamectl 链接到标题
hostnamectl 可用于查询和更改系统主机名和相关设置。点击查看命令描述文档
- 命令语法
$ hostnamectl [OPTIONS...] {COMMAND}
- 常用命令
# 查看主机的信息
$ hostnamectl status
# 设置主机名
$ hostnamectl set-hostname york
2.4. journalctl 链接到标题
journalctl 查询系统日志。点击查看命令描述文档
- 命令语法
$ journalctl [OPTIONS...] [MATCHES...]
- 常用命令
# 查看所有日志
$ journalctl
# 查看指定 unit 日志
$ journalctl _SYSTEMD_UNIT=httpd.service
# 查看内核日志(不显示应用日志)
$ journalctl -k
# 查看系统本次启动的日志
$ journalctl -b
$ journalctl -b -0
# 查看上一次启动的日志(需更改设置)
$ journalctl -b -1
# 显示尾部的最新10行日志
$ journalctl -n
# 显示尾部指定行数的日志
$ journalctl -n 20
# 实时滚动显示最新日志
$ journalctl -f
# 查看指定服务的日志
$ journalctl /usr/lib/systemd/systemd
# 查看指定进程的日志
$ journalctl _PID=1
# 查看某个路径的脚本的日志
$ journalctl /usr/bin/bash
# 查看指定用户的日志
$ journalctl _UID=33 --since today
2.5. loginctl 链接到标题
loginctl 系统登陆管理器。点击查看命令描述文档
- 命令语法
$ loginctl [OPTIONS...] {COMMAND} [NAME...]
- 常用命令
# 列出当前登录用户
$ loginctl list-users
# 列出显示指定用户的信息
$ loginctl show-user root
# 查看 sission 详情
$ loginctl show-session 130423 559 59
2.6. timedatectl 链接到标题
timedatectl 系统时间和日期查看与管理。点击查看命令描述文档
- 命令语法
$ timedatectl [OPTIONS...] {COMMAND}
- 常用命令
# 查看当前时区设置
$ timedatectl
# 显示所有可用的时区
$ timedatectl list-timezones
# 设置当前时区
$ timedatectl set-timezone America/New_York
三,Systemd 资源 链接到标题
Systemd可以管理所有系统资源。不同的资源统称为Unit(单位)。
点击查看 systemd.unit 描述文档 点击查看 systemd.service 描述文档
3.1. Unit 种类 链接到标题
Unit 文件是 ini 风格的纯文本文件。统一了过去各种不同系统资源配置格式,例如服务的启/停、定时任务、设备自动挂载、网络配置、虚拟内存配置等。而 Systemd 通过不同的文件后缀(如 .service)来区分这些配置文件。支持的 11 种 Unit 文件类型:
# 服务,封装守护进程的启动、停止、重启和重载操作,是最常见的一种 Unit 文件
service.service
# 套接字,监控来自于系统或网络的数据消息,用于实现基于数据自动触发服务启动
socket.socket
# 设备,对于 /dev 目录下的设备,主要用于定义设备之间的依赖关系
device.device
# 挂载点,定义系统结构层次中的一个挂载点,可以替代过去的 /etc/fstab 配置文件
mount.mount
# 自动挂载点,用于控制自动挂载文件系统,相当于 SysV-init 的 autofs 服务
automount.automount
# 交换分区或交换文件,定义一个用户做虚拟内存的交换分区
swap.swap
# 启动目标,用于对 Unit 文件进行逻辑分组,引导其它 Unit 的执行。它替代了 SysV-init 运行级别的作用,并提供更灵活的基于特定设备事件的启动方式
target.target
# 被监视的路径,用于监控指定目录或文件的变化,并触发其它 Unit 运行
path.path
# 任务计划,用于配置在特定时间触发的任务,替代了 Crontab 的功能
timer.timer
# 资源控制组,用于表示一个 CGroup 的树,通常用户不会自己创建这样的 Unit 文件
slice.slice
# 一组外部创建的进程,这种 Unit 文件不是用户创建的,而是 Systemd 运行时产生的,描述一些系统服务的分组信息
scope.scope
3.2. Unit 文件结构 链接到标题
下面这个 foo.service Unit。
# [Unit]区块包含与单元类型无关的通用信息
[Unit]
Description=Foo
# [Service]区块包含服务启动信息
[Service]
ExecStart=/usr/sbin/foo-daemon
# [Install]区块包含单元的启用信息
[Install]
WantedBy=multi-user.target
- 从上面的输出可以看到,配置文件分成几个区块。每个区块的第一行,是用方括号表示的区别名,比如:
[Unit] - 区块内容
每个区块内部是一些等号连接的键值对。
[Service] ExecStart=/usr/sbin/foo-daemon ExecStop=xxx - 配置文件注释使用
#开头 - 注意事项 配置文件的区块名和字段名,都是大小写敏感的 键值对的等号两侧不能有空格。
3.3. [Unit] 区块 链接到标题
Unit 文件中的 [Unit] 区块包含与 Unit 类型无关的通用信息。可用的如下配置指令如下:
Description:有利于人类阅读的、对单元进行简单描述的字符串。
Documentation:一组用空格分隔的文档URI列表, 这些文档是对此单元的详细说明。
Requires:设置此单元所必须依赖的其他单元。
Wants:此选项是 Requires= 的弱化版。
BindsTo:与 Requires= 类似,但是依赖性更强
Before, After:强制指定单元之间的先后顺序,接受一个空格分隔的单元列表。
Conflicts:指定单元之间的冲突关系。表明该单元不能与列表中的任何单元共存
3.4. [Service] 区块 链接到标题
[Service] 区块用来 Service 的配置,只有 Service 类型的 Unit 才有这个区块。包含服务启动信息。可用的如下配置指令如下:
Type:设置进程的启动类型。取值为 simple, exec, forking, oneshot, dbus, notify, idle 之一。
RemainAfterExit:当该服务的所有进程全部退出之后, 是否依然将此服务视为活动(active)状态。 默认值为 no
PIDFile:该服务PID文件的路径(一般位于 /run/ 目录下)。 强烈建议在 Type=forking 的情况下明确设置此选项。
BusName:设置与此服务通信 所使用的 D-Bus 名称。
ExecStart:在启动该服务时需要执行的 命令行(命令+参数),命令行必须以一个可执行文件(要么是绝对路径、要么是不含任何斜线的文件名)开始, 并且其后的那些参数将依次作为"argv[1] argv[2] …"传递给被执行的进程。
ExecReload:这是一个可选的指令, 用于设置当该服务 被要求重新载入配置时 所执行的命令行。
ExecStop:这是一个可选的指令, 用于设置当该服务被要求停止时所执行的命令行。
Restart:当服务进程 正常退出、异常退出、被杀死、超时的时候, 是否重新启动该服务。所谓"服务进程" 是指 ExecStartPre=, ExecStartPost=, ExecStop=, ExecStopPost=, ExecReload= 中设置的进程。
Environment:指定环境变量
User:指定运行服务的用户
Group:指定运行服务的用户组
WorkingDirectory:指定服务的工作目录
3.5. [Install] 区块 链接到标题
[Install] 区块包含单元的启用信息。 当执行命令 systemctl enable 与 disable 操作 Unit 时才会使用此小节。
Alias:启用时使用的别名,可以设为一个空格分隔的别名列表。
WantedBy:它的值是一个或多个 Target,当前 Unit 激活时(enable)符号链接会放入/etc/systemd/system目录下面以 Target 名 + .wants后缀构成的子目录中
RequiredBy:它的值是一个或多个 Target,当前 Unit 激活时,符号链接会放入/etc/systemd/system目录下面以 Target 名 + .required后缀构成的子目录中
Also:设置此单元的附属单元,表示当使用 systemctl enable 启用 或 systemctl disable 停用 此单元时, 也同时自动的启用或停用附属单元。
3.6. Unit 文件加载 链接到标题
Systemd 将会从一组在编译时设定好的 Unit 目录 中加载单元文件,目录拥有不同的优先级。高优先级目录中的文件, 将会覆盖低优先级目录中的同名文件。
- 当 systemd 以系统实例(–system)运行时,加载单元的先后顺序(较前的目录优先级较高)
| 系统单元目录 | 描述 |
|---|---|
| /run/systemd/transient | 动态配置的临时单元(系统与全局用户共用) |
| /etc/systemd/system | 本地配置的系统单元 |
| /run/systemd/system | 运行时配置的系统单元 |
| /usr/lib/systemd/system | 本地软件包安装的系统单元 |
| /usr/lib/systemd/system | 发行版软件包安装的系统单元 |
- 当 systemd 以用户实例(–user)运行时,加载单元的先后顺序(较前的目录优先级较高)
| 系统单元目录 | 描述 |
|---|---|
| /etc/systemd/user | 本地配置的全局用户单元 |
| /run/systemd/user | 运行时配置的全局用户单元 |
| /usr/lib/systemd/user | 本地软件包安装的全局用户单元 |
| /usr/lib/systemd/user | 发行版软件包安装的全局用户单元 |
3.7. 设置开机启动 链接到标题
可使用
systemctl enable命令激活 Unit 开机启动。
Systemd 默认从目录 /etc/systemd/system/ 读取配置文件。但是,里面存放的大部分文件都是符号链接,指向目录 /usr/lib/systemd/system/,真正的配置文件存放在这个目录。
systemctl enable 命令用于在上面两个目录之间,建立符号链接关系。
# 激活开机启动
$ systemctl enable koa.service
# 等同于
$ ln -s '/usr/lib/systemd/system/koa.service' '/etc/systemd/system/multi-user.target.wants/koa.service'
四,Systemd 资源管理 链接到标题
该节使用 Systemd 管理 Node.js 应用,实现应用的开机自启动。
4.1. Node.js 应用 链接到标题
新建文件 /data/app/node.js/node-systemd-demo/app.js,其内容如下。
const http = require('http');
http.createServer((request, response) => {
response.write('Systemd 从入门到实战');
response.end();
}).listen(8091);
4.2. 配置 Unit 链接到标题
配置 Systemd 的 Unit 文件,用于管理 Node.js 应用。新建文件 /usr/lib/systemd/system/node-demo.service,其内容如下:
#!/bin/bash
# 服务说明
[Unit]
# 服务描述
Description=node-systemd-demo
# 前置需要启动的服务
After=sysinit.target
# 服务启动行为
[Service]
# 服务类型
Type=simple
ExecStart=/usr/local/services/nodejs/bin/node /data/app/node.js/node-systemd-demo/app.js
# 设置预加载变量
Environment="PATH=/usr/local/services/nodejs/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/.ft:/root/bin"
# 执行用户
User=root
# 执行用户组
Group=root
WorkingDirectory=/data/app/node.js/node-systemd-demo
# 服务开机启动安装目标
[Install]
# 表示该服务所在的 Target
WantedBy=multi-user.targe
4.3. 启动应用 链接到标题
使用 Systemd 启动运行 node-demo.service,执行下命令:
# 设置可执行权限
$ chmod +x /usr/lib/systemd/system/node-demo.service
# 重新载入 Unit 配置
$ systemctl daemon-reload
# 启动 Unit 服务
$ systemctl start node-demo.service
# 查看 Unit 服务状态
$ systemctl status node-demo.service
# 请求 node-systemd-demo 服务
$ curl -v http://127.0.0.1:8091


4.4. 设置开机启动 链接到标题
使用 Systemd 配置 node-demo.service 服务开机启动,执行下命令:
# 激活开机启动
$ systemctl enable node-demo.service
# 或者 ln 激活开机启动
ln -s /usr/lib/systemd/system/node-demo.service /etc/systemd/system/multi-user.target.wants/
# 重启 linux
$ reboot
激活开机启动后,会在 /etc/systemd/system/multi-user.target.wants/ 目录中添加 node-demo.service 软链接。

执行 reboot 后,执行命令 systemctl status node-demo.service 查看服务状态。
