You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

重启Golang Gin的dbagent服务时避免误杀Java子服务的方案咨询

问题:systemctl重启Golang服务时,关联的Java进程被意外终止

环境与现状

  • 基于Golang Gin开发的dbagent服务,由systemd管理
  • 服务启动链路:Golang进程执行start-a.sh脚本,该脚本调用不可修改的start-b.sh启动Java服务
  • 异常现象:执行systemctl restart dbagent时,Java进程会被一并杀死;从systemctl status输出可见,Java进程属于dbagent的CGroup组

Golang执行脚本的初始代码

exec.Command("bash", "/etc/start-a.sh").Start()

start-a.sh 内容

nohup /etc/start-b.sh 1>/dev/null 2>&1 &

start-b.sh 内容(不可修改)

nohup java -jar xxxx 2>&1 &

systemctl状态输出

[root@core03 bin]# systemctl status dbagent-server
● dbagent-server.service - "Database Agent Server"
   Loaded: loaded (/etc/systemd/system/dbagent-server.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2023-06-29 12:22:09 CST; 29min ago
 Main PID: 1905 (dbagent-server)
   CGroup: /system.slice/dbagent-server.service
           ├─1905 /usr/local/dbagent-server/dbagent-server
           ├─2795 /usr/java/jdk1.8.0_301-amd64/bin/java -Xmx1500m -X

已尝试的无效方案

  • 设置Golang进程SysProcAttr:
    cmd := exec.Command("bash", "/etc/start-a.sh")
    cmd.SysProcAttr = &syscall.SysProcAttr{
       Setsid: true, //Setpgid也尝试过
    }
    cmd.Start()
    
  • 使用setsid直接执行脚本:
    cmd := exec.Command("setsid", "/etc/start-a.sh")
    cmd.Start()
    
  • 结合disown命令:
    cmd := exec.Command("bash", "/etc/start-a.sh & disown")
    
  • 修改start-a.sh为:
    setsid /etc/start-b.sh
    

可行解决方案

方案1:修改systemd服务配置(推荐)

编辑/etc/systemd/system/dbagent-server.service,在[Service]段添加:

KillMode=process

执行以下命令使配置生效:

systemctl daemon-reload
systemctl restart dbagent-server

原理:systemd默认KillMode=control-group会杀死CGroup下所有进程,设置为process后仅终止主PID对应的进程,避免连带杀死Java进程。

方案2:修改Java进程的CGroup归属

修改start-a.sh内容,在启动Java服务后将其移至系统默认CGroup:

nohup /etc/start-b.sh 1>/dev/null 2>&1 &
# 匹配Java进程PID(需根据实际参数调整匹配规则)
JAVA_PID=$(pgrep -f "java -jar xxxx")
# 将进程移至system.slice CGroup
echo $JAVA_PID > /sys/fs/cgroup/system.slice/tasks

注意:需确保dbagent进程具备写入对应CGroup文件的权限。

方案3:用systemd独立托管Java服务

修改start-a.sh,使用systemd-run启动Java服务:

systemd-run --unit=java-dbagent-service /etc/start-b.sh

原理:Java服务会以独立的systemd单元运行,完全脱离dbagent的CGroup,不受其重启影响。

内容的提问来源于stack exchange,提问作者First Rain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 11:07:57