Linux 多进程服务配置 systemd

整个项目由多个进程共同运行,现在需要一个可靠的保活机制,以便能够在进程崩溃的时候能够快速把它拉起来。有什么想法呢?最直观的解决方案无非就是写个保活脚本,在后台一直运行,如果发现某进程被关闭了,那么由脚本拉起来,但是脚本它自己挂掉怎么办?(总不能使用脚本继续保活保活脚本套娃吧)。此外,另一个办法就是配置出来一个服务,让Linux操作系统帮你守护进程,显然,这种办法完全不需要担心守护进程自己挂掉,毕竟是systemd帮你守护,如果它挂掉了,操作系统应该也没了。

sysvinit和systemd

sysvinitsystemd分别是两个Linux操作系统的初始化系统,Linux操作系统的服务就是它们运行起来的。在centos7之前使用的是sysvinitcentos7及之后使用的是systemd。此外还有ubuntuUpStart,不过新版的Ubuntu也使用systemd了。

比较明显的特征就是,旧版的linux使用service httpd start启动服务,新版的linux使用systemctl start httpd来启动服务,此外使用initd作为初始化系统的操作系统添加服务是在/etc/init.d/中添加脚本,而使用systemd作为初始化系统的操作系统只需要在/etc/systemd/system/文件夹中添加配置文件就好了。

具体和systemd相关的介绍可以看这里:浅析init和systemd【图文】_babylater_51CTO博客

一般来说,为了保持系统ABI的兼容性,系统的systemd版本不会特别激进,所以需要老一点文档,比如CentOS7运行的systemd对应的版本文档应该是这个systemd.service (archive.org)

多进程保活

首先最官方的文档在这里:systemd.service (www.freedesktop.org)

不过需要注意的是,需要注意操作系统上面使用的systemd的版本,通过执行systemd --version看到,比如我这个版本就是systemd 219,而最新的文档是systemd 250(这个可以在上面url页面的右上角看到)

但是,如果正在使用的systemd的版本和文档版本相差太大,可能会出现不准确的情况。比如在systemd 230之前是没有StartLimitInterSec这个选项的。此时就需要这个网站https://web.archive.org/,它会给网页拍摄快照,相当棒。此外,[systemd.unit 中文手册 金步国] (jinbuguo.com)这位译者翻译了相关文档,不过也请注意文档版本的问题。

创建配置文件(设定重试次数)

配置文件需要创建在/etc/systemd/system/文件夹里面,比如一个配置文件如下,文件名/etc/systemd/system/program.service

[Unit]
Description=program's service [Service]
Type=idle
Environment=LD_LIBRARY_PATH=.:/export/home/admin/usr/install/gcc940/lib
ExecStart=/export/home/admin/gamed/program/bin/program gamesys.conf 1
Restart=always
RestartSec=5
StandardOutput=null
StandardError=null
StartLimitInterval=40000000
StartLimitBurst=3 [Install]
WantedBy=multi-user.target

新版本的系统(systemd 230之后),没有StartLimitInterval需要使用StartLimitIntervalSec,并且StartLimitIntervalSecStartLimitBurst两个项在[Unit]节区!!!详情请通过https://web.archive.org/查询和系统systemd版本对应的文档

然后通过systemctl start program.service启动服务,通过systemctl status program.service查看服务状态和启动失败原因,通过systemctl stop program.service关闭服务。

首先一个服务的配置文件是.service作为后缀的,结构类似于windows.ini配置文件,其中一般由三个部分。分别是

  • [Unit]:包含与单元类型无关的通用信息
  • [Service]:其中是服务的属性
  • [Install]: 该小节包含单元的启用信息。 事实上,systemd(1) 在运行时并不使用此小节。 只有 systemctl(1)enabledisable 命令在启用/停用单元时才会使用此小节(个人理解:决定在systemd处于什么目标状态下有效)

其中有多个选项,例如上面的配置文件,含义分别如下

  • Description 是作为服务的描述

  • Type表示服务的类型,可以是simple exec forking oneshot dbus notify,一般使用simple

  • Environment 可以指定服务会用到的环境变量

  • ExecStart 是通过systemctl start xxx启动服务时执行的命令

    • 需要注意的是,实测这里不能直接指定>重定向到文件,如有需要见下面StandardOutput
  • Restart 表示重启的条件,可以取no, on-success, on-failure, on-abnormal, on-watchdog, on-abort, always之一

  • RestartSec 如果重启,两次重启之间的间隔 默认是100ms

  • StandardOutput 标准输出,老版本(比如Systemd 219)不能直接指定文件,新版本可以这样指定文件file:/var/log/xxx.log

  • StandardError 同上不过是标准错误

  • StartLimitIntervalStartLimitBurst 这两个表示在StartLimitInterval指定的时间里重试失败StartLimitBurst次则放弃重试,

    • 可以通过systemctl reset-failed 重置失败次数,
    • 需要注意的是,手动停止服务也会被计数,并且如果设定上面两个参数,失败后必须手动重置
    • 再者,Systemd 230之后使用StartLimitIntervalSec替代了StartLimitInterval这里很坑...所以需要注意文档版本
    • 新版本这个选项是在Unit节区
  • WantedBy它的值是一个或多个 Target,当前 Unit 激活时(enable)符号链接会放入/etc/systemd/system目录下面以 Target 名 + .wants后缀构成的子目录中

    (这里放一个我自己的理解,systemd有类似于initd的运行级别的东西,详见浅析init和systemd【图文】_babylater_51CTO博客Sysvinit 运行级别和 systemd 目标的对应表,所以 WantedBy设置为 multi-user.target的含义就比较明确了,也即是systemdctl enable xx.service之后,在对应目标状态下启用)

具体的含义见systemd.service (www.freedesktop.org)

以上配置能够实现的效果就是进程因为任何方式停止运行(除了手动stop),都会触发重启,但是在4000000秒之内只重启3次,重试三次不成功,就不再尝试,此时并不能直接systemctl start program,需要首先systemctl reset-failed(重置失败计数)之后才能再次start

如果不使用StartLimitIntervalSecStartLimitBurst 就不需要考虑systemctl reset-failed的使用了

多进程服务管理

如果需要创建很多服务,但是服务的配置文件只有ExecStart项有细微区别,那么可以考虑使用模板功能。

比如,创建服务文件/etc/systemd/system/ping@.service

[Unit]
Description=Ping service %i [Service]
Type=simple
ExecStart=/usr/bin/ping %i [Install]
WantedBy=multi-user.target

启动进程可以这样systemctl start ping@127.0.0.1.service,实际上,启动服务可以省略.service后缀,也即是systemctl start ping@127.0.0.1,如果要一次启动多个服务,可以systemctl start ping@127.0.0.1 ping@127.0.0.2,停止服务也是类似。

这样,如果想要ping别的地址,只需要修改命令中@之后的字符串就好了。

也支持如下这样拼接字符串

[Unit]
Description=Ping service %i [Service]
Type=simple
ExecStart=/usr/bin/ping 127.0.0.%i [Install]
WantedBy=multi-user.target

systemctl start ping@1就能执行ping 127.0.0.1服务

对于配置文件中的%i其实是有大小写区别的,%i是转义之后的字符串 %I是不转义的字符串,对于完整的说明符列表,见systemd.unit (www.freedesktop.org)

链式启动(服务依赖)

有这么一种情况,需要同时启动多个服务,并且他们有启动顺序的限制。那么可以像下面这么配置

假设有 A进程B进程C进程,想要按顺序依次启动,那么可以这么配置

/etc/systemd/system/C.service

[Unit]
Description=C Process
Requires=B.service
After=B.service [Service]
Type=simple
ExecStart=/export/CProgram [Install]
WantedBy=multi-user.target

/etc/systemd/system/B.service

[Unit]
Description=B Process
Requires=A.service
After=A.service [Service]
Type=simple
ExecStart=/export/BProgram [Install]
WantedBy=multi-user.target

/etc/systemd/system/A.service

[Unit]
Description=A Process [Service]
Type=simple
ExecStart=/export/AProgram [Install]
WantedBy=multi-user.target

效果是,systemctl start C.service之后几个进程会依次启动,Requires指定了几个服务之间的依赖关系,因为通过After选择指定了服务间启动顺序,所以几个服务是依次启动的。如果没有After启动顺序不被保证

如果,此时systemctl stop A.service,那么几个服务都会被关闭,因为Requires要求了前置服务必须存在,否则自身也不应该启动。如果不想自身服务被关闭,那么可以把Requires(要求)替换成Wants(想要)。

如果要形成依赖链,除了After也可以使用Before

完整说明参见systemd.unit (www.freedesktop.org)

指定关闭进程方式 - ExecStop

可以通过ExecStop选项关闭由ExecStart启动的服务,因为有些程序需要发送特定的信号才能安全退出,所以这个选项会很有用。而对于其他被主进程拉起来的进程,按照KillMode的设置处理,默认情况下,停止服务会关闭主进程以及主进程启动的所有子进程。

而对于KillMode有如下几个设置,分别是

  • control-group:会干掉主进程及子进程 这是默认选项
  • mixed: SIGTERM 信号被发送到主进程,而随后的 SIGKILL 信号被发送到单元控制组的所有剩余进程,可以通过KillSignal设置关闭主进程的信号
  • process: 仅关闭主进程
  • none: 什么也不干

详情见:systemd.kill (www.freedesktop.org)

例如,如果要事先约定某进程需要发送SIGUSR1信号才能安全结束,那么可以在[Service]节区设定ExecStop=kill -SIGUSR1 $MAINPID

上文$MAINPID类似于环境变量,表示主进程的pid,完整列表见[systemd.exec (www.freedesktop.org)](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Environment Variables Set or Propagated by the Service Manager)

查看服务输出 - journalctl

systemd不仅用来运行服务,它同时也有日志服务,用于取代老系统的syslog

运行的服务标准输出和错误输出会被交给journald管理,查看某个服务可以使用这样的命令journalctl -u ping@1-e参数可以跳到最新一行 -f参数可以看到实时输出,-n参数可以指定输出的行数,-r反序输出。

例如journalctl -u ping@1 -e 或者 journalctl -u ping@1 -f

如果服务的输出太多,那么可以在.servive文件中的[Unit]节区配置StandardOutput=null

也可以通过systemctl status xx.service查看服务的部分输出

具体使用参考

持久化journalctl日志清空命令查看配置参数详解_陈沩亮博客 (chenweiliang.com)

journalctl (www.freedesktop.org)

Linux 多进程服务配置 systemd的更多相关文章

  1. Linux ISCSI服务配置

    Linux ISCSI服务配置,客户端进行访问 环境配置: server端 172.25.0.11 client端 172.25.0.10 配置ISCSI服务端 1.安装软件包 yum install ...

  2. Kali Linux常用服务配置教程获取IP地址

    Kali Linux常用服务配置教程获取IP地址 下面以Kali Linux为例,演示获取IP地址的方法 (1)设置网络接口为自动获取IP地址.在Kali Linux的收藏夹中单击图标,将显示所有的程 ...

  3. Kali Linux常用服务配置教程启动DHCP服务

    Kali Linux常用服务配置教程启动DHCP服务 通过前面的介绍,DHCP服务就配置好了.接下来,用户就可以使用该服务器来获取IP地址了.下面将对前面配置的服务进行测试. 1.启动DHCP服务 如 ...

  4. Kali Linux常用服务配置教程安装及配置DHCP服务

    Kali Linux常用服务配置教程安装及配置DHCP服务 在Kali Linux中,默认没有安装DHCP服务.下面将介绍安装并配置DHCP服务的方法. 1.安装DHCP服务 在Kali Linux中 ...

  5. Kali Linux常用服务配置教程DHCP服务原理

    Kali Linux常用服务配置教程DHCP服务原理 动态主机配置协议(Dynamic Host Configuration Protocol,简称DHCP)是一个局域网的网络协议,基于UDP协议工作 ...

  6. Linux vsftpd服务配置以及三种验证方式以及常见错误解决办法

    文件传输协议(FTP): 文件传输协议(FTP,File Transfer Protocol),即能够让用户在互联网中上传.下载文件的文件协议,而FTP服务器就是支持FTP传输协议的主机,要想完成文件 ...

  7. Linux vsftpd服务配置具体解释

    [背景] 近日.一朋友dominoserver要进行升级.迁移,搭建了linux測试系统,也开启vsftpd服务,但是配置的ftp账号,程序无法正常下载附件. [问题跟踪] 通过ftpclient连接 ...

  8. linux nfs服务配置挂载以及oracle使用nfs存储挂载注意事项

    服务端共享目录 /home/XXX/nfs_shared 172.16.22.0/24(rw,no_root_squash) service nfs restart 常用命令: 查看所有nfs共享目录 ...

  9. Linux NTP服务配置 for Oracle RAC

    安装Oracle 11g RAC时,我们需要配置ntp服务.在使用虚拟机的情况下对于时钟同步方式的配置有很多种方式,可以使用vmware自带的时钟同步功能,也可以直接将本地的一个节点用作时间服务器.本 ...

  10. linux samba 服务配置及日志管理

    2012-01-16    安装samba共需3个rpm包   samba-common-3.0.23c-2.i386.rpm  samba-3.0.23c-2.i386.rpm  samba-cli ...

随机推荐

  1. rider代码折叠

    可折叠元素块 rider那些元素块是可折叠?参考官方文档:Fold Code Elements Code folding works for the keywords if/ while/ else/ ...

  2. 集成Unity3D到iOS应用程序中

    如果想让原生平台(例如 Java/Android.Objective C/iOS 或 Windows Win32/UWP)包含 Unity 功能,可以通过Unity 生成UnityFramework静 ...

  3. 苹果打破12年惯例:iPad一整年未更新

    1月2日消息,据媒体报道,自2010年首次亮相以来,苹果一直保持着每年至少发布一款新型号的传统. 但是在过去的2023年,苹果没有发布iPad,2023年苹果发布的唯一与iPad相关的产品是USB-C ...

  4. Oracle ADG + Keepalived 切换演练

    客户的一套生产环境采用的架构是Oracle ADG + Keepalived,近期需要进行切换演练,要求我这边保障.ADG本身切换倒没啥可说的,但引入keepalived软件,就需要提前研究下这个架构 ...

  5. OGG-将PostgreSQL通过OGG_BigData同步到Kafka后数据存在8小时时间差

    问题描述: 将PostgreSQL通过OGG_BigData同步到Kafka后数据存在8小时时间差. 问题原因: kafka.properties中的参数goldengate.userexit.tim ...

  6. 2023年多校联训NOIP层测试4+洛谷 8 月月赛 I & RiOI Round 2

    2023年多校联训NOIP层测试4 爆零了 T1 幸运数字 \(0pts\) 首先考虑一个结论: \(4\) 的倍数一定满足最后两位能被 \(4\) 整除. 从 \(1\) 进行输入,方便处理.若枚举 ...

  7. CF1829H Don't Blame Me

    题目链接 题解 知识点:线性dp,位运算. 考虑设 \(f_{i,j}\) 表示考虑了前 \(i\) 个数字,与和为 \(j\) 的方案数.转移方程显然. 注意初值为 \(f_{0,63} = 1\) ...

  8. NC26257 小雨坐地铁

    题目链接 题目 题目描述 小雨所在的城市一共有 \(m\) 条地铁线,分别标号为 1 号线,2 号线,--,m 号线.整个城市一共有 \(n\) 个车站,编号为 \(1 \sim n\) .其中坐 i ...

  9. NC20650 可爱の星空

    题目链接 题目 题目描述 "当你看向她时,有细碎星辰落入你的眼睛,真好."--小可爱 在一个繁星闪烁的夜晚,卿念和清宇一起躺在郊外的草地上,仰望星空. 星语心愿,他们,想把这片星空 ...

  10. Python 装饰器解析(二)

    前面一篇文章介绍了python装饰器,最后引入了functools.wraps的使用,本篇文章将对它进行深入的探究. functools模块提供了一系列的高阶函数以及对可调用对象的操作,其中为人熟知的 ...