如何让systemd服务启动的子进程脱离systemd监管?
如何让systemd服务启动的子进程脱离systemd监管?
嘿,这个问题我之前踩过坑!systemd默认会把服务启动的所有子进程都攥在自己的cgroup里管着,一旦服务状态有变化就会一刀切清理,尤其是你用的oneshot类型服务,很容易触发超时强杀的情况。我给你几个实用的解决办法,一步步来:
一、最省心的方案:修改systemd服务配置
直接改ss-agent.service的配置就能解决杀进程+串行的问题,这是最一劳永逸的办法:
[Service] Type=oneshot ExecStart=/srv/agent/bin/run.sh # 核心配置:告诉systemd别杀任何相关进程 KillMode=none # 关闭停止超时,避免systemd因为等不到服务停止就发SIGKILL TimeoutStopSec=infinity
给你拆解下这俩配置的作用:
KillMode=none:默认systemd会杀掉服务cgroup下的所有进程,改成none后,不管服务是正常结束还是失败,systemd都不会碰你的子进程,完全放开监管。TimeoutStopSec=infinity:解决你日志里的超时强杀问题,systemd不会再因为等服务停止超时就硬杀进程。
改完之后,run.sh启动子进程后哪怕自己退出了,子进程也能安安稳稳跑几周,完全不受systemd干扰。
二、解决服务串行调用的问题
你提到的systemd串行执行的问题,其实是因为默认情况下,如果服务被判定为“运行中”,timer会阻塞下一次触发。搭配上面的配置,run.sh执行完后服务会立刻进入dead状态,timer会准时在60秒后触发下一次调用,不会被之前的子进程卡住。
三、脚本层面的应急方案(不推荐,太麻烦)
如果暂时不想改systemd配置,也可以在run.sh里动手脚,让子进程彻底脱离:
# 用setsid启动,让子进程成为新会话领头进程,脱离原进程组 setsid /path/to/your/agent-binary & # 或者手动把进程移到根cgroup(需要root权限) /path/to/your/agent-binary & child_pid=$! echo $child_pid > /sys/fs/cgroup/systemd/cgroup.procs
不过这种方法每次改脚本都要折腾,还是改systemd配置更省心。
最后提个小建议:长期运行的子进程记得加好日志,不然跑几周出问题了连排查方向都找不到~
备注:内容来源于stack exchange,提问作者jno
相关产品推荐
相关产品推荐

