searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

systemd job介绍

2024-09-23 09:43:04
17
0

     在 systemd 中,job 是负责执行特定任务的一个重要概念,通常与 unit 紧密相关。为了有效地管理 Linux 系统中的服务、设备、挂载点、计时器等资源,systemd 通过创建和调度 job 来实现启动、停止、重启和重新加载等操作。本文将深入探讨 job 的详细机制,尤其是它与 unit 之间的关系,以及如何通过依赖管理、并发控制和状态跟踪来确保系统的高效运行。

1. unit 和 job 的基本概念

       在讨论 job 之前,我们必须理解 unit 的概念。unit 是 systemd 管理的基础对象,表示系统中的某种资源或服务。每个 unit 都有一个配置文件,用于定义其行为和依赖关系。这些配置文件通常位于 /etc/systemd/system//lib/systemd/system/ 目录中。systemd 支持多种不同类型的 unit,常见的包括:

  • Service unit (.service): 用于管理后台服务。比如 nginx.servicesshd.service,它们代表具体的系统服务。
  • Socket unit (.socket): 用于管理套接字激活的服务。某些服务仅在需要时才会启动,通过 socket 单元实现。
  • Target unit (.target): 表示一组 unit 的集合,是一种逻辑同步点。比如 multi-user.target 用于表示多用户运行级别。
  • Mount unit (.mount): 用于管理文件系统挂载点。
  • Timer unit (.timer): 用于定时启动的任务,类似于 cron 任务。

       每个 unit 在执行操作时都会生成对应的 job,这是 systemd 用于调度和管理这些操作的机制。job 是针对某个 unit 进行的具体任务,比如启动、停止或重启服务。

2. job 的类型与 unit 操作

      job 的类型决定了它对 unit 的操作方式。以下是 systemd 支持的常见 job 类型,以及它们与 unit 操作的对应关系:

  • start: 启动一个 unit。如果 unit 已经处于运行状态,此 job 将不会重复启动该 unit。
  • stop: 停止一个 unit,并确保与其依赖相关的其他 unit 也能够正确停止。
  • reload: 重新加载 unit 的配置文件,而不中断当前运行的服务。这通常用于需要在不中断服务的情况下应用新配置。
  • restart: 停止并重新启动一个 unit,相当于依次执行 stopstart 操作。
  • try-restart: 尝试重新启动一个 unit,但仅在 unit 已经运行时执行操作。如果 unit 未启动,则不会做任何事情。
  • reload-or-restart: 首先尝试重新加载配置,如果 reload 操作不支持,则执行 restart 操作。
  • try-reload-or-restart: 如果 unit 正在运行,首先尝试重新加载配置,如果不支持 reload 或者失败,则执行 restart。如果 unit 未启动,什么也不会做。

        这些 job 类型定义了 systemd 如何操作 unit。当你执行诸如 systemctl start nginx.service 这样的命令时,systemd 会为 nginx.service 创建一个 start job,并执行与其关联的操作。

3. job 与 unit 的关系

       job 与 unit 的关系体现在 systemd 通过 job 操作 unit 并根据 unit 文件中定义的依赖关系来处理任务的顺序。每个 unit 文件可以定义自己的依赖项,systemd 会根据这些依赖项自动生成和调度相应的 job。这种关系不仅使得 systemd 能够灵活管理服务,还能确保复杂的系统资源在启动和关闭时保持一致性。

     

      上图展示了 Job 如何与 Unit 的生命周期和操作紧密结合,并通过 Job 管理和调度不同 Unit 的状态转换,解释如下:

    1. Job 和 Unit 的关系

      • 一个 Job 通过启动、停止、重启和重新加载操作作用于不同的 Unit(如 Unit A 和 Unit B)。
      • JobCreated 表示一个 Job 的创建,随后执行不同的操作(启动、停止、重启、重新加载)。
      • UnitAUnitB 分别有自己独立的生命周期状态(ActiveInactive),这些状态会随着 Job 操作的执行而改变。
    2. 依赖关系

      • UnitB 在 UnitA 启动成功后才能启动,表示依赖关系。
    3. Job 操作结束

      • 每个操作执行完毕后,Job 将结束,回到初始状态。

3.1 依赖关系管理

   unit 文件中定义的依赖关系决定了 systemd 如何调度和执行 job。常见的依赖关系定义包括:

  • Requires=: 强依赖关系,表示当前 unit 依赖另一个 unit 的存在。如果依赖的 unit 启动失败,则当前 unit 也会失败。比如,如果 A.service Requires=B.service,则在启动 A.service 时,systemd 会先启动 B.service。如果 B 启动失败,则 A 的启动也会中止。
  • Wants=: 弱依赖关系,表示 systemd 希望关联的 unit 也启动,但即使它们启动失败,当前 unit 仍然可以继续启动。这通常用于非关键性服务。比如 A.service Wants=B.service,如果 B.service 启动失败,A.service 仍然会继续启动。
  • Before=After=: 这些指令控制了 job 执行的顺序。Before= 表示当前 unit 的 job 应该在指定 unit 之前执行,而 After= 表示应该在其之后执行。例如,network.service 通常定义为在 nginx.service 之前启动 (Before=nginx.service),因为 nginx 依赖网络连接。

3.2 Job 传播机制

         当你对某个 unit 发出操作命令时(例如启动或停止),systemd 会自动根据依赖关系传播相关操作。这意味着 systemd 不仅会为目标 unit 创建 job,还会为所有相关的依赖 unit 创建相应的 job。例如,假设 myapp.service 依赖 database.service,当你启动 myapp.service 时,systemd 会首先为 database.service 创建 start job,待其完成后再启动 myapp.service

这种传播机制保证了所有的依赖服务按正确的顺序启动或停止。例如:

  • 当你执行 systemctl stop myapp.service 时,systemd 会自动停止 myapp.service,并传播停止操作到 database.service,如果 database.service 也没有其他依赖它的服务在运行,systemd 会停止它。

4. Job 的执行顺序与并发

      由于依赖关系可能非常复杂,systemd 必须有效地管理 job 的执行顺序。它通过两种主要方式来实现这一点:

4.1 顺序执行

        在 unit 文件中定义的依赖关系(如 Requires=, Wants=, Before=, After=)会影响 job 的执行顺序。systemd 会根据这些依赖关系建立一个有向图,并确保所有 job 按照正确的顺序执行。如果一个 unit 的 start job 依赖另一个 unit 的 start job,那么 systemd 会等待后者完成后再执行前者。

       例如,假设你有一个应用程序 app.service,它依赖于 database.service。systemd 会首先创建 start job for database.service,并在其成功启动后再执行 app.servicestart job。

      start job for database.service --->  start job for app.service

4.2 并发执行

       为了加快系统启动的速度,systemd 支持并发执行 job。如果 unit 之间没有明确的依赖关系,systemd 可以并行启动多个 job。这种并发机制极大地提高了系统的启动效率。systemd 可以动态地调度和执行成百上千个 job,而不会影响系统的稳定性。

       例如,假设你启动 multi-user.target,systemd 会并发执行该 target 所依赖的多个服务的 start job(如 sshd.servicegetty@tty1.service 等),以加速系统进入多用户运行级别。

5. Job 的状态

      每个 job 都有一个状态,systemd 通过这些状态来跟踪 job 的执行情况。常见的 job 状态包括:

  • waiting: job 已创建,但尚未执行,可能因为它依赖的其他 job 尚未完成。
  • running: job 正在执行。
  • done: job 已成功完成。
  • failed: job 执行失败。可能是因为某些依赖未满足,或者系统资源不可用。
  • cancelled: job 被取消。可能是管理员手动取消,或由于某些依赖的 job 失败而自动取消。

      通过 systemctl list-jobs 命令,管理员可以查看当前系统中所有正在执行的 job 及其状态。这个命令会列出每个 job 的 ID、类型、相关 unit 和状态,帮助管理员跟踪系统的任务执行情况。

      各个状态之间的转换如下图所示:

     

6. Job 管理与操作

     systemd 提供了一系列工具来管理 job,包括:

  • systemctl list-jobs: 查看当前正在执行或等待执行的 job 列表。
  • systemctl cancel <job-id>: 取消一个指定的 job。

     管理员可以通过这些命令实时监控和调整 job 的执行,确保系统按照预期的方式运行。

7. 实际应用场景:复杂服务启动过程

      假设你有一个复杂的服务 myapp.service,它依赖于多个其他服务,如数据库 database.service 和缓存 redis.service。其 unit 文件可能如下:

[Unit]
Description=My Application Service
Requires=network.target
After=network.target
Wants=database.service redis.service
 

  当你执行 systemctl start myapp.service 时,systemd 会按照以下步骤创建并调度 job:

  1. 创建 start job for network.target,确保网络已经启动。
  2. 由于 Wants=database.service redis.service,systemd 会并行创建 start job for database.serviceredis.service
  3. 在所有依赖的 job 完成后,systemd 会启动 myapp.service

  这种依赖关系管理确保了服务按正确的顺序启动,并且提高了系统启动的效率。

总结

        在 systemd 中,job 是执行系统任务的核心机制,通常与 unit 直接相关。每个 job 代表对某个 unit 的具体操作,systemd 通过 job 来调度服务的启动、停止、重新加载和重启。unit 文件中的依赖关系直接影响 job 的执行顺序,而 systemd 通过传播机制、并发处理和状态管理来确保系统任务的高效执行。

0条评论
0 / 1000
Eden_Clock
7文章数
0粉丝数
Eden_Clock
7 文章 | 0 粉丝
原创

systemd job介绍

2024-09-23 09:43:04
17
0

     在 systemd 中,job 是负责执行特定任务的一个重要概念,通常与 unit 紧密相关。为了有效地管理 Linux 系统中的服务、设备、挂载点、计时器等资源,systemd 通过创建和调度 job 来实现启动、停止、重启和重新加载等操作。本文将深入探讨 job 的详细机制,尤其是它与 unit 之间的关系,以及如何通过依赖管理、并发控制和状态跟踪来确保系统的高效运行。

1. unit 和 job 的基本概念

       在讨论 job 之前,我们必须理解 unit 的概念。unit 是 systemd 管理的基础对象,表示系统中的某种资源或服务。每个 unit 都有一个配置文件,用于定义其行为和依赖关系。这些配置文件通常位于 /etc/systemd/system//lib/systemd/system/ 目录中。systemd 支持多种不同类型的 unit,常见的包括:

  • Service unit (.service): 用于管理后台服务。比如 nginx.servicesshd.service,它们代表具体的系统服务。
  • Socket unit (.socket): 用于管理套接字激活的服务。某些服务仅在需要时才会启动,通过 socket 单元实现。
  • Target unit (.target): 表示一组 unit 的集合,是一种逻辑同步点。比如 multi-user.target 用于表示多用户运行级别。
  • Mount unit (.mount): 用于管理文件系统挂载点。
  • Timer unit (.timer): 用于定时启动的任务,类似于 cron 任务。

       每个 unit 在执行操作时都会生成对应的 job,这是 systemd 用于调度和管理这些操作的机制。job 是针对某个 unit 进行的具体任务,比如启动、停止或重启服务。

2. job 的类型与 unit 操作

      job 的类型决定了它对 unit 的操作方式。以下是 systemd 支持的常见 job 类型,以及它们与 unit 操作的对应关系:

  • start: 启动一个 unit。如果 unit 已经处于运行状态,此 job 将不会重复启动该 unit。
  • stop: 停止一个 unit,并确保与其依赖相关的其他 unit 也能够正确停止。
  • reload: 重新加载 unit 的配置文件,而不中断当前运行的服务。这通常用于需要在不中断服务的情况下应用新配置。
  • restart: 停止并重新启动一个 unit,相当于依次执行 stopstart 操作。
  • try-restart: 尝试重新启动一个 unit,但仅在 unit 已经运行时执行操作。如果 unit 未启动,则不会做任何事情。
  • reload-or-restart: 首先尝试重新加载配置,如果 reload 操作不支持,则执行 restart 操作。
  • try-reload-or-restart: 如果 unit 正在运行,首先尝试重新加载配置,如果不支持 reload 或者失败,则执行 restart。如果 unit 未启动,什么也不会做。

        这些 job 类型定义了 systemd 如何操作 unit。当你执行诸如 systemctl start nginx.service 这样的命令时,systemd 会为 nginx.service 创建一个 start job,并执行与其关联的操作。

3. job 与 unit 的关系

       job 与 unit 的关系体现在 systemd 通过 job 操作 unit 并根据 unit 文件中定义的依赖关系来处理任务的顺序。每个 unit 文件可以定义自己的依赖项,systemd 会根据这些依赖项自动生成和调度相应的 job。这种关系不仅使得 systemd 能够灵活管理服务,还能确保复杂的系统资源在启动和关闭时保持一致性。

     

      上图展示了 Job 如何与 Unit 的生命周期和操作紧密结合,并通过 Job 管理和调度不同 Unit 的状态转换,解释如下:

    1. Job 和 Unit 的关系

      • 一个 Job 通过启动、停止、重启和重新加载操作作用于不同的 Unit(如 Unit A 和 Unit B)。
      • JobCreated 表示一个 Job 的创建,随后执行不同的操作(启动、停止、重启、重新加载)。
      • UnitAUnitB 分别有自己独立的生命周期状态(ActiveInactive),这些状态会随着 Job 操作的执行而改变。
    2. 依赖关系

      • UnitB 在 UnitA 启动成功后才能启动,表示依赖关系。
    3. Job 操作结束

      • 每个操作执行完毕后,Job 将结束,回到初始状态。

3.1 依赖关系管理

   unit 文件中定义的依赖关系决定了 systemd 如何调度和执行 job。常见的依赖关系定义包括:

  • Requires=: 强依赖关系,表示当前 unit 依赖另一个 unit 的存在。如果依赖的 unit 启动失败,则当前 unit 也会失败。比如,如果 A.service Requires=B.service,则在启动 A.service 时,systemd 会先启动 B.service。如果 B 启动失败,则 A 的启动也会中止。
  • Wants=: 弱依赖关系,表示 systemd 希望关联的 unit 也启动,但即使它们启动失败,当前 unit 仍然可以继续启动。这通常用于非关键性服务。比如 A.service Wants=B.service,如果 B.service 启动失败,A.service 仍然会继续启动。
  • Before=After=: 这些指令控制了 job 执行的顺序。Before= 表示当前 unit 的 job 应该在指定 unit 之前执行,而 After= 表示应该在其之后执行。例如,network.service 通常定义为在 nginx.service 之前启动 (Before=nginx.service),因为 nginx 依赖网络连接。

3.2 Job 传播机制

         当你对某个 unit 发出操作命令时(例如启动或停止),systemd 会自动根据依赖关系传播相关操作。这意味着 systemd 不仅会为目标 unit 创建 job,还会为所有相关的依赖 unit 创建相应的 job。例如,假设 myapp.service 依赖 database.service,当你启动 myapp.service 时,systemd 会首先为 database.service 创建 start job,待其完成后再启动 myapp.service

这种传播机制保证了所有的依赖服务按正确的顺序启动或停止。例如:

  • 当你执行 systemctl stop myapp.service 时,systemd 会自动停止 myapp.service,并传播停止操作到 database.service,如果 database.service 也没有其他依赖它的服务在运行,systemd 会停止它。

4. Job 的执行顺序与并发

      由于依赖关系可能非常复杂,systemd 必须有效地管理 job 的执行顺序。它通过两种主要方式来实现这一点:

4.1 顺序执行

        在 unit 文件中定义的依赖关系(如 Requires=, Wants=, Before=, After=)会影响 job 的执行顺序。systemd 会根据这些依赖关系建立一个有向图,并确保所有 job 按照正确的顺序执行。如果一个 unit 的 start job 依赖另一个 unit 的 start job,那么 systemd 会等待后者完成后再执行前者。

       例如,假设你有一个应用程序 app.service,它依赖于 database.service。systemd 会首先创建 start job for database.service,并在其成功启动后再执行 app.servicestart job。

      start job for database.service --->  start job for app.service

4.2 并发执行

       为了加快系统启动的速度,systemd 支持并发执行 job。如果 unit 之间没有明确的依赖关系,systemd 可以并行启动多个 job。这种并发机制极大地提高了系统的启动效率。systemd 可以动态地调度和执行成百上千个 job,而不会影响系统的稳定性。

       例如,假设你启动 multi-user.target,systemd 会并发执行该 target 所依赖的多个服务的 start job(如 sshd.servicegetty@tty1.service 等),以加速系统进入多用户运行级别。

5. Job 的状态

      每个 job 都有一个状态,systemd 通过这些状态来跟踪 job 的执行情况。常见的 job 状态包括:

  • waiting: job 已创建,但尚未执行,可能因为它依赖的其他 job 尚未完成。
  • running: job 正在执行。
  • done: job 已成功完成。
  • failed: job 执行失败。可能是因为某些依赖未满足,或者系统资源不可用。
  • cancelled: job 被取消。可能是管理员手动取消,或由于某些依赖的 job 失败而自动取消。

      通过 systemctl list-jobs 命令,管理员可以查看当前系统中所有正在执行的 job 及其状态。这个命令会列出每个 job 的 ID、类型、相关 unit 和状态,帮助管理员跟踪系统的任务执行情况。

      各个状态之间的转换如下图所示:

     

6. Job 管理与操作

     systemd 提供了一系列工具来管理 job,包括:

  • systemctl list-jobs: 查看当前正在执行或等待执行的 job 列表。
  • systemctl cancel <job-id>: 取消一个指定的 job。

     管理员可以通过这些命令实时监控和调整 job 的执行,确保系统按照预期的方式运行。

7. 实际应用场景:复杂服务启动过程

      假设你有一个复杂的服务 myapp.service,它依赖于多个其他服务,如数据库 database.service 和缓存 redis.service。其 unit 文件可能如下:

[Unit]
Description=My Application Service
Requires=network.target
After=network.target
Wants=database.service redis.service
 

  当你执行 systemctl start myapp.service 时,systemd 会按照以下步骤创建并调度 job:

  1. 创建 start job for network.target,确保网络已经启动。
  2. 由于 Wants=database.service redis.service,systemd 会并行创建 start job for database.serviceredis.service
  3. 在所有依赖的 job 完成后,systemd 会启动 myapp.service

  这种依赖关系管理确保了服务按正确的顺序启动,并且提高了系统启动的效率。

总结

        在 systemd 中,job 是执行系统任务的核心机制,通常与 unit 直接相关。每个 job 代表对某个 unit 的具体操作,systemd 通过 job 来调度服务的启动、停止、重新加载和重启。unit 文件中的依赖关系直接影响 job 的执行顺序,而 systemd 通过传播机制、并发处理和状态管理来确保系统任务的高效执行。

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0