systemd實踐 依據情況自動重啟服務

2021-09-20 21:11:31 字數 3363 閱讀 2023

systemd服務異常自動重啟很好用,但有的時候希望某些服務只在特定情況下進行重啟,其他時候不要自動重啟(比如oom,需要人工介入)。

本文拋磚引玉,旨在能夠讓讀者對systemd的重啟機制有一定了解。

[unit]

description=mytest

[service]

type=******

execstart=/root/mytest.sh

restart=always

restartsec=5

startlimitinterval=0

[install]

wantedby=multi-user.target

引數詳解

需求:有個業務,當程式因受到oom而退出的時候,不希望自動重啟(此時需要人工介入排查),其他情況下可以自動重啟

分析:oom就是通過kill -9來殺程序,因此只要找到方法,告訴systemd當該服務遇到kill -9時候不自動重啟即可

查詢man systemd.service發現,systemd的[service]段落裡支援乙個引數,叫做restartpreventexitstatus

該引數從字面上看,意思是當符合某些退出狀態時不要進行重啟。

該引數的值支援exit code和訊號名2種,可寫多個,以空格分隔,例如

restartpreventexitstatus=143 137 sigterm sigkill
表示,當退出情況只要符合以下4種情況中任意一種時候,則不再進行重啟

但實際情況並沒這麼簡單,請繼續往下看

/usr/lib/systemd/system/mytest.service

[unit]

description=mytest

[service]

type=******

execstart=/root/mem

restart=always

restartsec=5

startlimitinterval=0

restartpreventexitstatus=sigkill

[install]

wantedby=multi-user.target

/root/mem.c(不斷消耗記憶體直至發生oom)

#include #include #include #include #include int main ()

memset(p, 0, 1024*1024*100);

printf("malloc %dm memory\n", 100*count++);

usleep(500000);}}

編譯及執行

gcc -o /root/mem /root/mem.c

systemctl daemon-reload

systemctl start mytest

[root@fzxiaomange ~]# systemctl status mytest

● mytest.service - mytest

loaded: loaded (/usr/lib/systemd/system/mytest.service; disabled; vendor preset: disabled)

active: failed (result: signal) since sat 2018-10-20 23:32:24 cst; 45s ago

process: 10555 execstart=/root/mem (code=killed, signal=kill)

main pid: 10555 (code=killed, signal=kill)

oct 20 23:31:55 fzxiaomange.com systemd[1]: started mytest.

oct 20 23:31:55 fzxiaomange.com systemd[1]: starting mytest...

oct 20 23:32:24 fzxiaomange.com systemd[1]: mytest.service: main process exited, code=killed, status=9/kill

oct 20 23:32:24 fzxiaomange.com systemd[1]: unit mytest.service entered failed state.

oct 20 23:32:24 fzxiaomange.com systemd[1]: mytest.service failed.

重點看上面第6行main pid: 10555 (code=killed, signal=kill),這行表示主程序的狀態,常見有2種情況

等待5秒後,並沒有自動重啟,符合預期

此時將restartpreventexitstatus=sigkill改為restartpreventexitstatus=sigterm

執行systemctl restart mytest,再進行一次觀察,等待5秒後,服務自動重啟,符合預期

配置restartpreventexitstatus=後,並沒有完全忽略restart=,而是指當退出情況與restartpreventexitstatus=匹配的時候,才忽略restart=,若沒有匹配,根據restart=該怎麼樣還怎麼樣(具體詳見後面的擴充套件部分)

若systemd啟動的不是乙個簡單程序,而是會派生子程序的情況(比如執行shell指令碼,shell指令碼裡啟動多個程式),那麼當另外開乙個視窗通過kill -訊號測試時,會是什麼情況呢,先貼出測試方法

execstart=/root/mem改為execstart=/root/mytest.sh

/root/mytest.sh內容為

#!/bin/bash

sleep 100000 &

sleep 200000

測試結果

上面有提到restartpreventexitstatus和restart的關係,但沒有資料說明

另外,kill和kill -9的區別,也需要有乙份資料說明

因此做了乙個詳細對比,這裡附上詳細資料

Systemd實踐 依據情況自動重啟服務

systemd服務異常自動重啟很好用,但有的時候希望某些服務只在特定情況下進行重啟,其他時候不要自動重啟 比如oom,需要人工介入 本文拋磚引玉,旨在能夠讓讀者對systemd的重啟機制有一定了解。unit description mytest service type execstart root...

systemd自動重啟引數設定

systemctl是乙個systemd工具,主要負責控制systemd系統和服務管理器。systemd是乙個系統管理守護程序 工具和庫的集合,用於取代system v初始程序。systemd的功能是用於集中管理和配置類unix系統。案例 unit description meross rpc ser...

lodash實踐之依據規則處理物件

在實際開發中,如果你遇到需要對乙個比較複雜的物件刪除某些變數,或者替換某些變數的場景,你會怎麼處理呢?比如 const target c 1,d 你需要對target物件做以下處理 刪除a和b.n引數,並且b.m如果小於2的話進行刪除 替換c值和d.n值為9,並且替換d.m的值為 a c 你是否採用...