前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >systemd的oneshot 与 forking service的区别

systemd的oneshot 与 forking service的区别

作者头像
qsjs
发布2020-06-09 10:42:49
5.5K0
发布2020-06-09 10:42:49
举报
oneshot 类型的service:

A. 服务启动结果判断: 会等待”ExecStart=“ 指定的命令执行完成,然后根据返回值来判定是否执行成功;如果返回值为0, 那么认为执行成功,否则会有类似“failed to start service because control process exited with error code "这样的报错信息. 如果有多个“ExecStart=” 参数,那么会依次执行,只要有返回值是“error code”的,那么都会导致该service 启动失败. B. 服务状态查看: 无论执行成功或者失败,通过 "systemctl status" 来查看服务状态的时候,一般都会有 “Main PID: xxxx (code=exited, status=xx/...)” 之类的提示,只有 status=0 才表示服务启动成功,和上面A的描述是一致的,但是我们有时候可能会看到 "systemctl status” 显示该服务的状态是 : inactive(dead) 之类的提示,这是因为: control process 退出之后,oneshot类型的服务自动进入 inactive(dead) 状态, 但是如果设置了: RemainAfterExit=yes 的话,那么oneshot 类型的service 在成功启动之后会进入actived 状态. 所以,对于oneshot类型的服务,要查看其当前的状态,应该查看“exit ” code. C. 从子进程的角度看oneshot: 对于oneshot类型的service, 其在启动过程中并不关注有没有子进程,也不关注子进程的状态变化, 只要control process 退出的code 是0, 那么就表示启动成功. 所以很多服务的启动脚本可以修改为oneshot 类型的service unit.

forking 类型的service unit:

A. 这种类型和oneshot类型很像 . 如果control process的退出code不是0, 那么服务启动就被判定为fail. 同时,该类型并不支持多个 "ExecStart=" 参数。 B. 对于服务状态的显示,如果启动成功,那么 Active 状态始终是: running. 否则就是 inactive(dead) 的状态; C. 和oneshot不同的是: forking 类型的service, 其control process (ExecStart= )退出之后,其forking的子进程一定存在(如果不存在,那么该服务就不能是forking类型),并且应该是持续存在的, 除非手动去停止这个service. 如果forking的所有子进程中的main process 停止了,那么service 的状态就从running 变成了inactive(dead),同时其他的子进程也会被强制kill, 因为查寻service status的时候其实判断的是main process子进程的状态,基于这个原因,对于forking类型的service, 通常需要配合 "PIDFile=" 这个参数一起使用来指定main process 子进程,一旦main process 子进程退出,那么其他的子进程将也会被强制结束.而如果没有指定main process, 那么就算其中一个forking的子进程结束了,但是其他的子进程依然存在,这样的话,service的状态就依然是 running 的. 这就导致了"systemctl status" 查看的服务状态不够准确的问题. 所以建议 forking类型的service 总是加上 ”PIDFile=“ 这个参数

以下的代码验证了主进程退出就会导致 service unit的其他进程被系统kill的这种情况,主进程为 "sleep 30" ,当时间到30s后,主进程自动退出.从而导致 "sleep 3600" 进程被强制kill了.
代码语言:javascript
复制
[root@www ~]# cat /etc/systemd/system/my.service 
[Unit]
Description="Testing Service for forking"
After=syslog.service
[Service]
Type=forking
PIDFile=/var/run/my.pid
ExecStart=/root/s.sh start
ExecStop=/root/s.sh stop
[Install]
WantedBy=basic.target
[root@www ~]# cat s.sh 
#!/bin/bash
if [[ $1 = "start" ]];then
    nohup sleep 30 &
    nohup sleep 3600 & 
    echo `ps -ef | grep "sleep 30" | grep -Evi grep | awk '{print $2}'` >/var/run/my.pid
    exit 0
else:
    exit 0
fi
[root@www ~]# 
本文原创,转载请注明出处
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • oneshot 类型的service:
  • forking 类型的service unit:
  • 以下的代码验证了主进程退出就会导致 service unit的其他进程被系统kill的这种情况,主进程为 "sleep 30" ,当时间到30s后,主进程自动退出.从而导致 "sleep 3600" 进程被强制kill了.
  • 本文原创,转载请注明出处
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档