fork 的进程怎么自动 attach 到当前的 os.Std{in/out/err}而不是自动退出 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
dzdh
V2EX    Go 编程语言

fork 的进程怎么自动 attach 到当前的 os.Std{in/out/err}而不是自动退出

  •  
  •   dzdh 2022-12-25 11:17:25 +08:00 1593 次点击
    这是一个创建于 1040 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在折腾 go 的 0 停机重启升级。

    前几天看到了 systemd 方案,尝试后还可以。

    然后看到了另外一个方案: https://goteleport.com/blog/golang-ssh-bastion-graceful-restarts/

    有个疑问:

    测试后发现,当收到 HUP 信号后 fork 出子进程没问题,但是 http.Shutdown 结束后原来的进程直接退出了。当然是不影响服务的,就是有个问题,能不能不让老进程退出或者是老进程可以退出但是把 stdin/stdout/stderr 自动挂到新起的进程上呢。

    第 1 条附言    2022-12-25 11:53:30 +08:00

    当本地测试和使用systemd启动时,type=simple一旦fork子进程会systemd认为原先进程正常死掉了,然后就退出了子进程也跟着退了。当type=forking时,systemctl start 会卡住,直到fork一次(那只能进程一启动就自动先fork一遍?).

    试过 process.Wait() 但是进程会套娃

    7 条回复    2022-12-26 11:49:14 +08:00
    wheeler
        1
    wheeler  
       2022-12-25 12:34:49 +08:00 via iPhone
    能不能换个思路。起两个进程。监控进程和业务进程。监控进程作为 main process ,持久运行不退出。业务进程执行 fork exec 。
    wheeler
        2
    wheeler  
       2022-12-25 12:37:28 +08:00 via iPhone
    https://github.com/cloudflare/tableflip#integration-with-systemd

    或者你可以看看 fliptable 怎么玩的。
    dzdh
        3
    dzdh  
    OP
       2022-1225 12:46:21 +08:00
    @wheeler

    这样的话就要这么做:

    1. 启动 main process
    2. fork 业务 进程 传递个环境变量或者是指定参数 main process 记录个 pid 或者 process 对象
    3. main process 收到信号 再 fork 个进程,用 reuseport 监听(不用传递 fd 了),然后调用 process.signal 给老进程,覆盖全局的 process 对象为新启动的对象
    这样对于 systemd 来说只能是 type=simple

    是吧?类似 laravel 的 queue:listen ,自己不停的调 queue:work (本质上是两个命令)

    写成服务按传递不同参数的方案就是 xxx daemon 和 xxx work 用 xxx daemon 就是个 foreground manager 。它去管理 xxx work 的启停。也可以直接调用 xxx work ,收到信号就直接退

    按环境变量的做法就完全由 main process 管(ENV=ENV xxx 也太中二了)

    总的来说也是个办法。但是纯学习向来说还是想知道有没有什么方法可以做到让子进程在父进程退出后能直接接管父进程的 stdin/stdout/stderr...
    wheeler
        4
    wheeler  
       2022-12-25 12:50:07 +08:00 via iPhone
    @dzdh #3 golang exec 不是可以继承文件吗,然后子进程 serve fileListener 就好了。

    没记错的话,go http 默认自己会设置 reuseaddr 。
    lolizeppelin
        5
    lolizeppelin  
       2022-12-25 12:58:50 +08:00
    linux 基础问题, 查查文件描述符的复制继承就知道怎么做了,和 systemd 没有关系
    dzdh
        6
    dzdh  
    OP
       2022-12-25 14:07:50 +08:00
    @wheeler

    exec 可以继承文件但是解决不了本地开发的时候子进程脱离 console 的问题

    unix.SO_REUSEPORT 搜了一下源码目录没有地方调用。必须通过 net.ListenConfig.Control 手动指定。
    julyclyde
        7
    julyclyde  
       2022-12-26 11:49:14 +08:00
    可以由 systemd 持有 socket 然后你的软件只做服务

    不过其实我觉得你首先应该考虑,选 stdin/stdout 做服务,是不是真的合适
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5285 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 08:42 PVG 16:42 LAX 01:42 JFK 04:42
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86