『常驻在记体体中的程序,且可以提供 一些系统或网络功能,那就是服务』。而服务一般的英文说法是『 service 』。
那么 daemon 与 service 有关啰?否则为什么都能够提供 某些系统或网络功能?此外,这个 daemon 是什么东西呀? daemon 的字面上的意思就是『守护神、 恶魔?』
简单的说,系统为了某些功能必须要提供一些服务 (不论是系统本身还是网络方面),这个服务就称 为 service 。 但是 service 的提供总是需要程序的运作吧!否则如何执行呢?所以达成这个 service 的程序我们就称呼他为 daemon 。举例来说,达成循环型例行性工作排程服务 (service) 的程序为 crond 这个 daemon 啦!这样说比较容易理解了吧!
一般来说,当我们以文本模式或图形模式 (非单人维护模式) 完整开机进入 Linux 主机后, 系统已 经提供我们很多的服务了!包括打印服务、工作排程服务、邮件管理服务等等; 那么这些服务是如 何被启动的?他们的工作型态如何?底下我们就来谈一谈啰!
tips: daemon 既然是一只程序执行后的程序,那么 daemon 所处的那个原本的程序通常是如 何命名的呢 (daemon 程序的命名方式)。这些服务的名称被建立之后,被挂上 Linux 使用时,通常在服务的名称之后会加上一个 d ,例如 例行性命令的建立的 at, 与 cron 这两个服务, 他的程序文件名会被取为 atd 与 crond,这个 d 代表的就是 daemon 的意思。
早期 System V 的 init 管理行为中 daemon 的主要分类 (Optional)
还记得 Unix 的 system V 版本吧?那个很纯种的 Unix 版本~ 在那种年代底 下,我们启动系统服务的管理方式被称为 SysV 的 init 脚本程序的处理方式!亦即系统核心第一支 呼叫的程序是 init , 然后 init 去唤起所有的系统所需要的服务,不论是本地服务还是网络服务。
基本上 init 的管理机制有几个特色如下:
- 服务的启动、关闭与观察等方式:
所有的服务启动脚本通通放置于 /etc/init.d/ 底下,基本上都是使用 bash shell script 所写成的脚本程序,需 要启动、关闭、重新启动、观察状态时, 可以透过如下的方式来处理:
- 启动:/etc/init.d/daemon start
- 关闭:/etc/init.d/daemon stop
- 重新启动:/etc/init.d/daemon restart
- 状态观察:/etc/init.d/daemon status
- 服务启动的分类:
init 服务的分类中,依据服务是独立启动或被一只总管程序管理而分为两大类:
- 独立启动模式 (stand alone):服务独立启动,该服务直接常驻于内存中,提供本机或用户的服务行 为,反应速度快。
- 总管程序 (super daemon):由特殊的 xinetd 或 inetd 这两个总管程序提供 socket 对应或 port 对应 的管理。当没有用户要求某 socket 或 port 时, 所需要的服务是不会被启动的。若有用户要求时, xinetd 总管才会去唤醒相对应的服务程序。当该要求结束时,这个服务也会被结束掉~ 因为透过 xinetd 所总管,因此这个家伙就被称为 super daemon。好处是可以透过 super daemon 来进行服务 的时程、联机需求等的控制,缺点是唤醒服务需要一点时间的延迟。
- 服务的相依性问题:
服务是可能会有相依性的~例如,你要启动网络服务,但是系统没有网络, 那怎么可能可以唤醒网络服务 呢?这就是所谓的服务相依性问题。init 在管理员自己手动处理这些服务时,是没有办法协助相依服务的唤醒的!
- 执行等级的分类:
上面说到 init 是开机后核心主动呼叫的, 然后 init 可以根据用户自定义的执行等级 (runlevel) 来唤醒不 同的服务,以进入不同的操作界面。基本上 Linux 提供 7 个执行等级,分别是 0, 1, 2...6 , 比较重要的 是 1)单人维护模式、3)纯文本模式、5)文字加图形界面。而各个执行等级的启动脚本是透过 /etc/rc.d/rc[0-6]/SXXdaemon 连结到 /etc/init.d/daemon ,连结档名 (SXXdaemon) 的功能为: S 为启动该 服务,XX 是数字,为启动的顺序。由于有 SXX 的设定,因此在开机时可以『依序执行』所有需要的服务, 同时也能解决相依服务的问题。这点与管理员自己手动处理不太一样就是了。
- 制定执行等级默认要启动的服务:
若要建立如上提到的 SXXdaemon 的话,不需要管理员手动建立连结档, 透过如下的指令可以来处理默认 启动、预设不启动、观察预设启动否的行为:
- 预设要启动: chkconfig daemon on
- 预设不启动: chkconfig daemon off
- 观察预设为启动否: chkconfig --list daemon
- 执行等级的切换行为:
当你要从纯文本界面 (runlevel 3) 切换到图形界面 (runlevel 5), 不需要手动启动、关闭该执行等级的相关 服务,只要『 init 5 』即可切换,init 这小子会主动去分析 /etc/rc.d/rc[35].d/ 这两个目录内的脚本, 然后 启动转换 runlevel 中需要的服务~就完成整体的 runlevel 切换。
systemd 使用的 unit 分类
从 CentOS 7.x 以后,Red Hat 系列的 distribution 放弃沿用多年的 System V 开机启动服务的流程, 就是前一小节提到的 init 启动脚本的方法, 改用 systemd 这个启动服务管理机制~那么 systemd 有什么好处呢?
- 平行处理所有服务,加速开机流程:
旧的 init 启动脚本是『一项一项任务依序启动』的模式,因此不相依的服务也是得要一个一个的等待。但 目前我们的硬件主机系统与操作系统几乎都支持多核心架构了, 没道理未相依的服务不能同时启动啊! systemd 就是可以让所有的服务同时启动,因此你会发现到,系统启动的速度变快了!
- 一经要求就响应的 on-demand 启动方式:
systemd 全部就是仅有一只 systemd 服务搭配 systemctl 指令来处理,无须其他额外的指令来支持。不像 systemV 还要 init, chkconfig, service... 等等指令。 此外, systemd 由于常驻内存,因此任何要求 (on-demand) 都可以立即处理后续的 daemon 启动的任务。
- 服务相依性的自我检查:
由于 systemd 可以自定义服务相依性的检查,因此如果 B 服务是架构在 A 服务上面启动的,那当你在没 有启动 A 服务的情况下仅手动启动 B 服务时, systemd 会自动帮你启动 A 服务喔!这样就可以免去管 理员得要一项一项服务去分析的麻烦~
- 依 daemon 功能分类:
systemd 旗下管理的服务非常多,因此,首先 systemd 先定义所 有的服务为一个服务单位 (unit),并将该 unit 归类到不同的服务类型 (type) 去。 旧的 init 仅分为 stand alone 与 super daemon 实在不够看,systemd 将服务单位 (unit) 区分为 service, socket, target, path, snapshot, timer 等多种不同的类型(type), 方便管理员的分类与记忆。
- 将多个 daemons 集合成为一个群组:
如同 systemV 的 init 里头有个 runlevel 的特色,systemd 亦将许多的功能集合成为一个所谓的 target 项 目,这个项目主要在设计操作环境的建置, 所以是集合了许多的 daemons,亦即是执行某个 target 就是执 行好多个 daemon 的意思!
- 向下兼容旧有的 init 服务脚本:
基本上, systemd 是可以兼容于 init 的启动脚本的,因此,旧的 init 启动脚本也能够透过 systemd 来管 理,只是更进阶的 systemd 功能就没有办法支持就是了。
systemd 也是有些地方无法完全取代 init 的!包括:
- 在 runlevel 的对应上,大概仅有 runlevel 1, 3, 5 有对应到 systemd 的某些 target 类型而已,没有全部对应;
- 全部的 systemd 都用 systemctl 这个管理程序管理,而 systemctl 支持的语法有限制,不像/etc/init.d/daemon 就是纯脚本可以自定义参数,systemctl 不可自定义参数。;
- 如果某个服务启动是管理员自己手动执行启动,而不是使用 systemctl 去启动的 (例如你自己手动输入 crond 以启动 crond 服务),那么 systemd 将无法侦测到该服务,而无法进一步管理。
- systemd 启动过程中,无法与管理员透过 standard input 传入讯息!因此,自行撰写 systemd 的启动设定时, 务必要取消互动机制~(连透过启动时传进的标准输入讯息也要避免!)
- systemd 的配置文件放置目录
基本上, systemd 将过去所谓的 daemon 执行脚本通通称为一个服务单位 (unit),而每种服务单位
依据功能来区分时,就分类为不同的类型 (type)。 基本的类型有包括系统服务、数据监听与交换的 插槽档服务 (socket)、储存系统状态的快照类型、提供不同类似执行等级分类的操作环境 (target) 等等。配置文件都放置在底下的目录中:
- /usr/lib/systemd/system/:每个服务最主要的启动脚本设定,有点类似以前的 /etc/init.d 底下的文件;
- /run/systemd/system/:系统执行过程中所产生的服务脚本,这些脚本的优先序要比 /usr/lib/systemd/system/ 高!
- /etc/systemd/system/:管理员依据主机系统的需求所建立的执行脚本,其实这个目录有点像以前/etc/rc.d/rc5.d/Sxx 之类的功能!执行优先序又比 /run/systemd/system/ 高喔!
- systemd 的 unit 类型分类说明
那 /usr/lib/systemd/system/ 以下的数据如何区分上述所谓的不同的类型 (type) 呢?很简单!看扩展 名!举例来说,我们来瞧瞧上一章谈到的 vsftpd 这个范例的启动脚本设定, 还有 crond 与纯文本 模式的 multi-user 设定:
[root@study ~]# ll /usr/lib/systemd/system/ | grep -E '(vsftpd|multi|cron)'
-rw-r--r--. 1 root root 284 7月 30 2014 crond.service
-rw-r--r--. 1 root root 567 3月 6 06:51 multipathd.service
-rw-r--r--. 1 root root 524 3月 6 13:48 multi-user.target
drwxr-xr-x. 2 root root 4096 5月 4 17:52 multi-user.target.wants
lrwxrwxrwx. 1 root root 17 5月 4 17:52 runlevel2.target -> multi-user.target
lrwxrwxrwx. 1 root root 17 5月 4 17:52 runlevel3.target -> multi-user.target
lrwxrwxrwx. 1 root root 17 5月 4 17:52 runlevel4.target -> multi-user.target
-rw-r--r--. 1 root root 171 6月 10 2014 vsftpd.service
-rw-r--r--. 1 root root 184 6月 10 2014 vsftpd@.service
-rw-r--r--. 1 root root 89 6月 10 2014 vsftpd.target
# 比较重要的是上头提供的那三行特殊字体的部份!
所以我们可以知道 vsftpd 与 crond 其实算是系统服务 (service),而 multi-user 要算是执行环境相关 的类型 (target type)。根据这些扩展名的类型, 我们大概可以找到几种比较常见的 systemd 的服务类型如下:
扩展名 | 主要服务功能 |
---|---|
.service | 一般服务类型 (service unit):主要是系统服务,包括服务器本身所需要的本地服务以及网络服务都 是!比较经常被使用到的服务大多是这种类型! 所以,这也是最常见的类型了! |
.socket | 内部程序数据交换的插槽服务 (socket unit):主要是 IPC (Inter-process communication) 的传输讯息插槽文件 (socket file) 功能。 这种类型的服务通常在 监控讯息传递的插槽文件,当有透过此插槽文件传递讯息来说要链接服务时,就依据当时的状态将该用户的要求传送到对应的 daemon, 若 daemon 尚未启动,则启动该 daemon 后再传送用户的要求。使用 socket 类型的服务一般是比较不会被用到的服务,因此在开机时通常会稍微延迟 启动的时间 (因为比较没有这么常用嘛!)。一般用于本地服务比较多,例如我们的图 形界面很多的软件都是透过 socket 来进行本机程序数据交换的行为。 (这与早期的 xinetd 这个 super daemon 有部份的相似喔!) |
.target | 执行环境类型 (target unit):其实是一群 unit 的集合,例如上面表格中谈到的 multi-user.target 其实 就是一堆服务的集合~也就是说, 选择执行 multi-user.target 就是执行一堆其他 .service 或/ 及 .socket 之类的服务就是了! |
.mount .automount | 文件系统挂载相关的服务 (automount unit / mount unit):例如来自网络的自动挂载、NFS 文件系统 挂载等与文件系统相关性较高的程序管理。 |
.path | 侦测特定文件或目录类型 (path unit):某些服务需要侦测某些特定的目录来提供队列服务,例如最 常见的打印服务,就是透过侦测打印队列目录来启动打印功能! 这时就得要 .path 的服务类型支持 了! |
.timer | 循环执行的服务 (timer unit):这个东西有点类似 anacrontab 喔!不过是由 systemd 主动提供的, 比 anacrontab 更加有弹性! |