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

systemd服务异常自动重启很好用,但有的时候希望某些服务只在特定情况下进行重启,其他时候不要自动重启(比如OOM,需要人工介入)。
本文抛砖引玉,旨在能够让读者对systemd的重启机制有一定了解。
小慢哥的原创文章,欢迎转载
1.最简单的自动重启范例
[Unit]
Description=mytest
[Service]
Type=simple
ExecStart=/root/mytest.sh
Restart=always
RestartSec=5
StartLimitInterval=0
[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种,可写多个,以空格分隔,例如
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=5
StartLimitInterval=0
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 = 1;
while(1){
p = (char *)malloc(1024*1024*100);
if(!p){
printf("malloc error!\n");
return -1;
}
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
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 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种情况
- 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内容为
#!/bin/bash
sleep 100000 &
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实践: 依据情况自动重启服务的更多相关文章
- systemd实践: 依据情况自动重启服务【转】
1.最简单的自动重启范例 [Unit] Description=mytest [Service] Type=simple ExecStart=/root/mytest.sh Restart=alway ...
- zabbix通过curl命令判断web服务是否正常并自动重启服务
zabbix通过curl命令判断web服务是否正常并自动重启服务 主要思路: 通过curl命令获取服务器响应码,如果正常返回200,不正常返回000 具体命令: curl -I -s -w " ...
- windows service自动重启服务
服务一般都能正常的运行,但有时候也会有一些假死现象,比如公司有一考勤服务就因为依赖于硬件厂家的api, 但厂家api运行一段时间后会默名的假死,引起整个服务假死,因为这一假死现象具有不确定性,所以不太 ...
- Node.js热部署代码,实现修改代码后自动重启服务方便实时调试
写PHP等脚本语言的时候,已经习惯了修改完代码直接打开浏览器去查看最新的效果.而Node.js 只有在第一次引用时才会去解析脚本文件,以后都会直接访问内存,避免重复载入,这种设计虽然有利于提高性能,却 ...
- 监控windows服务,当服务停止后自动重启服务
近期花时间研究了一下windows和linux下某服务停了后自动重启的功能,在网上收集了些资料,并经过测试,在此整理一下.这里介绍的是windows服务的监控,是通过批处理来实现的.本例是监控wind ...
- nodejs之pm2自动重启服务
pm2 start xxx #启动服务器 pm2 list #查看运行状态 pm2 logs #查看日志 pm2 restart xxx #重启应用 pm2 stop xxx #停止应用 监听修改,并 ...
- swoft实现自动重启服务 转
目的:1.上传代码后HTTP服务自动重启,不需要自己手动执行:php bin/swoft http:start2.自动重启适用于开发调试阶段,因为不能再后台运行所以在线上环境的话还是要重启http服务 ...
- monit 监控并自动重启服务
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://coolerfeng.blog.51cto.com/133059/50126 Mo ...
- centos7下rsync+inotify脚本实现文件同步,.NET CORE客户端文件更新后自动重启服务
源服务器IP:192.168.8.51 目标服务器IP:192.168.8.79 安装前源服务器及目标服务器均需关闭FIREWALLD\SELINUX防火墙 sestatus | grep statu ...
随机推荐
- page事件
using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Secu ...
- shiro登陆权限验证
一>引入shirojar包 <!-- shiro登陆权限控制 --> <dependency> <groupId>org. ...
- (转)Jetty实战之 安装 运行 部署
http://blog.csdn.net/kongxx/article/details/7218767 本文地址:http://blog.csdn.NET/kongxx/article/details ...
- apicloud UISearchBar 使用方法
app中经常会有搜索的页面. 大概逻辑是,一般来说首页有一个搜索的图,点击之后跳转到一个搜索的页面,在这个页面做搜索. 正常代码逻辑 <body> <a class="bu ...
- H5网页涂鸦canvas
最近做了个播放页面,标题和一个iframe;需要对这个iframe可以进行网页涂鸦.网页涂鸦肯定是canvas了.网上找了个差不多的,实验下来问题很多,干脆自己一步步修改,学习. 效果: 本项目没有引 ...
- .Net Core 中X509Certificate2 私钥保存为 pem 的方法
在自己签发CA证书和颁发X509证书时,私钥通过下面的方法保存为PEM 相关代码可以已经提交在了 https://github.com/q2g/q2g-helper-pem-nuget/pull/13 ...
- Day 22 面向对象编程
面向对象基础 面向对象编程(抽象) 对象:特征和技能的结合体 面向对象编程:一个个对象进行交互 优点:扩展性非常强 缺点:逻辑非常复杂 类与对象 类(类别):一系列具有相同特征和技能的对象 现实世界中 ...
- appium+python,app自动化测试框架
目前正在写一个app的自动化UI测试框架,目录结构如, 脚本还在调试,实现的方法是从excel表格读取测试用例,执行完成后会将结果保存到Excel中. 等待.......
- [luogu2679] 子串 (多维dp)
传送门 Description 有两个仅包含小写英文字母的字符串 A 和 B . 现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来 ...
- intellij idea 的历史版本
开发工具intellij idea 的历史版本https://www.jetbrains.com/idea/download/previous.html