系统服务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架构图:
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/
下的软链接。
下图展示的就是这些配置文件:
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个运行级别。
rcN.d
下都是一些软链接文件,这些链接文件都指向/etc/rc.d/init.d
目录下的service
脚本文件。比如以rc3.d
举例
命名规则为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 | 创建新服务文件;修改了依赖关系,需要重载变更,否则不生效 |
本文来自博客园,作者:yyyz,转载请注明原文链接:https://www.cnblogs.com/yyyzyyyz/p/15582739.html