You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

监控故障并快速重启systemd服务的问题排查与优化

Ubuntu下YouTube不间断直播的systemd重启优化问题

我在Ubuntu上运行24小时不间断的YouTube直播,将ffmpeg命令封装在systemd服务中。多次遇到ffmpeg故障时,systemd的重启速度不足以维持直播在线,需要手动执行daemon-reload并重启服务。于是我写了一个bash脚本检测日志中的流结束错误,但脚本没触发生效,故障仍会发生。现提出两个问题:

  1. 是否有更高效的实现方式?
  2. 若没有,能否指出我的脚本存在什么问题?

我的脚本代码:

#!/bin/bash

RESET=0

while true; do
    # 获取1分钟前的时间
    LAST_1_MINUTE=$(date -d '1 minute ago' '+%b %e %H:%M:%S')
    
    # 检测最近1分钟内的错误日志
    if journalctl --since "$LAST_1_MINUTE" | grep -qi "Error writing trailer"; then
        if [ $RESET -lt 1 ]; then
            # 触发错误后的操作
            sudo systemctl daemon-reload && \
            echo "Restarting master.service by monitor.sh script at $(date)" >> /var/log/monitor.log && \
            sudo systemctl restart master.service
            RESET=2
        fi
    else
        RESET=$((RESET - 1))
    fi

    # 20秒后再次检测
    sleep 20
done

一、更高效的实现方式

完全不需要额外监控脚本,直接优化systemd服务配置就能解决问题,这是最原生且可靠的方案:

  • 调整服务重启策略:在master.service配置文件的[Service]段添加/修改以下参数:
    [Service]
    Restart=on-failure
    RestartSec=5  # 故障后5秒自动重启,可按需调整间隔
    StartLimitIntervalSec=300
    StartLimitBurst=10  # 限制5分钟内最多重启10次,避免无限循环
    
    Restart=on-failure会让systemd在进程异常退出(非0退出码)时自动重启,正常重启服务不需要执行systemctl daemon-reload,只有修改服务配置文件后才需要该命令。
  • 精准追踪进程状态:systemd直接监控服务主进程,比轮询日志更及时、准确,不会出现漏检或延迟问题。
  • 自定义错误码处理:如果ffmpeg退出时返回特定错误码,可通过RestartPreventExitStatus排除无需重启的情况,或RestartForceExitStatus强制重启特定错误场景。

二、你的脚本存在的问题

  1. 日志时间格式不匹配:
    脚本用%b %e %H:%M:%S生成的时间中,%e会输出带前导空格的日期(比如5号是 5),和journalctl的日志时间格式存在匹配误差,导致无法正确筛选目标时间段的日志。建议改用ISO-8601标准格式:LAST_1_MINUTE=$(date -d '1 minute ago' --iso-8601=seconds),确保时间参数能被journalctl正确识别。

  2. 未过滤目标服务日志:
    journalctl --since "$LAST_1_MINUTE"会返回系统所有服务的日志,其他服务日志中若出现Error writing trailer字符串,会导致误触发。应加上-u master.service参数,只过滤目标服务的日志:journalctl -u master.service --since "$LAST_1_MINUTE"。

  3. RESET变量逻辑缺陷:
    检测到错误后设置RESET=2,后续若持续检测到错误,RESET会一直保持2,无法触发下一次重启;而如果错误反复出现,脚本可能因RESET未降到1以下而无法及时响应。

  4. 权限问题导致执行卡住:
    脚本中使用sudo,若运行脚本的用户没有免密sudo权限,执行时会弹出密码输入提示,导致重启操作无法自动完成。建议给该用户配置免密sudo(编辑/etc/sudoers添加username ALL=(ALL) NOPASSWD: /bin/systemctl),或直接以root身份运行脚本。

  5. 检测窗口与循环间隔不匹配:
    每20秒检测一次过去1分钟的日志,会导致同一个错误被重复检测到,而RESET的限制逻辑可能让脚本在故障持续时无法及时重启服务,错过恢复时机。


内容的提问来源于stack exchange,提问作者mzrt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 04:20:28