Systemd 服务文件(service)

Linux Systemd 服务文件编写指南

1. 概述

在现代 Linux 系统中,systemd 是默认的初始化系统,用于管理系统服务的启动、停止、重启等操作。systemd 服务文件(以 .service 为后缀)是定义服务行为的核心配置文件。本文档将详细介绍如何编写一个 systemd 服务文件,包括文件结构、常用配置项、操作步骤以及注意事项。


2. 服务文件的作用

systemd 服务文件用于定义一个服务的以下行为:

  • 服务的启动和停止方式
  • 开机自启设置
  • 依赖关系
  • 重启策略
  • 日志和错误处理

通过服务文件,可以将自定义的应用程序或脚本作为系统服务运行,方便管理和监控。


3. 服务文件存放路径

服务文件通常存放在以下路径:

  • /etc/systemd/system/:用户自定义的服务文件,推荐使用此路径。
  • /lib/systemd/system/:系统预装的服务文件,不要直接修改此路径下的文件。

注意:用户自定义的服务文件优先级高于系统预装文件。


4. 服务文件的基本结构

一个 systemd 服务文件由以下三个主要部分组成:

  • [Unit]:描述服务的元信息和依赖关系。
  • [Service]:定义服务的具体行为(启动、停止、重启等)。
  • [Install]:定义服务的安装行为(例如是否开机自启)。

以下是一个基本的模板:

[Unit]
Description=服务描述
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/your_program --option
ExecStop=/usr/bin/killall your_program
Restart=always
User=your_user
Group=your_group

[Install]
WantedBy=multi-user.target

5. 各部分的详细说明

5.1 [Unit] 部分

[Unit] 部分用于描述服务的元信息和依赖关系,常用配置项如下:

  • Description:服务的描述信息,用于说明服务的功能。例如:Description=My Python Application
  • After:指定服务在哪些目标(target)或服务启动后启动。例如,After=network.target 表示在网络服务启动后启动。
  • Requires(可选):指定依赖的服务。如果依赖的服务未启动,则本服务也不会启动。例如,Requires=postgresql.service
  • Wants(可选):弱依赖,建议的依赖关系。即使依赖的服务未启动,本服务仍会尝试启动。例如,Wants=redis.service

5.2 [Service] 部分

[Service] 部分用于定义服务的具体行为,常用配置项如下:

  • Type:服务的类型,决定服务的启动行为。常见值包括:
    • simple(默认):服务启动后,主进程就是 ExecStart 指定的进程。
    • forking:服务启动后,主进程会 fork 出子进程,主进程退出。
    • oneshot:服务执行一次后退出,常用于脚本任务。
    • notify:服务启动后会通知 systemd。
    • idle:延迟启动,直到其他服务启动完成。
  • ExecStart:启动服务的命令,必须是绝对路径。可以带参数。例如,ExecStart=/usr/bin/python3 /opt/myapp/main.py
  • ExecStop(可选):停止服务的命令。如果不指定,systemd 会通过信号(如 SIGTERM)终止进程。例如,ExecStop=/usr/bin/killall python3
  • ExecReload(可选):重新加载服务的命令(例如重新加载配置文件)。例如,ExecReload=/bin/kill -HUP $MAINPID
  • Restart(可选):重启策略,常见值包括:
    • always:总是重启。
    • on-failure:仅在失败时重启。
    • no:不重启(默认)。
  • User(可选):指定运行服务的用户。例如,User=appuser
  • Group(可选):指定运行服务的用户组。例如,Group=appgroup
  • WorkingDirectory(可选):指定服务的工作目录。例如,WorkingDirectory=/opt/myapp
  • Environment(可选):设置环境变量。例如,Environment="PATH=/usr/local/bin"
  • EnvironmentFile(可选):从文件中加载环境变量。例如,EnvironmentFile=/etc/myapp/env.conf
  • TimeoutStartSec(可选):启动超时时长,超时后服务会被认为启动失败。例如,TimeoutStartSec=30
  • TimeoutStopSec(可选):停止超时时长,超时后服务会被强制终止。例如,TimeoutStopSec=10

5.3 [Install] 部分

[Install] 部分用于定义服务的安装行为,常用配置项如下:

  • WantedBy:指定服务在哪个目标(target)下启用。例如,WantedBy=multi-user.target 表示在多用户模式(类似于传统的 runlevel 3)下启用服务,相当于开机自启。
  • RequiredBy(可选):指定哪些目标依赖此服务。

6. 编写服务文件的步骤

6.1 创建服务文件

以一个实际的例子为例,假设你有一个 Python 脚本 /opt/myapp/main.py,希望将其作为服务运行,并开机自启。以下是服务文件的内容:

[Unit]
Description=My Python Application
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/python3 /opt/myapp/main.py
ExecStop=/usr/bin/killall python3
Restart=always
User=appuser
Group=appgroup
WorkingDirectory=/opt/myapp
Environment="PYTHONPATH=/opt/myapp/lib"

[Install]
WantedBy=multi-user.target

将上述内容保存为 /etc/systemd/system/myapp.service

6.2 重新加载 systemd 配置

每次修改服务文件后,需要运行以下命令重新加载配置:

sudo systemctl daemon-reload

6.3 启用服务(开机自启)

启用服务,使其在系统启动时自动运行:

sudo systemctl enable myapp.service

6.4 启动服务

手动启动服务:

sudo systemctl start myapp.service

6.5 查看服务状态

检查服务是否正常运行:

sudo systemctl status myapp.service

6.6 停止服务

手动停止服务:

sudo systemctl stop myapp.service

6.7 重启服务

重启服务:

sudo systemctl restart myapp.service

6.8 禁用服务(取消开机自启)

禁用服务,使其不再开机自启:

sudo systemctl disable myapp.service

7. 调试与日志

如果服务启动失败,可以通过以下方式调试:

  • 查看服务状态,获取详细的错误信息:

sudo systemctl status myapp.service
  • 查看服务的日志:

sudo journalctl -u myapp.service
  • 查看从本次开机开始的日志:

sudo journalctl -u myapp.service -b
  • 实时查看日志:

sudo journalctl -u myapp.service -f

8. 注意事项

  1. 路径问题ExecStart 和其他命令必须使用绝对路径,不能使用相对路径或 shell 别名。
  2. 权限问题:确保服务运行的用户和组有足够的权限访问相关文件和目录。
  3. 安全性:避免使用 root 用户运行服务,尽量使用普通用户。
  4. 测试:在生产环境部署前,务必在测试环境中验证服务文件的正确性。
  5. 日志管理:建议在服务中实现日志记录,或者利用 systemd 的日志功能(journalctl)。

9. 更复杂的例子

以下是一个更复杂的例子,展示如何编写一个依赖数据库、支持重新加载配置的服务:

[Unit]
Description=Complex Application Service
After=network.target postgresql.service
Requires=postgresql.service

[Service]
Type=simple
ExecStart=/usr/bin/your_program --config /etc/your_program.conf
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
User=appuser
Group=appgroup
WorkingDirectory=/opt/your_program
EnvironmentFile=/etc/your_program/env.conf
TimeoutStartSec=30
TimeoutStopSec=10

[Install]
WantedBy=multi-user.target

说明:

  • 服务依赖 PostgreSQL(Requires=postgresql.service)。
  • 使用 EnvironmentFile 加载环境变量文件。
  • 支持重新加载配置(ExecReload)。
  • 设置了启动和停止的超时时间。

10. 总结

编写 systemd 服务文件是管理 Linux 服务的重要技能。通过合理配置 [Unit][Service] 和 [Install] 部分,可以灵活地控制服务的行为。建议在编写完成后,仔细测试并查看日志,确保服务按预期运行。

你可能感兴趣的:(linux,服务器)