Linux中使用systemd服务单元定时任务

Linux中使用systemd服务单元定时任务

文章目录

一:Systemd简介

systemd 服务单元文件(通常放在 /etc/systemd/system/ 目录)是用来定义和管理服务的配置文件。它采用 INI 格式,由多节(section)组成,每节里包含若干参数。理解这些参数,有助于你根据实际需求准确配置服务。


systemd 服务单元文件结构

一个标准的 systemd 服务文件主要包含以下几节:

  • [Unit] ------ 描述服务单元的元数据和依赖关系
  • [Service] ------ 定义服务的启动方式、运行命令、重启策略等
  • [Install] ------ 定义服务如何被安装(比如开机启动)

各节详细参数说明及常用配置示例

1. [Unit] 节

用于描述服务单元本身、依赖和启动顺序。

参数 说明及常用值说明
Description 服务描述,简短说明服务作用
After 定义服务启动顺序,指定本服务在指定服务或目标(target)之后启动,如 network.target 表示网络启动后启动
Requires 依赖服务,若指定服务未启动,本服务不会启动
Wants 弱依赖服务,若指定服务启动失败,本服务仍尝试启动
Conflicts 指明和本服务冲突的服务,避免同时运行
Condition... 条件参数,控制服务是否启动,比如 ConditionPathExists= 判断文件是否存在

示例:

ini 复制代码
[Unit]
Description=My per-second task runner
After=network.target
Requires=network.target

2. [Service] 节

定义服务的执行方式,关键参数非常多,常用参数说明如下:

参数 说明 示例
Type 服务类型,常用类型:simple(默认)、forking、oneshot、notify等。 simple: ExecStart 启动的进程即为主进程。 Type=simple
ExecStart 启动服务时执行的命令(必须),完整路径推荐 ExecStart=/usr/local/bin/run_every_second.sh
ExecStop 停止服务时执行的命令(可选) ExecStop=/bin/kill $MAINPID
Restart 服务退出后的重启策略。可选值:no(默认)、on-success、on-failure、always、on-abnormal等。 Restart=always
RestartSec 服务退出后重启延时,单位秒 RestartSec=5
User 指定运行该服务的用户,推荐非root用户 User=someuser
Group 指定运行该服务的用户组 Group=somegroup
WorkingDirectory 服务启动时的工作目录 WorkingDirectory=/home/youruser
Environment 设置环境变量,一行一个,如 KEY=value Environment=JAVA_HOME=/usr/lib/jvm/java-11-openjdk
StandardOutput 标准输出去向,常用journal(日志系统)、file:/path/to/file 或 null StandardOutput=journal
StandardError 标准错误输出去向,同上 StandardError=journal
TimeoutStartSec 启动等待超时时间,单位秒,默认90秒 TimeoutStartSec=30
TimeoutStopSec 停止等待超时时间 TimeoutStopSec=30
KillMode 进程终止方式,常用 control-group(默认,终止整个进程组) KillMode=control-group
ExecReload 重新加载配置命令 ExecReload=/bin/kill -HUP $MAINPID

3. [Install] 节

定义服务的安装行为,主要用于控制服务是否开机启动。

参数 说明 示例
WantedBy 指定安装时绑定的目标(target),常用 multi-user.target 表示多用户模式 WantedBy=multi-user.target
Alias 给服务创建别名 Alias=myservice

一个完整示例

下面是一个典型的 systemd 服务单元示例,服务会启动一个脚本,并且异常退出后自动重启,开机自启:

ini 复制代码
[Unit]
Description=Run my script every second service
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/run_every_second.sh
Restart=always
RestartSec=5
User=youruser
Group=yourgroup
WorkingDirectory=/home/youruser
StandardOutput=journal
StandardError=journal
Environment=MY_ENV_VAR=production
TimeoutStartSec=30
TimeoutStopSec=30
KillMode=control-group

[Install]
WantedBy=multi-user.target

建议和注意事项

  • ExecStart 必须是绝对路径且可执行文件。
  • 尽量给服务指定合适的 User 和 Group,避免使用 root。
  • 通过 Restart 和 RestartSec 设置服务的自动恢复机制,提升稳定性。
  • 使用 journalctl -u 服务名 查看日志,不建议直接写日志文件。
  • TimeoutStartSec 和 TimeoutStopSec 适当调整,避免启动或停止卡死。
  • 如果脚本有依赖网络或数据库,确保 After= 配置正确,或在脚本内部做重试。

二:实现demo

你想用 systemd 实现服务器开机后,每秒调用一次脚本,下面给你一份详细的方案和步骤,确保你的任务能稳定、自动运行。


方案概述

  • 编写一个脚本,内部用死循环和 sleep 1 实现每秒调用。
  • 用 systemd 创建一个服务,启动时运行这个脚本。
  • 设置服务开机自启,自动重启,方便管理和日志查看。

具体步骤

1. 编写脚本

假设你的业务脚本是 /path/to/your_script.sh,你可以写一个"循环调用脚本"的启动脚本,例如:

创建文件 /usr/local/bin/run_every_second.sh

bash 复制代码
#!/bin/bash
while true; do
  /path/to/your_script.sh
  sleep 1
done

给脚本执行权限:

bash 复制代码
chmod +x /usr/local/bin/run_every_second.sh

2. 创建 systemd 服务单元文件

新建文件 /etc/systemd/system/run_every_second.service

ini 复制代码
[Unit]
Description=Run script every second service
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/run_every_second.sh
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
  • Restart=always:如果脚本意外退出,systemd 会自动重启服务。
  • RestartSec=5:重启前等待5秒,避免频繁重启。

3. 让 systemd 识别新服务并启动

bash 复制代码
# 重新加载 systemd 配置
sudo systemctl daemon-reload

# 设置服务开机启动
sudo systemctl enable run_every_second.service

# 立即启动服务
sudo systemctl start run_every_second.service

4. 查看服务状态和日志

bash 复制代码
# 查看服务状态
sudo systemctl status run_every_second.service

# 实时查看日志,方便调试
sudo journalctl -u run_every_second.service -f

补充说明

  • 你的 /path/to/your_script.sh 也要有执行权限,且写好业务代码。
  • 这个方案适合脚本执行时间较短的场景,确保1秒能跑完。如果脚本执行时间超过1秒,可能会出现堆积。
  • 如果业务复杂,建议改用消息队列或专业调度框架
相关推荐
半杯咖啡半行码8 小时前
Linux 驱动开发入门:内核模块编程基础
linux·服务器·网络
智能直播8 小时前
RK3528 V4L2 框架 UVC 接口自动获取 H.264 / MJPEG / YUYV 格式:从内核采集到硬解分发
java·网络·实时音视频·视频编解码·h.264
别动我齐刘海9 小时前
Linux 系统调试学习2
linux·运维·c++·人工智能·学习·机器学习·机器人
龙虾电话9 小时前
语音机器人打断不进去:VAD 双阈值迟滞里一个共用的 bool,和它引发的连锁误判
linux
honsor9 小时前
机房IP化改造首选:以太网温湿度传感器,PoE供电+Modbus TCP一网搞定
linux·运维·服务器
睿智の男孩9 小时前
MIG IP核对DDR3的输出时序分析记录
网络·网络协议·tcp/ip
艾芯微科技9 小时前
高充放电流锂电充放 SoC:ETA9885E10,便携储能、小移动电源 BOM 选型笔记
网络·单片机·嵌入式硬件·集成测试·51单片机
2401_868534789 小时前
数据交换方式
服务器·网络
艾芯微科技9 小时前
钰泰 ETA6973PQ3Y|QFN3×3 2A 同步降压 Buck,I2C 可配置多档输出,动态调压 PMIC
网络·单片机·嵌入式硬件·fpga开发·集成测试·51单片机