MarkLee's Studio.

openEuler:系统服务的配置和管理

2024/07/31
loading

Tag: #任务管理 #系统服务 #Linux

系统服务基本概念

系统服务

系统服务是在系统启动时候自启动的一些后台程序,主要负责一些系统必须的核心功能,如:网络服务,文件系统管理器,日志记录等等
一些常见的系统服务包括:

  • 网络服务:如SSH(远程登录)、HTTP服务器(如Apache)、DNS服务器(如BIND)等。
  • 日志服务:如Syslog,用于记录系统和应用程序的日志信息。
  • 文件系统服务:如NFS(网络文件系统),允许在不同主机之间共享文件。
  • 时间同步服务:如NTP(网络时间协议),用于同步系统时间。

守护进程与系统服务的概念区分

  • 守护进程是一种脱离终端,在后台运行的进程
  • 这些后台运行的进程其中一些提供系统服务
  • 总的来说守护进程是一个更广泛的概念,因为守护进程仍可能提供一些非系统的服务

系统和服务管理器 — systemd

简介

systemd 设计目标是提供一套完整的系统启动和管理的解决方案

根据 Linux 惯例,字母d是守护进程(daemon)的缩写。 Systemd 这个名字的含义,就是它要守护整个系统。

系统管理

现在 systemd 已经成为很多发行版的标准配置
使用 systemctl --version 查看 systemd 的版本

1
2
3
[root@localhost ~]# systemctl --version
systemd 249 (v249-52.oe2203sp2)
+PAM +AUDIT +SELINUX -APPARMOR +IMA -SMACK +SECCOMP +GCRYPT +GNUTLS -OPENSSL +ACL +BLKID -CURL -ELFUTILS -FIDO2 +IDN2 -IDN -IPTC +KMOD -LIBCRYPTSETUP +LIBFDISK +PCRE2 -PWQUALITY +P11KIT -QRENCODE +BZIP2 +LZ4 +XZ +ZLIB -ZSTD +XKBCOMMON +UTMP +SYSVINIT default-hierarchy=legacy

systemd 功能强大体系复杂,下图为 systemd 架构图

Unit

systemd 开启和监督服务是基于 Unit 概念
不同的系统资源对应不同的 Unit,Unit 分为 12 类:

  • Service unit:系统服务
  • Target unit:多个 Unit 构成的一个组
  • Device Unit:硬件设备
  • Mount Unit:文件系统的挂载点
  • Automount Unit:自动挂载点
  • Path Unit:文件或路径
  • Scope Unit:不是由 Systemd 启动的外部进程
  • Slice Unit:进程组
  • Snapshot Unit:Systemd 快照,可以切回某个快照
  • Socket Unit:进程间通信的 socket
  • Swap Unit:swap 文件
  • Timer Unit:定时器

systemctl list-units命令可以查看当前系统的所有 Unit

Unit的配置文件

Unit 依赖关系

Unit 之间存在依赖关系:A 依赖于 B,就意味着 Systemd 在启动 A 的时候,同时会去启动 B。

存放配置文件的目录

Systemd 默认从目录/etc/systemd/system/读取配置文件。但是,里面存放的大部分文件都是符号链接,指向目录/usr/lib/systemd/system/,真正的配置文件存放在那个目录。

符号链接可以简单理解为一个副本,或者类比为 Windows 中的快捷方式

配置文件的格式

以下面文件内容为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@localhost system]# cat cron.service
[Unit]
Description=Command Scheduler
After=auditd.service nss-user-lookup.target systemd-user-sessions.service time-sync.target ypbind.service autofs.service

[Service]
EnvironmentFile=/etc/sysconfig/crond
ExecStart=/usr/sbin/crond -n $CRONDARGS
ExecReload=/bin/kill -URG $MAINPID
KillMode=process
Restart=on-failure
RestartSec=30s

[Install]
WantedBy=multi-user.target
Alias=cron.service

配置文件主要分为三个区块

[ Unit ] 区块

定义单元的元数据和依赖关系:

  • Description:描述单元的简要信息。
  • Documentation:相关文档的URL。
  • After:指定此单元应在列出的其他单元启动后启动。
[ Service ] 区块

该区块只有 .service 服务单元有,定义其行为和属性

  • EnvironmentFile:指定一个环境变量文件,这里是/etc/sysconfig/crond
  • ExecStart:定义启动服务的命令,这里是/usr/sbin/crond -n $CRONDARGS,其中$CRONDARGS是从环境文件中读取的变量。
  • ExecReload:定义重新加载服务配置时执行的命令,这里是/bin/kill -URG $MAINPID
  • KillMode:定义如何终止服务,这里是process,表示杀死主进程和子进程。
  • Restart:定义重启策略,这里是on-failure,表示在服务失败时重启。
  • RestartSec:定义重启前的等待时间,这里是30秒。
[ Install ] 区块
  • WantedBy:定义此服务在哪些目标单元下启用,这里是multi-user.target
  • Alias:定义此服务的别名,这里是cron.service

挂载和自动挂载点管理

Systemd 监控和管理挂载和自动挂载点。
Systemd 使用 _mount 单元作为挂载点 ,自动挂载单元用于自动挂载点_。


管理系统服务

systemd 管理任务组,分配资源,跟踪和管理进程的生命周期是依据 cgroup 特性的,可见文章 [[浅谈 Cgroups 和 systemd]]

systemd 的命令组

systemd 不是一个命令,而是一组命令

systemctl

systemctlsystemd 的主命令,用于系统管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 重启系统
$ sudo systemctl reboot

# 关闭系统,切断电源
$ sudo systemctl poweroff

# CPU停止工作
$ sudo systemctl halt

# 暂停系统
$ sudo systemctl suspend

# 让系统进入冬眠状态
$ sudo systemctl hibernate

# 让系统进入交互式休眠状态
$ sudo systemctl hybrid-sleep

# 启动进入救援状态(单用户状态)
$ sudo systemctl rescue

Unit管理

对于用户来说,最常用的是下面这些命令,用于启动和停止 Unit(主要是 service)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 
# 立即启动一个服务
$ sudo systemctl start apache.service

# 立即停止一个服务
$ sudo systemctl stop apache.service

# 重启一个服务
$ sudo systemctl restart apache.service

# 杀死一个服务的所有子进程
$ sudo systemctl kill apache.service

# 重新加载一个服务的配置文件
$ sudo systemctl reload apache.service

# 重载所有修改过的配置文件
$ sudo systemctl daemon-reload

# 显示所有服务
$ systemctl list-units --type service

# 显示某个 Unit 的所有底层参数
$ systemctl show httpd.service

# 显示某个 Unit 的指定属性的值
$ systemctl show -p CPUShares httpd.service

# 设置某个 Unit 的指定属性
$ sudo systemctl set-property httpd.service CPUShares=500

systemd-analyze

systemd-analyze 命令用于查看启动耗时

1
2
3
systemd-analyze
Startup finished in 855ms (kernel) + 3.890s (initrd) + 9.291s (userspace) = 14.037s
multi-user.target reached after 3.277s in userspace
1
2
3
4
5
6
7
8
9
10
# 查看启动耗时
$ systemd-analyze
# 查看每个服务的启动耗时
$ systemd-analyze blame

# 显示瀑布状的启动过程流
$ systemd-analyze critical-chain

# 显示指定服务的启动流
$ systemd-analyze critical-chain atd.service

hostnamectl

hostnamectl命令用于查看当前主机的信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 显示当前主机的信息
$ sudo hostnamectl
Static hostname: n/a
Transient hostname: localhost
Icon name: computer-vm
Chassis: vm
Machine ID: 3af2603ba85e4b9998585459a851f47a
Boot ID: fe23723dd9ee439581cc046701c0c6d0
Virtualization: kvm
Operating System: openEuler 22.03 (LTS-SP2)
Kernel: Linux 5.10.0-153.12.0.92.oe2203sp2.x86_64
Architecture: x86-64
Hardware Vendor: Tencent Cloud
Hardware Model: CVM
1
2
# 设置主机名。
$ sudo hostnamectl set-hostname rhel7

任务管理

cron & crontab

“Cron”一词来自于希腊语中的”kronos”(Κρόνος),意为时间或期限。

关键概念

  • cron:cron 是一个守护进程,负责进行周期性的调度
  • crontab:这里有两个含义:
    • 负责管理 cron 调度的工具
    • cron 调度的配置文件,每个用户可以有自己的 crontab 文件,通常存储在 /var/spool/cron/ 目录下,以用户名命名。这些文件包含了用户定义的定时任务列表。

cron 运行机制

  • 守护进程启动
    • 系统启动时,cron 守护进程会作为后台进程启动,并持续运行监听任务的执行需求。
  • 定时检查
    • Cron 守护进程每分钟检查一次预定任务的执行时间,即使系统时间发生变化,也会确保按照新的时间执行任务。
  • 读取 crontab 文件
    • Cron 会读取系统中每个用户的 crontab 文件,这些文件通常存储在 /var/spool/cron/ 目录中,文件名与用户名对应。
  • 执行任务
    • 当 cron 执行任务时,它会以预定义的用户环境变量运行命令。这意味着任务的执行环境可能会与手动执行命令时稍有不同,例如路径变量和其他环境设置。
  • 记录日志
    • 每次任务执行完成后,cron 会将执行的结果记录到系统日志中,例如 /var/log/syslog/var/log/cron。这些日志记录对于监视任务执行情况和排查问题非常重要。

crontab 配置文件语法

我们查看 /etc/crontab 配置文件

可以看到语法为: * * * * * user-name command_to_execute

crontab 配置工具

命令格式 crontab -u user_name -e -l -r

  • -e 编辑配置文件
  • -l 列出配置文件
  • -r 删除配置文件内容

demo 实现简单的定时工具

编写执行脚本


将当前时间输出到 timer.txt 文件

编辑 crontab 文件

使用 crontab -e 编写 crontab 文件

每分钟执行脚本,并将错误输出和标准输出重定向

查看结果


每分钟 1 秒时候,时间被写入 timer.txt

查看我们刚才编写的定时程序

使用 & 将程序放在后台运行

在指令最后加上 & 符号,将该程序放在后台运行,该进程的父进程为当前 bash

demo

编写 python 程序,每十秒钟将时间写入 timer.txt 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import datetime as dt

import time

file_path = "/root/openEuler_study/timer.txt"
while(1):

    current_time = dt.datetime.now()

    time_str = current_time.strftime("%Y-%m-%d %H:%M:%S")

    with open(file_path,"+a") as file:

        file.write(time_str + "\n")

    time.sleep(10)

 将该程序放在后台运行
 
 [ 1 ] 中数字代表 jobs 编号,后面数字是该进程 pid
 使用 ps -l 查看完整信息
 
 我们可以看到该进程的父进程为当前 bash
 查看 timer.txt 文件是否被正确写入
 
 每十秒写入一次
 结束该进程我们可以使用 kill %[josb ID] or kill [PID]
 

At 实现定时任务管理

1. 用户提交任务

当用户通过 at 命令提交任务时,系统会记录下任务的具体执行时间和需要执行的命令。命令示例如下:

或者使用 echo 提交任务
echo "sh /path/to/your/script.sh" | at 15:30

2. 任务存储

任务提交后,at 命令会将任务信息存储在一个指定目录中,通常是 /var/spool/at。每个任务会生成一个文件,文件名包含了任务的执行时间和其他信息。

3. 任务调度

系统中有一个守护进程 atd,它负责定期检查任务存储目录中的任务文件。atd 会读取这些文件,解析任务的执行时间,并将任务排入调度队列。

4. 任务执行

atd 检测到某个任务的执行时间到了,它会读取该任务文件中的命令,并在指定的时间执行这些命令。执行的过程类似于用户在命令行直接输入这些命令。

nohub 命令

参考资料

CATALOG
  1. 1. 系统服务基本概念
    1. 1.1. 系统服务
    2. 1.2. 守护进程与系统服务的概念区分
    3. 1.3. 系统和服务管理器 — systemd
      1. 1.3.1. 简介
      2. 1.3.2. 系统管理
      3. 1.3.3. Unit
        1. 1.3.3.1. Unit的配置文件
          1. 1.3.3.1.1. Unit 依赖关系
          2. 1.3.3.1.2. 存放配置文件的目录
        2. 1.3.3.2. 配置文件的格式
          1. 1.3.3.2.1. [ Unit ] 区块
          2. 1.3.3.2.2. [ Service ] 区块
          3. 1.3.3.2.3. [ Install ] 区块
      4. 1.3.4. 挂载和自动挂载点管理
      5. 1.3.5.
  2. 2. 管理系统服务
    1. 2.1. systemd 的命令组
      1. 2.1.1. systemctl
        1. 2.1.1.1. Unit管理
      2. 2.1.2. systemd-analyze
      3. 2.1.3. hostnamectl
  3. 3. 任务管理
    1. 3.1. cron & crontab
      1. 3.1.1. 关键概念
      2. 3.1.2. cron 运行机制
      3. 3.1.3. crontab 配置文件语法
      4. 3.1.4. crontab 配置工具
      5. 3.1.5. demo 实现简单的定时工具
        1. 3.1.5.1. 编写执行脚本
        2. 3.1.5.2. 编辑 crontab 文件
        3. 3.1.5.3. 查看结果
    2. 3.2. 使用 & 将程序放在后台运行
      1. 3.2.1. demo
    3. 3.3. At 实现定时任务管理
      1. 3.3.1. 1. 用户提交任务
      2. 3.3.2. 2. 任务存储
      3. 3.3.3. 3. 任务调度
      4. 3.3.4. 4. 任务执行
    4. 3.4. nohub 命令
  4. 4. 参考资料