- A+
Systemd为Linux中的初始化init系统,用于启动与停止服务进程,设计目标为:尽可能启动更少进程、更多进程并行启动;Systemd使用Linux的CGroup特性用来跟踪与管理进程的生命周期,在服务启动时会并发创建依赖的服务进程,子进程继承父进程CGroup相关服务进程归属与同一个CGroup。Systemd只需遍历CGroup即可找到所有相关进程,关闭所有依赖;
Systemd具有快照与恢复的能力,可对系统当前运行状态创建快照,并可通过所创建的快照恢复所创建快照时系统的运行状态;Systemd带有日志服务journald,使用二进制格式保持日志信息可使用journalctl命令查看服务日志;
依赖消除
Systemd的依赖消除,其将依赖定义为三种类别:Socket依赖、D-Bus依赖、文件系统依赖,每种依赖使用不同的技术手段进行消除;
Socket依赖:服务AS通过Socket端口18080提供服务,其他服务如需使用服务AS需通过18080连接,此时如服务AS未启动套接字亦不存在,自然提供不了服务,此时就存在Socket依赖,在Systemd中启动其他服务无需等待AS服务启动,其会预先创建好Socket套接字共其他服务使用,其他服务发送的服务请求会在Linux中缓存,待服务AS启动后就会立即处理请求;Systemd所使用的是Linux的特性Fork或exec创建的子进程父进程所打开的所有文件句柄都被子进程继承;
D-Bus依赖:D-Bus为高性能的进程间通讯机制,D-Bus支持bus activation功能,当服务需要使用服务C所提供的D-Bus服务时该服务C并没有启动,D-Bus可在服务请求服务C时自动启动服务B。
文件系统依赖:Systemd使用了与autofs类似的思路,当某个文件系统挂载点被访问时才触发挂载操作,同时事先创建临时挂载点待真实设备挂载好后再替换挂载点;
Systemd解除了部分依赖达到了服务并发启动的能力,但部分强依赖并不能完全消除,通过Unit定义服务间的依赖关系;
基本命令
Systemd提供了:systemctl、systemd-analyze、hostnamectl、localectl、timedatetl、loginctl等命令,systemctl为管理系统的主命令;
Unit基本概念
系统初始化时需要启动各类系统、用户服务,Systemd将所管理的系统资源统一称为Unit,目前Systemd有12中Unit:
Service Unit:系统服务 Target Unit:由多个Unit所构成 Device Unit:硬件设备 Mount Unit:文件系统挂载点 Automount Unit:自动挂载点 Path Unit:路径与文件 Scope Unit:非Systemd启动的进程 Slice Unit:进程组 Snapchat Unit:Systemd快照 Socket Unit:进程通信Socket Swap Unit:Swap文件 Timer Unit:定时器
Unit相关命令
通过systemctl list-units可查看当前系统的所有Unit
systemctl status查看系统或服务的状态 systemctl start 启动服务 systemctl stop 停止服务 systemctl restart 重启服务 systemctl daemon-reload重新加载配置文件 systemctl list-dependencies 列出Unit的所有依赖
Unit的配置文件
每个Unit都有一个配置文件,用于配置Systemd如何启动Unit,默认从/etc/systemd/system/目录读取配置文件,目前存放的只是符号链接,指向/usr/lib/systemd/system/存放配置文件的目录;使用systemctl enable xxx@xxx.service建立两个目录的符号链接,如配置了开机启动,enable会激活开机启动;
配置文件名的后缀为Unit的种类,省略后缀默认后缀名为.service;
1、配置文件格式
配置文件为文本文件,直接用编辑器打开编辑,一个简单的配置文件如下:分为三个区块组成:Unit、Service、Install,区块的内容为等号连接的键值对,可通过:systemctl cat xxx.service查看配置文件的内容;
[Unit] Description=描述 [Service] Type=forking ExecStart=/usr/bin/sshd [Install] WantedBy=multi-user.target
2、配置文件区块
Unit区块:定义Unit元数据,配置与其他Unit的关系,主要字段有:
Description:描述 Documentation:文档链接 Requires:Unit依赖的其他 Unit,如没有运行,当前Unit会启动失败 Wants:Unit配合的其他Unit,如果它们没运行,当前Unit不会启动失败 BindsTo:与Requires类似,它指定的Unit如退出,会导致当前Unit停止运行 Before:如该字段指定的Unit也要启动,那必须在当前Unit之后启动 After:如该字段指定的Unit也要启动,那么必须在当前Unit之前启动 Conflicts:指定Unit不能与当前Unit同时运行 Condition...:Unit运行必须满足的条件,否则不会运行 Assert...:Unit 运行必须满足的条件,否则会报启动失败
Install区块:用于定义如何启动,以及是否开机启动;
WantedBy:值为一个或多个Target,当前Unit激活时(enable)符号链接会放入/etc/systemd/system/目录下面以Target名+.wants后缀构成的子目录中 RequiredBy:值是一个或多个 Target,当前Unit激活时,符号链接会放入/etc/systemd/system/目录下面以 Target 名 + .required后缀构成的子目录中 Alias:Unit可用于启动的别名 Also:Unit激活(enable)时,会被同时激活的其他Unit
Service区块用与Service的配置,Service类型的Unit专属区块,主要字段如下:
Type:定义启动时的进程行为,它有以下几种值: Type=simple:默认值,执行ExecStart指定的命令,启动主进程 Type=forking:以fork方式从父进程创建子进程,创建后父进程立即退出 Type=oneshot:一次性进程,Systemd会等当前服务退出,再继续往下执行 Type=dbus:当前服务通过D-Bus启动 Type=notify:当前服务启动完毕,会通知Systemd,再继续往下执行 Type=idle:若有其他任务执行完毕,当前服务才会运行 ExecStart:启动当前服务的命令; ExecStartPre:启动当前服务之前执行的命令 ExecStartPost:启动当前服务之后执行的命令 ExecReload:重启当前服务时执行的命令 ExecStop:停止当前服务时执行的命令 ExecStopPost:停止当其服务之后执行的命令 RestartSec:自动重启当前服务间隔的秒数 Restart:定义何时Systemd会自动重启当前服务,可能值包括always(总是重启)、on-success、on-failure、on-abnormal、on-abort、on-watchdog TimeoutSec:定义Systemd停止当前服务之前等待的秒数 Environment:指定环境变量
Target
Target由多个Unit所组成,启动某个Target就启动了多个Unit,在系统初始化时只需启动某个Target即可;
systemctl list-unit-files --type=target 查看当前所有 systemctl list-dependencies multi-user.target 查看Target包含的所有Unit systemctl get-default 查看启动时默认Target
日志
Systemd 统一管理所有Unit日志,只用journalctl一个命令,查看所有日志(内核日志和应用日志),日志的配置文件是/etc/systemd/journald.conf。
查看所有日志(默认情况下 ,只保存本次启动的日志) sudo journalctl 查看内核日志(不显示应用日志) sudo journalctl -k 查看系统本次启动的日志 sudo journalctl -b 查看指定时间的日志 sudo journalctl --since "30 min ago" sudo journalctl --since yesterday sudo journalctl --since "2022-01-10" --until "2022-01-11 03:00" 显示尾部的最新10行日志 sudo journalctl -n 实时滚动显示最新日志 sudo journalctl -f 查看指定服务的日志 sudo journalctl /usr/lib/systemd/systemd 查看指定进程的日志 sudo journalctl _PID=1 查看某个路径的脚本的日志 sudo journalctl /usr/bin/bash 查看某个 Unit 的日志 sudo journalctl -u nginx.service 实时滚动显示某个 Unit 的最新日志 sudo journalctl -u nginx.service -f 查看指定优先级(及其以上级别)的日志,共有8级 # 0: emerg # 1: alert # 2: crit # 3: err # 4: warning # 5: notice # 6: info # 7: debug sudo journalctl -p err -b 日志默认分页输出,--no-pager 改为正常的标准输出 sudo journalctl --no-pager 以 JSON 格式(多行)输出,可读性更好 sudo journalctl -b -u nginx.serviceqq -o json-pretty 显示日志占据的硬盘空间 sudo journalctl --disk-usage 指定日志文件占据的最大空间 sudo journalctl --vacuum-size=1G 指定日志文件保存多久 sudo journalctl --vacuum-time=2years