简单探寻一下systemd的service服务

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 5centos 6系统中,使用的都是Sys Vinit脚本程序来启动各种服务,例如,所有的启动脚本都放到/etc/init.d下,启动服务的时候,需要执行各种命令,如: chkconfigservice等等。

但是在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管理中心,一个服务单位,通常称之为unitunit有专门的类型,正如上面介绍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/目录下,该目录包含了一系列unitmulti-user.targetsystemd中的一个运行级别,对应的运行级别是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方面:

    1. 会进行初始化系统,
    1. 管理机器的各个服务。

不过一般维护使用不会涉及到初始化系统操作,而更多的使用是管理各项服务。

包括我们从yum安装各种包体,以及自己编写的服务,此外,systemd更好是管理服务器程序,而非用户自定义程序。

systemd中,由于各种服务很多,所有拆分为了以扩展名来定义的服务,比如:以service结尾的服务为一般服务,也是用的最多的服务,以timer结尾的服务,是定时服务,很少使用。

在每项服务中,又可以定义服务的依赖以及启动先后顺序等。目前本章只是简单的使用了service而已。

相关推荐
舞动CPU4 小时前
linux c/c++最高效的计时方法
linux·运维·服务器
皮锤打乌龟5 小时前
(干货)Jenkins使用kubernetes插件连接k8s的认证方式
运维·kubernetes·jenkins
钰@5 小时前
小程序开发者工具的network选项卡中有某域名的接口请求,但是在charles中抓不到该接口
运维·服务器·小程序
wanhengwangluo5 小时前
云服务器和物理服务器的区别有哪些?
运维·服务器
秦jh_6 小时前
【Linux】多线程(概念,控制)
linux·运维·前端
yaosheng_VALVE6 小时前
稀硫酸介质中 V 型球阀的材质选择与选型要点-耀圣
运维·spring cloud·自动化·intellij-idea·材质·1024程序员节
看山还是山,看水还是。7 小时前
Redis 配置
运维·数据库·redis·安全·缓存·测试覆盖率
扣得君7 小时前
C++20 Coroutine Echo Server
运维·服务器·c++20
keep__go7 小时前
Linux 批量配置互信
linux·运维·服务器·数据库·shell
矛取矛求8 小时前
Linux中给普通账户一次性提权
linux·运维·服务器