当前位置: 首页 > news >正文

【Linux】systemd 服务管理详解

目录

引言

一、systemd简介

二、systemd 服务单元

2.1 服务单元文件(.service 文件)

2.1.1 文件位置

2.1.2 文件命名约定

2.2 服务单元文件结构

核心部分与常用指令

三、常用 systemctl 命令

3.1 服务状态与控制

3.2 服务启用与禁用(开机自启)

3.3 查看服务列表与日志

3.4 其他重要命令

四、自定义 systemd 服务示例

4.1. 创建服务用户(推荐)

4.2 编写服务文件

4.3 启用并启动服务

五、注意事项


引言

        在现代 Linux 系统中,systemd 已经成为绝大多数主流发行版(如 Ubuntu, CentOS/RHEL, Debian, Fedora 等)默认的系统和服务管理器。它取代了传统的 SysVinit 和 Upstart,带来了更快的启动速度、更强大的依赖管理、更完善的日志记录和更灵活的服务控制能力。

一、systemd简介

systemd 是一个 Linux 系统的系统和服务管理器。它作为 PID 1 进程启动,是整个用户空间进程的“祖先进程”。它的主要职责包括:

  • 系统初始化: 并行启动系统服务,显著加快启动速度。
  • 服务管理: 启动、停止、重启、监控和管理各种系统服务(如 Web 服务器、数据库、自定义应用)。
  • 依赖管理: 自动处理服务之间的依赖关系,确保服务按正确顺序启动。
  • 资源管理: 集成 cgroups,更好地管理和隔离服务资源。
  • 日志管理: 提供 journald 服务,集中管理结构化日志。
  • 设备管理: 与 udev 集成,管理硬件设备的热插拔。
  • 定时任务: 提供 timer 单元,作为 cron 的现代化替代。

本文只聚焦于服务管理

二、systemd 服务单元

2.1 服务单元文件(.service 文件)

每个由 systemd 管理的服务都由一个配置文件定义,通常以 .service 结尾。

这些文件定义了服务如何启动、停止、重启以及其运行环境。

2.1.1 文件位置
  • 系统服务:
    • /usr/lib/systemd/system/: 由软件包安装的默认服务文件。不建议直接修改,因为更新软件包时可能被覆盖。
    • /etc/systemd/system/: 系统管理员创建或覆盖默认配置的首选位置。优先级高于 /usr/lib/systemd/system/
  • 用户服务:
    • ~/.config/systemd/user/ 或 /usr/lib/systemd/user/ (用于用户级别的服务)。
2.1.2 文件命名约定

服务文件通常命名为 <service-name>.service

例如:

  • nginx.service
  • mysql.service
  • myapp.service

在使用 systemctl 命令时,.service 后缀通常可以省略。

2.2 服务单元文件结构

一个 .service 文件是 INI 格式的文本文件,包含多个 [Section],每个部分包含键值对。

核心部分与常用指令
[Unit]
# 通用元数据和依赖关系
Description=My Custom Application Service
Documentation=https://example.com/myapp/docs
After=network.target syslog.target
# Before=other-service.service
# Requires=network.target mysql.service
# Wants=network.target
# Conflicts=old-app.service
  • Description=: 服务的描述。
  • Documentation=: 指向服务文档的链接。
  • After=: 指定本服务在哪些目标(target)或其他服务之后启动。不表示依赖,仅控制顺序。常用 network.target 表示网络就绪。
  • Before=: 指定本服务在哪些目标或其他服务之前启动。
  • Requires=: 强依赖。如果列出的服务启动失败,本服务也会启动失败。
  • Wants=: 弱依赖。推荐启动列出的服务,但即使它们失败,本服务仍会尝试启动。比 Requires= 更常用。
  • Conflicts=: 冲突关系。如果列出的服务正在运行,本服务不能启动,反之亦然。
    [Service]
    # 服务的具体执行和行为
    Type=simple
    ExecStart=/usr/bin/myapp --config /etc/myapp/config.yaml
    # ExecStartPre=/bin/sleep 10 # 启动前执行的命令
    # ExecStartPost=/bin/echo "Service started"
    # ExecStop=/usr/bin/myapp --stop
    # ExecReload=/bin/kill -HUP $MAINPID
    Restart=on-failure
    RestartSec=5
    TimeoutSec=30
    User=myappuser
    Group=myappgroup
    WorkingDirectory=/var/lib/myapp
    # Environment=ENV_VAR=value
    # EnvironmentFile=/etc/myapp/environment
    StandardOutput=journal
    StandardError=journal
    SyslogIdentifier=myapp
    # KillMode=process
    # KillSignal=SIGTERM
    # SuccessExitStatus=0 143
    • Type=最关键的指令之一,定义了服务的启动类型:
      • simple (默认): systemd 认为 ExecStart 启动的进程就是主进程。适用于前台运行的守护进程。
      • forking: 适用于传统的守护进程(daemon),它们会 fork 并让父进程退出。systemd 会跟踪 fork 出的子进程。通常需要 PIDFile= 指定 PID 文件路径。
      • oneshot: 一次性任务。systemd 会等待命令执行完毕才继续。常用于脚本或初始化任务。配合 RemainAfterExit=yes 使用,表示服务在命令执行后仍被视为“激活”状态。
      • dbus: 服务在获取一个 D-Bus 名称后才被视为启动成功。
      • notify: 服务通过 sd_notify() 调用通知 systemd 启动完成。需要服务本身支持。
      • idle: 类似 simple,但执行延迟到所有活动完成。
    • ExecStart=必需。指定启动服务时执行的命令及其参数。只能有一个 ExecStart= 指令(除非 Type=oneshot)。
    • ExecStartPre= / ExecStartPost=: 在 ExecStart 之前/之后执行的命令。
    • ExecStop=: 指定停止服务时执行的命令。如果未设置,systemd 会发送 SIGTERM 信号。
    • ExecReload=: 指定重新加载服务配置时执行的命令(如 systemctl reload)。
    • Restart=: 定义服务进程退出后是否重启:
      • no (默认): 不重启。
      • on-success: 仅在正常退出(退出码 0)或被 systemd 重启时重启。
      • on-failure: 在非正常退出(非零退出码)、被信号终止(非 SIGKILL)、超时或被看门狗终止时重启。最常用
      • on-abnormal: 在被信号终止、超时或看门狗终止时重启。
      • on-abort: 在被信号终止或看门狗终止时重启。
      • always: 无论退出原因如何都重启。
    • RestartSec=: 重启前等待的秒数(默认 100ms)。
    • TimeoutSec=: 启动、停止、重启操作的超时时间(秒)。可被 TimeoutStartSec=TimeoutStopSec= 覆盖。
    • User= / Group=: 以指定的用户和组身份运行服务进程。强烈推荐为服务创建专用用户。
    • WorkingDirectory=: 设置服务进程的工作目录。
    • Environment=: 设置环境变量。可多次使用。
    • EnvironmentFile=: 从文件中读取环境变量(每行 KEY=value)。
    • StandardOutput= / StandardError=: 定义标准输出和错误的处理方式。journal (默认) 发送到 journaldsyslog 发送到 syslog;null 丢弃;tty 输出到控制台。
    • SyslogIdentifier=: 在日志中使用的标识符(替代进程名)。
    • KillMode=: 定义停止服务时如何发送信号:
      • control-group (默认): 向服务的 cgroup 中所有进程发送信号。
      • process: 仅向主进程(ExecStart 启动的)发送信号。
      • mixed: 先发送 SIGTERM,等待超时后发送 SIGKILL
      • none: 不发送信号。
    • KillSignal=: 停止服务时发送的信号(默认 SIGTERM)。
    • SuccessExitStatus=: 指定哪些退出码被视为“成功”(不影响 Restart=on-failure 的判断)。
      [Install]
      # 定义服务如何被启用(enable)
      WantedBy=multi-user.target
      # Also=other-service.service
      # RequiredBy=other-service.service
      • WantedBy=最常用。当启用(systemctl enable)此服务时,会在指定的 target 的 .wants/ 目录下创建一个指向此服务文件的符号链接。例如 WantedBy=multi-user.target 表示服务在多用户模式下被“需要”。
      • RequiredBy=: 类似 WantedBy=,但创建的是 .requires/ 链接,表示强依赖。
      • Also=: 当此服务被启用/禁用时,同时启用/禁用列出的服务。

      三、常用 systemctl 命令

      systemctl 是管理 systemd 服务的主要命令行工具。

      3.1 服务状态与控制

      命令说明
      systemctl status <service>查看服务的详细状态(运行状态、PID、日志片段等)。
      systemctl start <service>启动服务。
      systemctl stop <service>停止服务。
      systemctl restart <service>重启服务。
      systemctl reload <service>重新加载服务配置(不中断服务)。
      systemctl try-restart <service>如果服务正在运行,则重启它。
      systemctl kill <service>向服务进程发送信号(可指定信号)。
      systemctl is-active <service>检查服务是否处于 active (running) 状态。
      systemctl is-enabled <service>检查服务是否已启用(开机自启)。

      3.2 服务启用与禁用(开机自启)

      命令说明
      systemctl enable <service>启用服务,创建符号链接,使其在下次启动时自动运行。
      systemctl disable <service>禁用服务,删除符号链接,下次启动时不再自动运行。
      systemctl reenable <service>先禁用再启用服务,用于刷新链接。
      systemctl preset <service>根据预设规则(/usr/lib/systemd/system-preset/)启用/禁用服务。

      3.3 查看服务列表与日志

      命令说明
      systemctl list-units --type=service列出所有已加载的服务及其状态。
      systemctl list-units --type=service --state=active仅列出正在运行的服务。
      systemctl list-unit-files --type=service列出所有服务单元文件及其启用状态(enableddisabledstaticmasked)。
      journalctl -u <service>查看指定服务的完整日志。
      journalctl -u <service> -f实时跟踪(-f)指定服务的日志。
      journalctl -u <service> --since "2023-10-27 10:00"查看指定时间范围内的日志。
      journalctl -u <service> -p err查看指定服务的错误级别日志。

      3.4 其他重要命令

      命令说明
      systemctl daemon-reload重要! 当修改了服务文件后,必须运行此命令重新加载 systemd 配置。否则 systemctl 命令可能找不到新服务或使用旧配置。
      systemctl cat <service>显示服务单元文件的完整内容(包括片段)。
      systemctl show <service>显示服务的详细属性(所有配置项的当前值)。
      systemctl list-dependencies <service>列出服务的依赖关系。

      四、自定义 systemd 服务示例

      创建一个名为 myapp 的 Python 脚本,位于 /opt/myapp/myapp.py,希望它作为服务运行。

      4.1. 创建服务用户(推荐)

      sudo useradd -r -s /bin/false myappuser

      4.2 编写服务文件

      创建文件 /etc/systemd/system/myapp.service

      [Unit]
      Description=My Awesome Python Application
      After=network.target
      Wants=network.target[Service]
      Type=simple
      User=myappuser
      Group=myappuser
      WorkingDirectory=/opt/myapp
      ExecStart=/usr/bin/python3 /opt/myapp/myapp.py
      Restart=on-failure
      RestartSec=5
      StandardOutput=journal
      StandardError=journal
      SyslogIdentifier=myapp[Install]
      WantedBy=multi-user.target

      4.3 启用并启动服务

      # 重新加载 systemd 配置以识别新服务
      sudo systemctl daemon-reload# 启用服务(开机自启)
      sudo systemctl enable myapp.service# 启动服务
      sudo systemctl start myapp.service# 检查状态
      sudo systemctl status myapp.service# 查看日志
      sudo journalctl -u myapp.service -f

      五、注意事项

      1. 使用专用用户: 为每个服务创建专用的系统用户,避免使用 root 运行服务,提升安全性。
      2. 明确 Type 正确设置 Type 对于 systemd 正确监控服务至关重要。对于大多数现代应用,simple 是合适的。
      3. 合理设置 Restart on-failure 通常是生产环境的最佳选择,防止服务因崩溃而长时间离线,同时避免因配置错误导致无限重启循环。
      4. 日志重定向: 将 StandardOutput 和 StandardError 设置为 journal,利用 journald 的强大日志功能。
      5. 修改后 daemon-reload 切记在修改任何 .service 文件后,必须运行 sudo systemctl daemon-reload
      6. 测试配置: 使用 systemctl cat <service>  systemctl show <service> 验证配置是否被正确加载。
      7. 避免直接修改 /usr/lib/ 下的文件: 将自定义或覆盖配置放在 /etc/systemd/system/ 目录下。
      8. 处理依赖: 清晰地定义 After 和 Wants/Requires,确保服务在依赖项(如网络、数据库)就绪后才启动。
      9. 监控与告警: 结合 systemctl is-active 和日志监控工具,建立服务健康检查和告警机制。
      http://www.dtcms.com/a/524596.html

      相关文章:

    • Python哪个Excel库最好用?
    • 瓦力机器人-编码电机控制(基于树莓派5)
    • dw做网站怎么上线大良用户网站建设
    • Node.js 进阶:掌握高性能服务器开发的核心技术
    • Elasticsearch 的 SQL 与 DSL 转换
    • 快速做网站的软件腾讯企业邮箱电脑版登录入口
    • API测试工具进化:从Postman到Apipost的全局参数管理革命
    • 数据结构——排序的超级详解(Java版)
    • C# 加密解密字符方法Cryptography
    • 教做详情页的网站关键词优化公司电话
    • 中企动力科技股份有限公司网站梵克雅宝官网官方网
    • 自己电脑做电影网站中国建设教育协会培训中心
    • 第三章、React项目国际化介绍(`react-i18next`)
    • RHCA - DO374 | Day03:通过自动化控制器运行剧本
    • 深圳微商城网站建设温州 网站开发
    • 何谓RSS
    • 【SpringCloud】Eureka
    • 网站后台尺寸一般做多大的如何把优酷视频放到网站上
    • 帝国建站模板淘宝网络营销案例分析
    • 企业选择内容+人工智能供应商应该考虑什么?​
    • CI/CD(一)—— 从零搭建 GitLab 全流程(Docker 部署 + 实战指南)
    • 【Android】 Gradle 下载后本地使用方式(macOS / Windows通用)
    • 华为od面经-23届-Java面经
    • Kubernetes LoadBalancer系列|MetalLB介绍与配置
    • 网站制作及管理教程模板网站建设公司 东莞
    • 网站内容品质网站开发的相关语言有哪些
    • 淘宝自己网站怎么建设怎么制作网站编辑页面
    • SQLMap 终极渗透手册(2025全功能版)
    • 微硕WSP4884双N沟MOSFET:汽车智能座舱PMIC“微型稳压核”
    • 【Redis 全解析】高性能内存数据库的原理、实践与优化