Loading

系统服务systemd

系统服务systemd

参考文章:Systemd 入门教程:命令篇

1 系统服务介绍

系统服务是在后台运行的应用程序,并且可以提供一些本地系统或网络的功能。我们把这些应用程序称作服务,也就是Service。它们通常都会监听某个端口,等待其它程序的请求,比如mysql,nginx等等。

linux的启动流程大致分为开机自检BIOS-->MBR启动引导-->硬盘启动-->加载内核-->启动初始化进程。到这一步时,linux内核的一些系统的不同版本使用的初始化进程是不同的。比如CentOS6使用init进程,而CentOS7使用Systemd。

2 systemd介绍

linux一直以来都是采用init进程作为初始进程,但是init有两个缺点:

  • 启动时间长。Init进程是串行启动,只有前一个进程启动完,才会启动下一个进程。
  • 启动脚本复杂,初始化完成后系统会加载很多脚本,脚本都会处理各自的情况,这会让脚本变得很复杂。

Systemd 就是为了解决这些问题而诞生的。它的设计目标是,为系统的启动和管理提供一套完整的解决方案。使用了 Systemd,就不需要再用init了。Systemd 取代了initd,成为系统的第一个进程(PID 等于 1),其他进程都是它的子进程。

相比于init,systemd有以下优点:

  • 最新系统都采用systemd管理(RedHat7,CentOS7,Ubuntu15等)
  • Centos7支持开机并行启动服务,显著提高开机启动效率
  • Centos7关机只关闭正在运行的服务
  • Centos7服务的启动与停止不再使用脚本进行管理
  • 原有service不会关闭程序产生的子进程,Centos7使用systemd解决原有模式缺陷

systemd架构图:

image

3 systemd配置文件

3.1 概述

Systemd可以管理所有系统资源。不同的资源统称为 Unit(单位)。每一个 Unit 都有一个配置文件,告诉 Systemd 怎么启动这个 Unit 。

/usr/lib/systemd/system/ # 目录下是真正的system的配置
/etc/systemd/system/ # 配置文件,大部分是软链接
/etc/systemd/system/multi-user.target.wants/  # 开机启动的程序都在这里配置

Systemd 默认从目录/etc/systemd/system/读取配置文件。但是,里面存放的大部分文件都是符号链接,指向目录/usr/lib/systemd/system/,真正的配置文件存放在这里。我们通过systemctl设置开机启动,其实质是增加由/usr/lib/systemd/system//etc/systemd/system/multi-user.target.wants/下的软链接。

下图展示的就是这些配置文件:

image

3.2 配置文件的格式

任意打开一个配置文件,你会发现他们的格式有共同点。

[Unit]
Description=ATD daemon

[Service]
Type=forking
ExecStart=/usr/bin/atd

[Install]
WantedBy=multi-user.target

配置文件分成几个区块,每个块之间使用中括号[]区别,注意,配置文件的区块名和字段名,都是大小写敏感的。区块内部是一些键值对,等号两侧不能有空格。

[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 运行必须满足的条件,否则会报启动失败

[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:指定环境变量

[Install]通常是配置文件的最后一个区块,用来定义如何启动,以及是否开机启动。它的主要字段如下。

WantedBy:它的值是一个或多个 Target,当前 Unit 激活时(enable)符号链接会放入/etc/systemd/system目录下面以 Target 名 + .wants后缀构成的子目录中
RequiredBy:它的值是一个或多个 Target,当前 Unit 激活时,符号链接会放入/etc/systemd/system目录下面以 Target 名 + .required后缀构成的子目录中
Alias:当前 Unit 可用于启动的别名
Also:当前 Unit 激活(enable)时,会被同时激活的其他 Unit

如需查看完整字段,请参阅官方文档,或者中文翻译文档

3.3 举例:nginx的service配置

在我的本地博客部署这篇博客中,有介绍nginx的配置,这里补充一下。

[Unit]
Description=nginx
After=network.target
  
[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp= true  # PrivateTmp=True表示给服务分配独立的临时空间
  
[Install]
WantedBy=multi-user.target  # 运行级别

这里的运行级别,就是操作系统当前正在运行的功能级别。级别从0到6,如下:

运行级别 systemd目标名称 作用
0 runlevel0.target, poweroff.target 关机
1 runlevel1.target, rescue.target 单用户模式
2 runlevel2.target, multi-user.target 暂未使用
3 runlevel3.target, multi-user.target 多用户的文本界面(黑框)
4 runlevel4.target, multi-user.target 没有使用
5 runlevel5.target, graphical.target 多用户的图形界面
6 runlevel6.target, reboot.target 重启
原理(了解)

/etc/rc.d/init.d下有许多服务器脚本程序,一般称为服务(service),在/etc/rc.d下有7个名为rcN.d的目录,对应系统的7个运行级别。

image

rcN.d下都是一些软链接文件,这些链接文件都指向/etc/rc.d/init.d目录下的service脚本文件。比如以rc3.d举例

image

命名规则为K+nn+服务名或S+nn+服务名,其中nn为两位数字。

系统启动时,会根据运行级别进入对应的rcN.d目录,并按照文件名顺序检索目录下的链接文件。对于以K开头的文件,系统将终止对应的服务;对于以S开头的文件,系统将启动对应的服务。

查看系统运行级别可以使用命令:

runlevel

一般来说,默认选3就可以。也就是multi-user.target

4 systemctl相关命令

systemctl是Systemd的主命令,用于管理系统。比如管理服务的启动、重启、停止、重载、查看状态等。对于用户来说,最常用的是下面这些命令,用于启动和停止 Unit(主要是 service)。想要使用systemctl命令,必须确保软件的配置文件在/usr/lib/systemd/system/目录下,一般来说yum安装会自动配置,但是二进制安装不会,需要手动配置(去该目录下创建一个xxx.service文件)。另外,一旦修改配置文件,就要让Systemd重新加载配置文件,否则修改不会生效。

systemctl命令 说明
systemctl start crond.service 启动服务;cround为服务名,.service可以不加,下同
systemctl stop crond.service 停止服务
systemctl restart crond.service 重启服务
systemctl kill crond.service 杀死一个服务的所有子进程
systemctl reload crond.service 重新加载配置
systemctl status crond.servre 查看服务运行状态
systemctl is-active sshd.service 查看服务是否在运行中
systemctl mask crond.servre 禁止服务运行
systemctl unmask crond.servre 取消禁止服务运行

当我们使用systemctl启动一个守护进程后,可以通过sytemctl status 进程名查看此守护进程的状态。比如systemctl status nginx.service(可以不写.service),相关状态如下:

状态 描述
loaded 服务单元的配置文件已经被处理
active(running) 服务持续运行
active(exited) 服务成功完成一次的配置
active(waiting) 服务已经运行但在等待某个事件
inactive 服务没有在运行
enabled 服务设定为开机运行
disabled 服务设定为开机不运行
static 服务开机不启动,但可以被其他服务调用启动

systemctl设置服务开机启动、不启动、查看各级别下服务启动状态等常用命令:

systemctl命令(CentOS7) 描述
systemctl enable crond.service 开机自动启动
systemctl disable crond.service 开机不自动启动
systemctl list-unit-files 查看各个级别下服务的相关状态
systemctl is-enabled crond.service 查看特定服务是否为开机自启动
systemctl is-active crond.service 查看特定服务是否为正在运行
systemctl daemon-reload 创建新服务文件;修改了依赖关系,需要重载变更,否则不生效
posted @ 2021-11-20 21:51  yyyz  阅读(69)  评论(0编辑  收藏  举报