跳转到内容
搜索 RunEntLinux 文档

仅搜索 RunEntLinux 通用文档,各发行版文档使用各自的搜索入口。

    浏览当前文档目录

    管理服务单元

    systemd 的 service 单元文件定义了如何启动、停止和管理一个后台服务。掌握单元文件的结构和常用配置项,你就可以为任何应用程序创建可靠的系统服务。

    systemd 按优先级从高到低搜索以下目录中的单元文件:

    路径用途优先级
    /etc/systemd/system/管理员自定义的单元文件最高
    /run/systemd/system/运行时动态生成的单元文件中
    /usr/lib/systemd/system/软件包安装的单元文件最低

    自定义服务应始终放在 /etc/systemd/system/ 目录中。

    一个标准的 service 单元文件由三个主要段落(Section)组成:

    单元文件基本结构
    [Unit]
    # 描述和依赖关系
    [Service]
    # 服务运行参数
    [Install]
    # 安装(启用)行为

    [Unit] 段提供单元的描述信息和依赖关系,是所有单元类型通用的配置段。

    [Unit] 段常用配置项
    [Unit]
    Description=我的应用服务
    Documentation=https://example.com/docs
    After=network.target
    Wants=network-online.target
    Requires=postgresql.service

    常用指令说明:

    指令说明
    Description=服务的简短描述,会显示在 systemctl status 输出中
    Documentation=文档 URL,供参考使用
    After=指定启动顺序,本服务在指定单元之后启动
    Before=指定启动顺序,本服务在指定单元之前启动
    Requires=强依赖,指定单元未启动则本服务也无法启动
    Wants=弱依赖,指定单元未启动不影响本服务
    BindsTo=类似 Requires,但指定单元停止时本服务也会被停止

    [Service] 段是 service 单元文件的核心,定义服务的启动方式、运行参数和重启策略。

    [Service] 段常用配置项
    [Service]
    Type=simple
    ExecStart=/usr/bin/myapp --config /etc/myapp/config.yml
    ExecReload=/bin/kill -HUP $MAINPID
    ExecStop=/bin/kill -SIGTERM $MAINPID
    Restart=on-failure
    RestartSec=5
    User=myapp
    Group=myapp
    WorkingDirectory=/opt/myapp
    Environment=NODE_ENV=production
    EnvironmentFile=/etc/myapp/env

    Type= 指定服务的启动方式,直接影响 systemd 如何判断服务是否启动成功:

    类型说明适用场景
    simple(默认)ExecStart 进程即为主进程大多数前台运行的应用
    forking进程 fork 后父进程退出,子进程成为主进程传统守护进程(如 Apache)
    oneshot进程执行完毕即退出,可配合 RemainAfterExit初始化脚本、一次性任务
    notify服务通过 sd_notify() 主动通知 systemd 已就绪支持 sd_notify 的应用
    dbus服务获取 D-Bus 名称后视为启动完成D-Bus 服务
    idle类似 simple,但等到其他任务完成后再启动控制台输出相关服务
    值说明
    no(默认)不自动重启
    on-success仅在正常退出(退出码 0)时重启
    on-failure仅在非正常退出时重启(推荐用于守护进程)
    on-abnormal在信号终止或超时时重启
    on-abort在收到未捕获的信号时重启
    always无论何种原因退出都重启

    配合 RestartSec= 设置重启前的等待秒数,避免服务故障时频繁重启。

    ExecStart= 定义服务启动时执行的命令。注意必须使用绝对路径:

    正确写法 - 使用绝对路径
    ExecStart=/usr/bin/python3 /opt/myapp/server.py

    对于 Type=oneshot 的服务,可以指定多个 ExecStart= 行,它们会按顺序依次执行。

    [Install] 段定义了执行 systemctl enable 时的行为:

    [Install] 段常用配置项
    [Install]
    WantedBy=multi-user.target
    Alias=myapp.service
    指令说明
    WantedBy=指定在哪个 target 下启用本服务(最常用 multi-user.target)
    RequiredBy=类似 WantedBy,但建立强依赖关系
    Alias=为服务创建别名

    下面以一个 Go 语言编写的 Web 应用为例,演示如何创建完整的 systemd 服务。

    创建自定义服务单元文件
    sudo vim /etc/systemd/system/mywebapp.service

    写入以下内容:

    /etc/systemd/system/mywebapp.service
    [Unit]
    Description=My Go Web Application
    Documentation=https://example.com/mywebapp
    After=network.target
    Wants=network-online.target
    [Service]
    Type=simple
    User=webadmin
    Group=webadmin
    WorkingDirectory=/opt/mywebapp
    ExecStart=/opt/mywebapp/mywebapp
    ExecReload=/bin/kill -HUP $MAINPID
    Restart=on-failure
    RestartSec=10
    StandardOutput=journal
    StandardError=journal
    SyslogIdentifier=mywebapp
    # 安全加固
    NoNewPrivileges=true
    ProtectSystem=full
    ProtectHome=true
    PrivateTmp=true
    # 资源限制:MemoryMax 按实测常驻内存设定(示例 1G,不是最低要求)
    LimitNOFILE=65536
    MemoryMax=1G
    [Install]
    WantedBy=multi-user.target

    每次新增或修改单元文件后,必须通知 systemd 重新加载配置:

    重新加载 systemd 守护进程配置
    sudo systemctl daemon-reload
    启用开机自启并立即启动服务
    sudo systemctl enable --now mywebapp.service
    查看服务运行状态
    sudo systemctl status mywebapp.service
    查看服务日志
    sudo journalctl -u mywebapp.service -f

    如果需要修改软件包安装的服务配置,不应直接编辑 /usr/lib/systemd/system/ 下的文件(系统更新时可能被覆盖)。应使用 drop-in 覆盖机制:

    使用 systemctl edit 创建覆盖配置
    sudo systemctl edit nginx.service

    这会打开编辑器,创建文件 /etc/systemd/system/nginx.service.d/override.conf。例如增加内存限制:

    override.conf 示例 - 添加内存限制
    [Service]
    MemoryMax=1G

    保存退出后自动执行 daemon-reload。

    如果需要查看完整的合并后配置(原始配置 + 覆盖配置):

    查看合并后的完整单元配置
    systemctl cat nginx.service

    有些任务只需执行一次,例如系统初始化脚本:

    /etc/systemd/system/init-database.service
    [Unit]
    Description=Initialize Application Database
    After=postgresql.service
    Requires=postgresql.service
    [Service]
    Type=oneshot
    ExecStart=/opt/myapp/init-db.sh
    RemainAfterExit=yes
    User=postgres
    [Install]
    WantedBy=multi-user.target

    RemainAfterExit=yes 表示进程退出后,服务状态仍显示为 active,避免依赖它的其他服务受到影响。

    当服务无法正常启动时,按以下步骤排查:

    查看服务详细状态和最近日志
    sudo systemctl status mywebapp.service -l
    查看服务完整日志(不截断长行)
    sudo journalctl -u mywebapp.service --no-pager -n 50
    验证单元文件语法是否正确
    sudo systemd-analyze verify /etc/systemd/system/mywebapp.service
    查看服务的所有属性
    systemctl show mywebapp.service