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:进程通信SocketSwap 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=forkingExecStart=/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-watchdogTimeoutSec:定义Systemd停止当前服务之前等待的秒数Environment:指定环境变量

Target

  Target由多个Unit所组成,启动某个Target就启动了多个Unit,在系统初始化时只需启动某个Target即可;

systemctl list-unit-files --type=target  查看当前所有systemctl list-dependencies multi-user.target 查看Target包含的所有Unitsystemctl 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 yesterdaysudo 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: debugsudo 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

文章首发地址:https://mp.weixin.qq.com/s/Xl0Vm57E7qd11wZzbCtEOQ