1.最简单的自动重启范例

[Unit]
Description=mytest [Service]
Type=simple
ExecStart=/root/mytest.sh
Restart=always
RestartSec=
StartLimitInterval= [Install]
WantedBy=multi-user.target

重点参数详解

  • Restart=always: 只要不是通过systemctl stop来停止服务,任何情况下都必须要重启服务,默认值为no

  • RestartSec=5: 重启间隔,比如某次异常后,等待5(s)再进行启动,默认值0.1(s)

  • StartLimitInterval: 无限次重启,默认是10秒内如果重启超过5次则不再重启,设置为0表示不限次数重启

2.案例需求

需求:有个业务,当程序因受到OOM而退出的时候,不希望自动重启(此时需要人工介入排查),其他情况下可以自动重启

分析:OOM就是通过kill -9来杀进程,因此只要找到方法,告诉systemd当该服务遇到kill -9时候不自动重启即可

3.RestartPreventExitStatus参数

查询man systemd.service发现,systemd的[Service]段落里支持一个参数,叫做RestartPreventExitStatus

该参数从字面上看,意思是当符合某些退出状态时不要进行重启。

该参数的值支持exit code和信号名2种,可写多个,以空格分隔,例如

  1.  RestartPreventExitStatus=143 137 SIGTERM SIGKILL

表示,当退出情况只要符合以下4种情况中任意一种时候,则不再进行重启

  • exit code为143

  • exit code为137

  • 信号为TERM

  • 信号为KILL

但具体如何使用,请继续往下看

4.测试方法

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

[Unit]
Description=mytest [Service]
Type=simple
ExecStart=/root/mem
Restart=always
RestartSec=
StartLimitInterval=
RestartPreventExitStatus=SIGKILL [Install]
WantedBy=multi-user.target

/root/mem.c(不断消耗内存直至发生OOM)

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> int main ()
{
char *p = NULL;
int count = ;
while(){
p = (char *)malloc(**);
if(!p){
printf("malloc error!n");
return -;
}
memset(p, , **);
printf("malloc %dM memoryn", *count++);
usleep();
}
}

编译及执行

gcc -o /root/mem /root/mem.c
systemctl daemon-reload
systemctl start mytest

5.测试结果

      [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 -- :: CST; 45s ago
Process: ExecStart=/root/mem (code=killed, signal=KILL)
Main PID: (code=killed, signal=KILL) Oct :: fzxiaomange.com systemd[]: Started mytest.
Oct :: fzxiaomange.com systemd[]: Starting mytest...
Oct :: fzxiaomange.com systemd[]: mytest.service: main process exited, code=killed, status=/KILL
Oct :: fzxiaomange.com systemd[]: Unit mytest.service entered failed state.
Oct :: fzxiaomange.com systemd[]: mytest.service failed.

重点看上面第6行 MainPID:10555(code=killed,signal=KILL),这行表示主进程的状态,常见有2种情况

  • code=exited, status=143:表示systemd认为主进程自行退出的,exit code为143

  • code=killed, signal=KILL:表示systemd认为主进程是被kill的,接收到的信号是SIGKILL

等待5秒后,并没有自动重启,符合预期

此时将RestartPreventExitStatus=SIGKILL改为RestartPreventExitStatus=SIGTERM

执行systemctl restart mytest,再进行一次观察,等待5秒后,服务自动重启,符合预期

6.注意事项

6.1.RestartPreventExitStatus与Restart的关系

配置RestartPreventExitStatus=后,并没有完全忽略Restart=,而是指当退出情况与RestartPreventExitStatus=匹配的时候,才忽略Restart=,若没有匹配,根据Restart=该怎么样还怎么样(具体详见后面的详细测试数据)

6.2.kill子进程会是什么情况

若systemd启动的不是一个简单进程,而是会派生子进程的情况(比如执行shell脚本,shell脚本里启动多个程序),那么当另外开一个窗口通过 kill-信号测试时,会是什么情况呢,先贴出测试方法

ExecStart=/root/mem改为ExecStart=/root/mytest.sh

/root/mytest.sh内容为

  1.  #!/bin/bash

  2.  sleep 100000 &

  3.  sleep 200000

测试结果

  • 若kill 主进程PID(kill不带参数),则主进程状态为 code=killed,signal=TERM

  • 若kill -9 主进程PID,则主进程状态为 code=killed,signal=KILL

  • 若kill 最后一个子进程PID(kill不带参数),则systemd不认为是接收到信号,而是根据最后一个进程的exit code进行处理,此时主进程状态为 code=exited,status=143

  • 若kill -9 最后一个子进程PID,此时主进程状态为 code=exited,status=137

7.详细测试数据

上面有提到RestartPreventExitStatus和Restart的关系,但没有数据说明

另外,kill和kill -9的区别,也需要有一份数据说明

因此做了一个详细对比,这里附上详细数据


转自

systemd实践: 依据情况自动重启服务 – 小慢哥的技术网站 https://fzxiaomange.com/2018/10/21/systemd-restartpreventexitstatus/

技术|Systemd服务简介 https://linux.cn/article-3352-3.html

systemd实践: 依据情况自动重启服务【转】的更多相关文章

  1. systemd实践: 依据情况自动重启服务

    systemd服务异常自动重启很好用,但有的时候希望某些服务只在特定情况下进行重启,其他时候不要自动重启(比如OOM,需要人工介入). 本文抛砖引玉,旨在能够让读者对systemd的重启机制有一定了解 ...

  2. zabbix通过curl命令判断web服务是否正常并自动重启服务

    zabbix通过curl命令判断web服务是否正常并自动重启服务 主要思路: 通过curl命令获取服务器响应码,如果正常返回200,不正常返回000 具体命令: curl -I -s -w " ...

  3. windows service自动重启服务

    服务一般都能正常的运行,但有时候也会有一些假死现象,比如公司有一考勤服务就因为依赖于硬件厂家的api, 但厂家api运行一段时间后会默名的假死,引起整个服务假死,因为这一假死现象具有不确定性,所以不太 ...

  4. Node.js热部署代码,实现修改代码后自动重启服务方便实时调试

    写PHP等脚本语言的时候,已经习惯了修改完代码直接打开浏览器去查看最新的效果.而Node.js 只有在第一次引用时才会去解析脚本文件,以后都会直接访问内存,避免重复载入,这种设计虽然有利于提高性能,却 ...

  5. 监控windows服务,当服务停止后自动重启服务

    近期花时间研究了一下windows和linux下某服务停了后自动重启的功能,在网上收集了些资料,并经过测试,在此整理一下.这里介绍的是windows服务的监控,是通过批处理来实现的.本例是监控wind ...

  6. nodejs之pm2自动重启服务

    pm2 start xxx #启动服务器 pm2 list #查看运行状态 pm2 logs #查看日志 pm2 restart xxx #重启应用 pm2 stop xxx #停止应用 监听修改,并 ...

  7. swoft实现自动重启服务 转

    目的:1.上传代码后HTTP服务自动重启,不需要自己手动执行:php bin/swoft http:start2.自动重启适用于开发调试阶段,因为不能再后台运行所以在线上环境的话还是要重启http服务 ...

  8. monit 监控并自动重启服务

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://coolerfeng.blog.51cto.com/133059/50126 Mo ...

  9. centos7下rsync+inotify脚本实现文件同步,.NET CORE客户端文件更新后自动重启服务

    源服务器IP:192.168.8.51 目标服务器IP:192.168.8.79 安装前源服务器及目标服务器均需关闭FIREWALLD\SELINUX防火墙 sestatus | grep statu ...

随机推荐

  1. 2017-12-15python全栈9期第二天第五节之格式化输出补充之想要在格式化输出中表示单纯的%号就加%

    #!/user/bin/python# -*- coding:utf-8 -*-name = input('姓名:')age = input('年龄:')height = input('身高:')ms ...

  2. Hbase_02、Hbase的常用的shell命令&Hbase的DDL操作&Hbase的DML操作(转)

    阅读目录 前言 一.hbase的shell操作 1.1启动hbase shell 1.2执行hbase shell的帮助文档 1.3退出hbase shell 1.4使用status命令查看hbase ...

  3. C语言复习---找出一个二维数组的鞍点

    前提: 求任意的一个m×n矩阵的鞍点——鞍点是指该位置上的元素在该行上为最大.在该列上为最小, 矩阵中可能没有鞍点,但最多只有一个鞍点. m.n(<=m<=.<=n<=)及矩阵 ...

  4. 设计模式---行为变化模式之访问器模式(Visitor)

    一:概念 访问者模式,是行为模式之一,它分离对象的数据和行为,使用Visitor模式,可以不修改已有类的情况下,增加新的操作角色和职责. 二:动机 在软件构建的过程中,由于需求的改变,某些类层次结构中 ...

  5. python django基础一web框架的本质

    web框架的本质就是一个socket服务端,而浏览器就是一个socker客户端,基于请求做出相应,客户端先请求,服务器做出对应响应 按照http协议的请求发送,服务器按照http协议来相应,这样的通信 ...

  6. Golang入门教程(十二)安装注意事项

    1.$GOPATH (1)go 命令依赖一个重要的环境变量:$GOPATH .注:这个不是Go安装目录 (2) (3) (4)git 安装 (5)包管理对应关系 (6)安装完之后bee 工具后,bee ...

  7. npm离线安装插件

    公司内部网络与外部网络隔离,导致npm无法通过npm install安装,只能通过离线安装. 要求: 两台机器(内网一台,外网一台) 两台机器上都已安装好的node和npm 以内网机器安装ftpsyn ...

  8. css3实现单行文本溢出显示省略号

    文本超出一定宽度让其隐藏,以省略号替代 width:200px; white-space:nowrap; text-overflow:ellipsis; overflow:hidden; 如下图

  9. Ganglia 入门介绍及解决fsockopen error: Connection refused问题

    一,问题描述 Ganglia的各个组件安装情况(不是我装的,只知道这些信息): 集群一共有4台机器,分别是192.168.121.34-37.Gmetad.Gweb和httpd 安装在 192.168 ...

  10. NSScanner类的基本用法

    NSScanner是一个类,用于在字符串中扫描指定的字符,尤其是把它们翻译/转换为数字和别的字符串.可以在创建NSScaner时指定它的string属性,然后scanner会按照你的要求从头到尾地扫描 ...