Linux06 守护进程
Linux守护进程
守护进程(daemon),也可以叫做系统服务,指后台运行的、等待特定事件发生并提供服务的程序。典型的例子如网页服务器,等待网页传输请求并提供传输服务;又如ssh服务器,等待用户登入操作。许多守护进程提供不可见的服务,比如记录日志(syslog,metalog)、校准时间(ntpd)。
一、守护进程
守护进程是用systemd管理的. 用户用systemctl命令来管理. systemctl读取<service>.service文件中包含怎么和什么时候启动相关的进程. Service的文件保存在/{etc,usr/lib,run}/systemd/system中.
systemd 开启和监督整个系统是基于 unit 的概念。unit 是由一个与配置文件对应的名字和类型组成的(例如:avahi.service unit 有一个具有相同名字的配置文件,是守护进程 avahi 的一个封装单元)。unit 有以下几种类型:
1. service :代表一个后台服务进程,比如 mysqld。这是最常用的一类。
2. socket :此类配置单元封装系统和互联网中的一个 套接字 。当下,systemd 支持流式、数据报和连续包的 AF_INET、AF_INET6、AF_UNIX socket 。每一个套接字配置单元都有一个相应的服务配置单元 。相应的服务在第一个"连接"进入套接字时就会启动(例如:nscd.socket 在有新连接后便启动 nscd.service)。
3. device :此类配置单元封装一个存在于 Linux 设备树中的设备。每一个使用 udev 规则标记的设备都将会在 systemd 中作为一个设备配置单元出现。
4. mount :此类配置单元封装文件系统结构层次中的一个挂载点。Systemd 将对这个挂载点进行监控和管理。比如可以在启动时自动将其挂载;可以在某些条件下自动卸载。Systemd 会将/etc/fstab 中的条目都转换为挂载点,并在开机时处理。
5. automount :此类配置单元封装系统结构层次中的一个自挂载点。每一个自挂载配置单元对应一个挂载配置单元 ,当该自动挂载点被访问时,systemd 执行挂载点中定义的挂载行为。
6. swap: 和挂载配置单元类似,交换配置单元用来管理交换分区。用户可以用交换配置单元来定义系统中的交换分区,可以让这些交换分区在启动时被激活。
7. target :此类配置单元为其他配置单元进行逻辑分组。它们本身实际上并不做什么,只是引用其他配置单元而已。这样便可以对配置单元做一个统一的控制。这样就可以实现大家都已经非常熟悉的运行级别概念。比如想让系统进入图形化模式,需要运行许多服务和配置命令,这些操作都由一个个的配置单元表示,将所有这些配置单元组合为一个目标(target),就表示需要将这些配置单元全部执行一遍以便进入目标所代表的系统运行状态。 (例如:multi-user.target 相当于在传统使用 SysV 的系统中运行级别 5)
8. timer:定时器配置单元用来定时触发用户定义的操作,这类配置单元取代了 atd、crond 等传统的定时服务。
9. snapshot :与 target 配置单元相似,快照是一组配置单元。它保存了系统当前的运行状态。
Target 和运行级别
systemd 用目标(target)替代了运行级别的概念,提供了更大的灵活性,如您可以继承一个已有的目标,并添加其它服务,来创建自己的目标。下表列举了 systemd 下的目标和常见 runlevel 的对应关系:
表 1. Sysvinit 运行级别和 systemd 目标的对应表
| Sysvinit 运行级别 | Systemd 目标 | 备注 |
| 0 | poweroff.target, runlevel0.target | 关闭系统 |
| 1, s, single | rescue.target, runlevel1.target | 单用户模式 |
| 2, 4 | multi-user.target, runlevel2.target, runlevel4.target | 用户定义/域特定运行级别。默认等同于 3 |
| 3 | multi-user.target, runlevel3.target | 多用户,非图形化。用户可以通过多个控制台或网络登录 |
| 5 | graphical.target, runlevel5.target | 多用户,图形化。通常为所有运行级别 3 的服务外加图形化登录 |
| 6 | reboot.target, runlevel6.target | 重启 |
| emergency | emergency.target | 紧急 Shell |
二、Systemd 的使用
下面针对技术人员的不同角色来简单地介绍一下 systemd 的使用。
1. 系统软件开发人员
开发人员需要了解 systemd 的更多细节。
Unit 文件的编写
对于开发者来说,工作量最大的部分应该是编写配置单元文件,定义所需要的单元。
举例来说,开发人员开发了一个新的服务程序,比如 httpd,就需要为其编写一个配置单元文件以便该服务可以被 systemd 管理。在该文件中定义服务启动的命令行语法,以及和其他服务的依赖关系等。
此外我们之前已经了解到,systemd 的功能繁多,不仅用来管理服务,还可以管理挂载点,定义定时任务等。这些工作都是由编辑相应的配置单元文件完成的。我在这里给出几个配置单元文件的例子。
下面是 SSH 服务的配置单元文件,服务配置单元文件以.service 为文件名后缀。
#cat /etc/system/system/sshd.service
[Unit]
Description=OpenSSH server daemon
[Service]
EnvironmentFile=/etc/sysconfig/sshd
ExecStartPre=/usr/sbin/sshd-keygen
ExecStart=/usrsbin/sshd –D $OPTIONS
ExecReload=/bin/kill –HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target
文件分为三个小节。第一个是[Unit]部分,这里仅仅有一个描述信息。第二部分是 Service 定义,其中,ExecStartPre 定义启动服务之前应该运行的命令;ExecStart 定义启动服务的具体命令行语法。第三部分是[Install],WangtedBy 表明这个服务是在多用户模式下所需要的。
那我们就来看下 multi-user.target 吧:
#cat multi-user.target
[Unit]
Description=Multi-User System
Documentation=man.systemd.special(7)
Requires=basic.target
Conflicts=rescue.service rescure.target
After=basic.target rescue.service rescue.target
AllowIsolate=yes
[Install]
Alias=default.target
第一部分中的 Requires 定义表明 multi-user.target 启动的时候 basic.target 也必须被启动;另外 basic.target 停止的时候,multi-user.target 也必须停止。如果您接着查看 basic.target 文件,会发现它又指定了 sysinit.target 等其他的单元必须随之启动。同样 sysinit.target 也会包含其他的单元。采用这样的层层链接的结构,最终所有需要支持多用户模式的组件服务都会被初始化启动好。
在[Install]小节中有 Alias 定义,即定义本单元的别名,这样在运行 systemctl 的时候就可以使用这个别名来引用本单元。这里的别名是 default.target,比 multi-user.target 要简单一些。。。
此外在/etc/systemd/system 目录下还可以看到诸如*.wants 的目录,放在该目录下的配置单元文件等同于在[Unit]小节中的 wants 关键字,即本单元启动时,还需要启动这些单元。比如您可以简单地把您自己写的 foo.service 文件放入 multi-user.target.wants 目录下,这样每次都会被默认启动了。
最后,让我们来看看 sys-kernel-debug.mout 文件,这个文件定义了一个文件挂载点:
#cat sys-kernel-debug.mount
[Unit]
Description=Debug File System
DefaultDependencies=no
ConditionPathExists=/sys/kernel/debug
Before=sysinit.target
[Mount]
What=debugfs
Where=/sys/kernel/debug
Type=debugfs
这个配置单元文件定义了一个挂载点。挂载配置单元文件有一个[Mount]配置小节,里面配置了 What,Where 和 Type 三个数据项。这都是挂载命令所必须的,例子中的配置等同于下面这个挂载命令:
mount –t debugfs /sys/kernel/debug debugfs
配置单元文件的编写需要很多的学习,必须参考 systemd 附带的 man 等文档进行深入学习。希望通过上面几个小例子,大家已经了解配置单元文件的作用和一般写法了。
2.
系统管理员
systemd 的主要命令行工具:
systemctl :用作内省和控制 systemd 系统和服务管理器的状态。
systemd-cgls:以树形递归显示选中的 Linux 控制组结构层次。
systemadm:一个 systemd 系统和服务管理器的图形化前端。是 systemd-gtk 软件包的一部分。这还只是前期版本,尚需完善。除非你是一个开发者,否则请不要使用它。
表 2. Systemd 命令和 sysvinit 命令的对照表
| Sysvinit 命令 | Systemd 命令 | 备注 |
|---|---|---|
| service foo start | systemctl start foo.service | 用来启动一个服务 (并不会重启现有的) |
| service foo stop | systemctl stop foo.service | 用来停止一个服务 (并不会重启现有的)。 |
| service foo restart | systemctl restart foo.service | 用来停止并启动一个服务。 |
| service foo reload | systemctl reload foo.service | 当支持时,重新装载配置文件而不中断等待操作。 |
| service foo condrestart | systemctl condrestart foo.service | 如果服务正在运行那么重启它。 |
| service foo status | systemctl status foo.service | 汇报服务是否正在运行。 |
| ls /etc/rc.d/init.d/ | systemctl list-unit-files --type=service | 用来列出可以启动或停止的服务列表。 |
| chkconfig foo on | systemctl enable foo.service | 在下次启动时或满足其他触发条件时设置服务为启用 |
| chkconfig foo off | systemctl disable foo.service | 在下次启动时或满足其他触发条件时设置服务为禁用 |
| chkconfig foo | systemctl is-enabled foo.service | 用来检查一个服务在当前环境下被配置为启用还是禁用。 |
| chkconfig –list | systemctl list-unit-files --type=service | 输出在各个运行级别下服务的启用和禁用情况 |
| chkconfig foo –list | ls /etc/systemd/system/*.wants/foo.service | 用来列出该服务在哪些运行级别下启用和禁用。 |
| chkconfig foo –add | systemctl daemon-reload | 当您创建新服务文件或者变更设置时使用。 |
| telinit 3 | systemctl isolate multi-user.target (OR systemctl isolate runlevel3.target OR telinit 3) | 改变至多用户运行级别。 |
表 3,systemd 电源管理命令
| 命令 | 操作 |
|---|---|
| systemctl reboot | 重启机器 |
| systemctl poweroff | 关机 |
| systemctl suspend | 待机 |
| systemctl hibernate | 休眠 |
| systemctl hybrid-sleep | 混合休眠模式(同时休眠到硬盘并待机) |
关机不是每个登录用户在任何情况下都可以执行的,一般只有管理员才可以关机。正常情况下系统不应该允许 SSH 远程登录的用户执行关机命令。否则其他用户正在工作,一个用户把系统关了就不好了。
为了决定关机命令是否可行,系统需要了解当前用户登录情况,如果用户从 SSH 登录,不允许其执行关机命令;如果普通用户从本地登录,且该用户是系统中的唯一会话,则允许其执行关机命令;这些判断都需要 logind 维护所有的用户会话和登录情况。
注:
在 systemctl 参数中添加 -H <用户名>@<主机名> 可以实现对其他机器的远程控制。该过程使用ssh链接。
1. systemctl 是最主要的工具
在开机启动的时候添加,删除服务使用 systemctl enable|disable <service_name>命令
在系统运行时手动启动,停止服务, 使用 systemctl start|stop <service_name>命令.
为了重启服务, 使用 systemctl restart <service_name>命令.
禁用或取消禁用一个单元(禁用后,间接启动也是不可能的): systemctl mask|unmask <单元>
杀死服务 systemctl kill <service_name>命令
查看运行状态
查看当前服务的运行状态, 使用 systemctl status <service_name>命令.
检查服务是否开机启动,使用 systemctl is-enabled <service_name>; echo $?命令.
列出所有系统挂载点 systemctl list-unit-files --type=mount
检查某个服务的所有配置细节 systemctl show httpd
检查systemd和systemctl的二进制文件和库文件的安装位置
# whereis systemd
# whereis systemctl
改变运行级别
你可以使用下面的命令切换到“运行级 3 ”:
systemctl isolate multi-user.target (or) systemctl isolate runlevel3.target
改变默认运行级别
systemd 使用链接来指向默认的运行级别。在创建新的链接前,你可以通过下面命令删除存在的链接:
rm /etc/systemd/system/default.target
默认切换到运行级 3 :
ln -sf /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
查看当下运行级别
systemctl list-units --type=target
分析系统状态
输出激活的单元:
$ systemctl
$ systemctl list-units
输出运行失败的单元:
$ systemctl --failed
所有可用的单元文件存放在 /usr/lib/systemd/system/ 和 /etc/systemd/system/ 目录(后者优先级更高)。查看所有已安装服务:
$ systemctl list-unit-files
系统引导性能分析
Systemd提供了工具用于识别和定位引导相关的问题或性能影响。Systemd-analyze是一个内建的命令,可以用来检测引导过程。你可以找出在启动过程中出错的单元,然后跟踪并改正引导组件的问题。在下面列出一些常用的systemd-analyze命令。
systemd-analyze time 用于显示内核和普通用户空间启动时所花的时间。
systemd-analyze blame 会列出所有正在运行的单元,按从初始化开始到当前所花的时间排序,通过这种方式你就知道哪些服务在引导过程中要花较长时间来启动。
systemd-analyze verify 显示在所有系统单元中是否有语法错误。
systemd-analyze plot 可以用来把整个引导过程写入一个SVG格式文件里。systemd-analyze plot > boot.svg
systemd-analyze critical-chain 分析启动时的关键链
分析某个服务(httpd)的关键链 systemd-analyze critical-chain httpd.service
获取某个服务(httpd)的依赖性列表 systemctl list-dependencies httpd.service
按等级列出控制组 systemd-cgls
按CPU、内存、输入和输出列出控制组 systemd-cgtop
浙公网安备 33010602011771号