V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
gzk329
V2EX  ›  Java

一台服务器上的程序 1 启动了多个子程序(脚本启动,固定),这个时候程序 1 突然挂了,那么这些子程序还在跑着,这种场景有什么好的处理方式吗?最好是程序 1 突然挂了的时候能带走它启动的所有子程序?

  •  
  •   gzk329 · 236 天前 · 2235 次点击
    这是一个创建于 236 天前的主题,其中的信息可能已经有所发展或是发生改变。
    20 条回复    2023-02-03 21:27:59 +08:00
    gzk329
        1
    gzk329  
    OP
       236 天前
    我记得是 Java Process 启动子进程,会随着主进程挂掉而一起挂掉,但是这个子进程的实际 processId 好像和获取的 processId 不一致,加了 1 ,所有选择的脚本启动,能解决这个问题,但是主程序挂了的话,子进程会失去控制
    cheng6563
        2
    cheng6563  
       236 天前   ❤️ 3
    丢容器,程序 1 以 pid 1 启动,这样他挂了就整个容器都挂了。
    Mohanson
        3
    Mohanson  
       236 天前
    Linux 进程组

    https://man7.org/linux/man-pages/man2/setpgid.2.html
    https://man7.org/linux/man-pages/man2/prctl.2.html PR_SET_PDEATHSIG 小章节

    至于 Java 要用什么 API 调用这个不了解
    killva4624
        4
    killva4624  
       236 天前
    Systemd 或者容器
    ruanimal
        5
    ruanimal  
       236 天前
    daemon
    eibici
        6
    eibici  
       236 天前
    加例检吧?
    julyclyde
        7
    julyclyde  
       236 天前
    你是腾讯 TEG 的吧?最好弃用那俩垃圾框架

    启动脚本开头设置个 trap ,收到 SIGCHLD 的话就 kill 掉 %1 %2 %3 等等子进程
    启动脚本里多个进程都&启动,转入后台,变成%1 %2 %3
    然后脚本末尾 wait
    gzk329
        8
    gzk329  
    OP
       236 天前
    @cheng6563 容器这个功能我们也是有的,但是把普通的和 docker 的分成两类了,现在得解决普通的异常场景...
    opengps
        9
    opengps  
       236 天前
    需要反向思维(因为是子进程而不是子线程)
    子程序单独加个线程去检测是否存在主进程,主进程不再则自己的进程退出
    8355
        10
    8355  
       236 天前
    优雅停机?
    kaiki
        11
    kaiki  
       236 天前 via iPhone
    @opengps 这样检测岂不是得用定时器这些重复判断的方法来额外占用资源?感觉有点不理想。
    opengps
        12
    opengps  
       236 天前
    @kaiki #11 其实是个通信的心跳用法,这个做法在高可用等场景并不少见,实际通信包很小,占用不了太多资源
    julyclyde
        13
    julyclyde  
       236 天前
    “固定”这个就限制了:不会有什么好的方案

    你必须得改
    aw2350
        14
    aw2350  
       236 天前
    context 上下文。或者每个子服务 启动后都有一个异步独立线程去监听主服务的状态。
    如果用 go 做,这是很简单的事情
    litguy
        15
    litguy  
       236 天前
    我们是 SIGABORT 自杀,自己捕获这个触发系统 PANIC
    jorneyr
        16
    jorneyr  
       236 天前
    这 2 天用 go 启动进程:
    - 使用 os.StartProcess 启动的多个后台进程,go 进程挂了的话所有它启动的进程都会被杀掉 (满足楼主的需求)
    - 适用 exec.Command 执行 nohup x > 2>&1 & 启动的后台进程,go 进程挂了的话它启动的进程不会被杀掉,因为这些进程的 PPID 是 1
    liuyongwang
        17
    liuyongwang  
       236 天前
    守护线程 daemon
    tool2d
        18
    tool2d  
       236 天前
    用 linux 管道把两个程序连接起来,如果管道挂了,那么两个程序都自动退出。
    pkking
        19
    pkking  
       236 天前
    PID 1 的进程不是会负责回收孤儿进程吗(如果这个进程结束了且没有人 wait ),在容器里有 tiini/dumb-init ,非容器的 systemd 都会做的吧
    kaneg
        20
    kaneg  
       236 天前
    可以看下 systemd 。systemd 的功能强大到让一些 Linux 大牛吐槽它管的太多了,想必你的这个需求应该已经在它的考虑范围了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   895 人在线   最高记录 6067   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 21:42 · PVG 05:42 · LAX 14:42 · JFK 17:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.