AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 729369
Accepted
Arkaik
Arkaik
Asked: 2022-12-23 12:13:03 +0800 CST2022-12-23 12:13:03 +0800 CST 2022-12-23 12:13:03 +0800 CST

仅在达到突发限制后才触发 Service OnFailure

  • 772

我正在使用 systemd 单元文件来控制在服务器上运行的 python 进程(使用 systemd v247)。

此进程必须在退出后 60 秒重新启动,无论是失败还是成功,除非它在 ​​600 秒内失败 5 次。

该单元文件链接另一个服务,以便通过电子邮件通知故障。

/etc/systemd/system/python-test.service

[Unit]
After=network.target
OnFailure=mailer@%n.service

[Service]
Type=simple

ExecStart=/home/debian/tmp.py

# Any exit status different than 0 is considered as an error
SuccessExitStatus=0

StandardOutput=append:/var/log/python-test.log
StandardError=append:/var/log/python-test.log

# Always restart service 60sec after exit
Restart=always
RestartSec=60

# Stop restarting service after 5 consecutive fail in 600sec interval
StartLimitInterval=600
StartLimitBurst=5

[Install]
WantedBy=multi-user.target

/etc/systemd/system/[email protected]

[Unit]
After=network.target

[Service]
Type=oneshot

ExecStart=/home/debian/mailer.py --to "[email protected]" --subject "Systemd service %I failed" --message "A systemd service failed %I on %H"

[Install]
WantedBy=multi-user.target

在基本测试期间,触发OnFailure工作得很好。但是,当我将以下部分添加到单元文件中时,OnFailure仅在连续 5 次失败时触发。

StartLimitInterval=600
StartLimitBurst=5

这不是我想要的行为,因为我希望每次进程失败时都能收到通知,即使尚未达到突发限制。


检查进程状态时,未达到突发限制时输出不同

● python-test.service
     Loaded: loaded (/etc/systemd/system/python-test.service; disabled; vendor preset: enabled)
     Active: activating (auto-restart) (Result: exit-code) since Thu 2022-12-22 19:51:23 UTC; 2s ago
    Process: 1421600 ExecStart=/home/debian/tmp.py (code=exited, status=1/FAILURE)
   Main PID: 1421600 (code=exited, status=1/FAILURE)
        CPU: 31ms

Dec 22 19:51:23 test-vps systemd[1]: python-test.service: Failed with result 'exit-code'.

比当它是

● python-test.service
     Loaded: loaded (/etc/systemd/system/python-test.service; disabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Thu 2022-12-22 19:52:02 UTC; 24s ago
    Process: 1421609 ExecStart=/home/debian/tmp.py (code=exited, status=1/FAILURE)
   Main PID: 1421609 (code=exited, status=1/FAILURE)
        CPU: 31ms

Dec 22 19:51:56 test-vps systemd[1]: python-test.service: Failed with result 'exit-code'.
Dec 22 19:52:02 test-vps systemd[1]: python-test.service: Scheduled restart job, restart counter is at 5.
Dec 22 19:52:02 test-vps systemd[1]: Stopped python-test.service.
Dec 22 19:52:02 test-vps systemd[1]: python-test.service: Start request repeated too quickly.
Dec 22 19:52:02 test-vps systemd[1]: python-test.service: Failed with result 'exit-code'.
Dec 22 19:52:02 test-vps systemd[1]: Failed to start python-test.service.
Dec 22 19:52:02 test-vps systemd[1]: python-test.service: Triggering OnFailure= dependencies.

我找不到任何解释如何OnFailure在单元文件中修改触发的内容。

有没有办法在每次进程失败时通知邮件并仍然保持突发限制?

linux
  • 1 1 个回答
  • 56 Views

1 个回答

  • Voted
  1. Best Answer
    Edgar Magallon
    2022-12-24T19:23:37+08:002022-12-24T19:23:37+08:00

    为了根据需要使用系统服务,您应该做几件事(更改在/etc/systemd/system/python-test.service上)。

    1. 改为Restart=always_Restart=on-failure
    2. 价值观StartLimitInterval=600,StartLimitBurst=5似乎还得到支持。但是你应该把它们放在[Unit]. 如果您放置StartLimitInterval在[Unit]您可以将其重命名为StartLimitIntervalSec(改为man systemd.unit使用StartLimitIntervalSec)。
    3. 添加RemainAfterExit=no到[Service]部分。
    4. 在部分中添加此行[Service]:TimeoutStopSec=infinity
    5. 使用脚本中的环境变量EXIT_STATUS来确定脚本是否成功退出。
    6. 改为。OnFailure=mailer@%n.service_ OnFailure=mailer@%N.service两者的区别是using%N会去掉后缀。
    7. 安装并启动服务atd( sudo systemctl start atd.service) 以便能够使用at命令。或者,如果您不想使用,at则可以编写另一个 systemd 服务来重新启动该服务。(在这个例子中,我使用了relaunch.service)
    8. sleep在和上使用相同的值RestartSec。在你的情况下,因为RestartSec在60这一行中 sleep60也必须有:
     echo "sleep 60; sudo systemctl start ${1}.service" | at now
    
    1. 使用ExecStart和ExecStopPost=获取主进程的ExitStatus/home/debian/tmp.py:。不要使用ExecStop, 来自man systemd.service:

    执行停止=

    请注意,ExecStop= 中指定的命令仅在服务首先成功启动时执行。如果服务根本没有启动,或者启动失败,则不会调用它们,例如,因为在 ExecStart=、ExecStartPre= 或 ExecStartPost= 中指定的任何命令失败(并且没有前缀“-” ,见上文)或超时。当服务未能正确启动并再次关闭时,使用 ExecStopPost= 调用命令。


    服务/etc/systemd/system/python-test.service应该是:

    [Unit]
    After=network.target
    OnFailure=mailer@%N.service
    
    StartLimitBurst=5
    StartLimitIntervalSec=600
     
    [Service]  
    Type=simple 
    TimeoutStopSec=infinity
    ExecStart=/home/debian/tmp.py
    ExecStopPost=/bin/bash -c 'echo The Service  has exited with values: $$EXIT_STATUS,$$SERVICE_RESULT,$$EXIT_CODE'
    ExecStopPost=/home/debian/bin/checkSuccess "%N"
    # Any exit status different than 0 is considered as an error
    SuccessExitStatus=0
    StandardOutput=append:/tmp/python-out-test.log
    StandardError=append:/tmp/python-err-test.log
    # Always restart service 60sec after exit
    Restart=on-failure
    RestartSec=60
    RemainAfterExit=no
    
    [Install]
    WantedBy=multi-user.target
    

    /home/debian/bin/checkSuccess应该有这个:

    解决方案 1:使用at命令:

    #!/bin/bash
    
    if [ "$EXIT_STATUS" -eq 0 ]
    then
       echo "sleep 60; sudo systemctl start ${1}.service" | at now
       exit 0
    else
       systemctl start "mailer@${1}.service"
       exit 0
    fi
    

    解决方案 2:使用另一个 systemd 服务:

    #!/bin/bash
    
    if [ "$EXIT_STATUS" -eq 0 ]
    then
       systemctl start relaunch.service
    else
       systemctl start "mailer@${1}.service"
    fi
    exit 0
    

    relaunch.service应该有:

    [Unit]
    Description=Relaunch Python Test Service
    
    [Service]
    Type=simple
    RemainAfterExit=no 
    ExecStart=/bin/bash -c 'echo Delay; sleep 10 ; systemctl start python-test.service'
    

    systemd 服务设置的"$EXIT_STATUS"变量由 的退出状态决定/home/debian/tmp.py。

    ${1}代表单元的名称: 并python-test传递给行中的脚本/home/debian/bin/checkSuccess "%N"。


    笔记:

    1. 'echo The Service %n has exited with values: $$EXIT_STATUS,$$SERVICE_RESULT,$$EXIT_CODE' 您可以使用以下方式实时检查日志:
    tail -f /tmp/python-out-test.log
    
    1. relaunch.service如果你想停止你的主要服务时使用解决方案 2 ( with ),你应该运行:
    sudo systemctl stop relaunch.service
    #Might not be necessary but you stop python service too:
    # sudo systemctl stop python-test.service
    
    • 1

相关问题

  • 有没有办法让 ls 只显示某些目录的隐藏文件?

  • 使用键盘快捷键启动/停止 systemd 服务 [关闭]

  • 需要一些系统调用

  • astyle 不会更改源文件格式

  • 通过标签将根文件系统传递给linux内核

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve