在centos 7
系统中,使用的是systemd
作为默认的初始化系统 ,同时也包括了启动和管理系统服务。
整理一下,systemd
承担了2个角色:
-
初始化系统(
Init System
):systemd
将是centos 7
默认的初始化系统,主要负责引导操作系统,取代了此前的SysV init
(centos 5
以及centos 6
使用SysV Init
初始化系统)。 -
服务管理:
systemd
也负责管理系统服务,包括启动、停止、重启、查看等,这些可以使用systemctl
来进行上述操作。
首先来介绍一下systemd
作为默认的初始化系统。
systemd 初始化系统
这里只是提及一下systemd Init System
。
systemd
初始化是在centos 7
机器启动中,内核初始化后再进行的systemd
初始化,这里可以使用dmesg
命令查看详细的启动过程。
在centos 7
系统中,使用pstree
可以看到当前系统中的进程树,命令如下:
bash
# yum install psmisc -y
# pstree
其中,pstree
是在软件包psmisc
中,所依赖的源为base
,若直接使用pstree
发现没有该命令的时候,需要先安装一下psmisc
。
命令直接结果如下:
可以看到systemd
是整个初始化进程树的根,所以,它的pid
应当为1,可以使用如下命令来校验一下:
arduino
# ps -fp 1
其结果如下:
关于systemd
初始化系统就介绍到这里,下面将介绍一下system
所管理的服务了。
systemd 管理服务
在centos 5
、centos 6
系统中,使用的都是Sys V
的init
脚本程序来启动各种服务,例如,所有的启动脚本都放到/etc/init.d
下,启动服务的时候,需要执行各种命令,如: chkconfig
、service
等等。
但是在centos 7
中,使用了systemd
来管理各种服务,其管理服务优点如下:
- 并行启动服务,加快开机流程。
systemd
所管理的服务仅需要systemctl
来调用即可,无需其他额外的命令。- 按照服务单位
unit
分类,方便管理和查看。 - 服务依赖自启动,避免手动启动依赖。
systemd配置目录
使用systemd
管理的服务主要存放以下三个目录,分别为:
-
/usr/lib/systemd/system
: 每个服务的启动脚本。 -
/run/systemd/system
: 用于存储服务启动过程中临时创建的systemd
相关信息。 -
/etc/systemd/system/
: 该目录是systemd
单元文件的默认目录。
其优先级为:/etc/systemd/system/
---> /run/systemd/system
---> /usr/lib/systemd/system
。
systemd服务分类
在systemd
管理中心,一个服务单位,通常称之为unit
,unit
有专门的类型,正如上面介绍systemd
优点所述,按照unit
分类,可以方便查看和管理服务。
unit
服务分类主要如下:
service
:
一般类型服务,是最常见的类型。
target
:
unit
集合,例如:/etc/systemd/system/multi-user.target.wants
记录的是一堆unit
集合,用于开机自启动。
socket
:
IPC
通信服务。例如有些服务不经常启动,可以使用socket unit
,它会先创建socket
套接字,而不会启动后面的真实服务(daemon
),当客户端请求该服务的时候,再由systemd
启动该服务再将请求打到真实的服务上去。
mount
:
文件系统的挂载点。
automount
:
文件系统自动挂载点。
timer
:
循环运行的服务。和crontanb
类似,不过是由systemd
提供并且维护运行的。
systemctl 常用的命令
systemctl
是一个命令行工具,是用于管理systemd
服务的,可以使用systemctl
来启动、重启、停用以及查看系统服务的状态。
启动服务
sql
systemctl start 服务名称
停止服务
sql
systemctl start 服务名称
重启服务
systemctl restart 服务名称
查看服务状态
lua
systemctl status 服务名称
设置服务开机自启
bash
systemctl enable 服务名称
禁用服务开机自启
bash
systemctl disable 服务名称
重新加载配置文件
systemctl daemon-reload
查看当前系统正在运行的服务
ini
systemctl list-units --type=service
比如,将yum
安装的nginx
启动起来,并且设置为开机自启,可以使用如下命令来设置:
shell
# systemctl start nginx
# systemctl enable nginx
命令执行结果如下:
在设置nginx
开机自启的时候,会出现这样的一条日志:
perl
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.
在设置nginx
开机后,就将该服务加入到了/etc/systemd/system/multi-user.target.wants/
目录下,该目录包含了一系列unit
,multi-user.target
是systemd
中的一个运行级别,对应的运行级别是3。即多用户运行模式,当在该目录下,系统启动后,会执行该target
。
自己编写一个systemd服务
首先编写一个毫无意义的一段shell
脚本,其脚本名称为:/root/testSystem.sh
,内容如下:
ruby
#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/go/bin/:/root/go/bin/:/root/bin
export PATH
while true
do
nowtime=$(date +"%F %T")
echo "set key '$nowtime'"
echo "set key '$nowtime'" | redis-cli
echo "get key"
echo "get key" | redis-cli
sleep 10
done
这段脚本的作用是建立一个无限循环,而后再循环中定义一个变量nowtime
,该变量的值是当前系统时间,而后将该值存入到redis
中,完毕后再使用get
获取其值。
手动运行脚本,效果如下:
当然前提我们需要使用yum
安装一个redis
服务在当前主机上。
而后再来编写systemd
服务,服务的存放目录是在: /usr/lib/systemd/system
下,我们可以新建一个文件,名称是testSystem.service
。
除此之外,我们还需要写一个启动脚本和停止脚本,其名称为:/root/startTestSystem.sh
,脚本内容如下:
ruby
#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/go/bin/:/root/go/bin/:/root/bin
export PATH
cd /root/
nohup bash testSystem.sh >> /root/testSystem.log &
该脚本运行后,会在后台启动/root/testSystem.sh
脚本。
停止脚本名称:/root/stopTestSystem.sh
,内容如下:
ruby
#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/go/bin/:/root/go/bin/:/root/bin
export PATH
pidCount=$(ps aux | grep testSystem.sh | grep -v grep | wc -l)
if [ 0 -eq $pidCount ];then
echo "no killed"
else
kill -9 $(ps aux | grep testSystem.sh | grep -v grep | awk '{print $2}')
fi
最后再来编写systemd service
服务,我们新建文件:/usr/lib/systemd/system/testSystem.service
,其内容如下:
ini
[Unit]
Description=a bash test
[Service]
Type=forking
ExecStart=/usr/bin/bash /root/startTestSystem.sh
ExecStop=/usr/bin/bash /root/stopTestSystem.sh
[Install]
WantedBy=multi-user.target
该service
的主要有三段组成,分别是:[Unit]
、[Service]
以及Install
。
其中:
Unit
: 服务本身的说明,可以设置依赖关系,服务启动顺序等。Service
: 这是服务器本身,定义的是启动方式、启动和停止脚本定义。Install
:这里定义的是该脚本定义到哪个target
去。
定义后,使用systemctl daemon-reload
重新加载一下配置,而后就可以使用systemctl start testSystem.servic
启动该服务了。
当然,上面的服务是强度依赖于redis
的,如果redis
也是使用systemd
启动的话,可以修改service
来增加一个依赖,当启动testSystem
的时候,若redis
未启动,会先启动redis
,而后再启动testSystem
,systemd
服务修改如下:
ini
[Unit]
Description=a bash test
Requires=redis.service
[Service]
Type=forking
ExecStart=/usr/bin/bash /root/startTestSystem.sh
ExecStop=/usr/bin/bash /root/stopTestSystem.sh
[Install]
WantedBy=multi-user.target
上面的改动仅一点,就是在Unit
下增加了一个Requires
,值为: redis.service
,这样当启动testSystem
的时候,若发现redis
未启动,会先启动redis
,而后再启动testSystem
的。
总结
systemd
非常复杂,主要表示在2方面:
-
- 会进行初始化系统,
-
- 管理机器的各个服务。
不过一般维护使用不会涉及到初始化系统操作,而更多的使用是管理各项服务。
包括我们从yum
安装各种包体,以及自己编写的服务,此外,systemd
更好是管理服务器程序,而非用户自定义程序。
在systemd
中,由于各种服务很多,所有拆分为了以扩展名来定义的服务,比如:以service
结尾的服务为一般服务,也是用的最多的服务,以timer
结尾的服务,是定时服务,很少使用。
在每项服务中,又可以定义服务的依赖以及启动先后顺序等。目前本章只是简单的使用了service
而已。