Systemd使用
Systemd是Linux操作系统的系统和服务管理器,用来启动守护进程。目前多数Linux发行版都已经采用Systemd取代了initd,作为整个系统的守护进程,成为系统第一个进程(PID为1,其他进程都是他的子进程)。他的设计目的是为了让进程并发启动,按需启动进程,提高Linux系统启动速度,让使用也更简洁。
Systemd跟initd的使用对比:
# initd使用
/etc/init.d/nginx start
# 或
service nginx start
# systemd使用
systemctl start nginx
systemctl命令
systemctl
命令是Systemd中最重要的一个命令,用于对进程进行启动,停止等管理操作。
命令格式
systemctl [command] [unit]
例如:
systemctl start nginx.service
# 或
systemctl start nginx
command 说明
start 开启
stop 关闭
restart 重启
status 查看状态
is-active 查看激活与否
enable 设置开机启动
disable 禁止开机启动
is-enabled 查看是否开机自动启动
kill 杀死进程
mask 禁止自动和手动启动
unmask 取消禁止
list-dependencies 查看服务的依赖关系
常用管理命令
# 立即启动
systemctl start nginx.service
# 立即停止
systemctl stop nginx.service
# 重启
systemctl restart nginx.service
# 显示一个Unit的状态
systemctl status nginx.service
# 显示系统状态
systemctl status
# 重新加载一个Unit的配置文件
systemctl reload nginx.service
# 重载所有修改过的配置文件
systemctl daemon-reload
# 列出正在运行的Unit
systemctl list-units # 可以直接使用systemctl
# 列出所有Unit,包括没有找到配置文件的或者启动失败的
systemctl list-units --all
# 列出所有没有运行的 Unit
systemctl list-units --all --state=inactive
# 列出所有加载失败的 Unit
systemctl list-units --failed
# 列出所有正在运行的、类型为service的Unit
systemctl list-units --type=service
# 显示某个 Unit 是否正在运行
systemctl is-active nginx.service
# 显示某个 Unit 是否处于启动失败状态
systemctl is-failed nginx.service
# 显示某个 Unit 服务是否建立了启动链接
systemctl is-enabled nginx.service
# 显示一个 Unit 的所有依赖
systemctl list-dependencies
对Unit操作时,如果缺省扩展名,默认使用.service
Unit
Unit 是 Systemd 管理系统资源的基本单位。Systemd将所有系统资源划分为12类,既有12种 Unit。
Service Unit
系统服务,最常见的 UnitTarget Unit
多个 Unit 构成的一个组Device Unit
硬件设备Mount Unit
文件系统的挂载点Automount Unit
自动挂载点Path Unit
文件或路径Scope Unit
不是由 Systemd 启动的外部进程Slice Unit
进程组Snapshot Unit
Systemd 快照,可以切回某个快照Socket Unit
进程间通信的 socketSwap Unit
swap 文件Timer Unit
定时器
Unit 配置文件
每一个 Unit 都有一个配置文件,用来告诉 Systemd 如何管理这个 Unit。配置文件目录默认为/etc/systemd/system/
,不过默认目录下存放的多是链接文件,链接到的文件目录为/usr/lib/systemd/system/
。
Unit 配置文件由三段组成:
[Unit]
段:所有类型Unit文件通用,用于提供unit的描述信息、unit行为及依赖关系等[Install]
段:所有类型Unit文件通用,用来定义如何启动,以及是否开机启动[Service]
段:Service Unit文件特有,用于定义服务的具体管理和执行动作
[Unit] 段配置项
Description
当前服务的简单描述Documentation
文档地址,可以是一个或多个文档的 URL 路径After
该字段指定的 Unit 全部启动完成以后,才会启动当前 UnitBefore
该字段指定的 Unit 必须在当前 Unit 启动完成之后再启动Requires
与其它 Unit 的强依赖关系,如果其中任意一个 Unit 启动失败或异常退出,当前 Unit 也会被退出Wants
与其它 Unit 的弱依赖关系,如果其中任意一个 Unit 启动失败或异常退出,不影响当前 Unit 继续执行Conflicts
定义 Units 间的冲突关系
[Install] 段配置项
WantedBy
被哪些 units 所依赖,弱依赖RequiredBy
被哪些 units 所依赖,强依赖Alias
当前 Unit 可用于启动的别名Also
当前 Unit 被 enable/disable 时,会被同时操作的其他 Unit
[Install]段一般设置为 WantedBy=multi-user.target
[Service] 段配置项
-
User
指定运行服务的用户 -
Group
指定运行服务的用户组 -
PIDFile
指向当前服务 PID file 的绝对路径 -
EnvironmentFile
指定当前服务的环境参数文件 -
ExecStart
启动当前服务的命令 -
ExecStartPre
启动当前服务之前执行的命令 -
ExecStartPost
启动当前服务之后执行的命令 -
ExecReload
重启当前服务时执行的命令 -
ExecStop
停止当前服务时执行的命令 -
ExecStopPost
停止当前服务之后执行的命令 -
RemainAfterExit
当前服务的所有进程都退出的时候,Systemd 仍认为该服务是激活状态 -
TimeoutSec
定义 Systemd 停止当前服务之前等待的秒数 -
RestartSec
Systemd 重启当前服务间隔的秒数 -
KillMode
定义 Systemd 如何停止服务,可选值:control-group(默认)、process、mixed、none -
Restart
定义何种情况 Systemd 会自动重启当前服务,可选值:no(默认)、on-success、on-failure、on-abnormal、on-abort、on-watchdog、always -
Type
定义启动时的进程行为,可选值:-
simple
默认值,ExecStart
字段启动的进程为主进程 -
forking
使ExecStart
字段以fork()
方式从父进程创建子进程启动,创建后父进程会立即退出,子进程成为主进程。 -
oneshot
只执行一次,Systemd 会等当前服务退出,再继续往下执行 -
dbus
当前服务通过 D-Bus 信号启动。当指定的 BusName 出现在 DBus 系统总线上时,Systemd认为服务就绪 -
notify
当前服务启动完毕会发出通知信号,通知 Systemd,然后 Systemd 再启动其他服务 -
idle
Systemd 会等到其他任务都执行完,才会启动该服务
-
使用实例:systemctl托管Golang项目
创建文件 /etc/systemd/system/xxx.service
编辑内容如下:
[Unit]
Description=XXX # XXX为应用名称
After=syslog.target network-online.target
[Service]
Type=simple
WorkingDirectory=/data/xxx/ # /data/xxx/为运行目录
ExecStart=./xxx # xxx为可执行程序
Restart=always
RestartSec=2s
[Install]
WantedBy=multi-user.target
如果需要将程序输出重定向到文件,可以采用如下方式
[Unit]
Description=XXX # XXX为应用名称
After=syslog.target network-online.target
[Service]
Type=simple
WorkingDirectory=/data/xxx/ # /data/xxx/为运行目录
ExecStart=/bin/sh -c 'exec ./xxx >> run.log 2>&1' # xxx为可执行程序
Restart=always
RestartSec=2s
[Install]
WantedBy=multi-user.target
Systemd的其他命令
除了systemctl
,Systemd还包含一些其他系统管理的命令:
systemd-analyze
查看系统启动耗时
hostnamectl
查看当前主机的信息
localectl
查看本地化设置
timedatectl
查看当前时区设置
loginctl
查看当前登录用户
journalctl
系统日志管理
journalctl 命令管理Unit日志
Systemd 统一管理所有 Unit 的启动日志。带来的好处就是,可以只用journalctl
一个命令,查看所有日志(内核日志和应用日志)。日志的配置文件是/etc/systemd/journald.conf
。
常用日志管理命令
# 查看所有日志(默认只保存本次启动的日志)
journalctl
# 查看内核日志(不显示应用日志)
journalctl -k
# 查看系统本次启动的日志
journalctl -b
journalctl -b -0
# 查看上一次启动的日志(需更改设置)
journalctl -b -1
# 查看指定时间的日志
journalctl --since="2012-10-30 18:17:16"
journalctl --since "20 min ago"
journalctl --since yesterday
journalctl --since "2015-01-10" --until "2015-01-11 03:00"
journalctl --since 09:00 --until "1 hour ago"
# 显示尾部的最新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
# 查看某个 Unit 的日志
journalctl -u nginx.service
journalctl -u nginx.service --since today
# 实时滚动显示某个 Unit 的最新日志
journalctl -u nginx.service -f
# 合并显示多个 Unit 的日志
$ journalctl -u nginx.service -u php-fpm.service --since today
# 日志默认分页输出,--no-pager 改为正常的标准输出
journalctl --no-pager
# 以 JSON 格式(单行)输出
journalctl -b -u nginx.service -o json
# 以 JSON 格式(多行)输出,可读性更好
journalctl -b -u nginx.serviceqq -o json-pretty
# 显示日志占据的硬盘空间
journalctl --disk-usage
# 指定日志文件占据的最大空间
journalctl --vacuum-size=1G
# 指定日志文件保存多久
journalctl --vacuum-time=1years