workerman 平滑重启原理 。分析源码 没有看懂

oldtwo

截图
为什么这个就可以实现平滑重启。 没有看懂。 怎么保证。我在重启的时候 之前没有完成的请求可以继续完成。新的请求不过来

2346 2 1
2个回答

phpcreeper

得分开理解,就拿 restart 和 reload 举例来说吧

  • restart自身的含义是父进程接收到特定信号后,父进程会将特定信号送给旗下的各个子进程,注意:这时候子进程收到相应信号后可以看做是同时退出的,与此同时父进程也会退出;
  • reload恰好相反,其本身的含义基本同上,区别之一在于子进程收到相应的信号后,是一个一个来的,就是你退完了,我再退,如此迭代往复,完成子进程的灭失和再生;区别之二在于父进程并不会退出,但是restart会退出;

那再来说说 -g 参数
上面的描述针对的都是指令本身,也就是裸参行为,但是一旦带了-g参数,那么上述指令的行为就会发生微妙的变化,体现在: 当子进程发现依然有活动的TCP连接时,子进程是不会退出的,换句话就是它就会等待你把事情干完,所以我想在必要的时候(比如业务干完了)是需要关闭下TCP连接的。

如此看来,应该使用: restart -g 或 reload -g

  • phpcreeper 2022-05-12

    再补充下,其实对于短连接这个是没有问题,长连接我认为还要做些额外工作: 比如在收到reload -g 指令后【业务层可以在onWorkerReload回调里干】还是应该有个timeout机制的,可以先判断下是否有保活数据包或者通过一个标记位判断有没有业务正在处理,没有就直接干掉TCP连接,否则限定在timeout内干完然后再干掉TCP连接.

  • oldtwo 2022-05-12

    谢谢 你。 我自己在想想吧

  • oldtwo 2022-05-12

    当子进程发现依然有活动的TCP连接时,子进程是不会退出 。 子进程 怎么发现 有没有活动的进程的

  • yzmdd 2022-11-20

    如何平滑重启,你得看看worker启动之后,进入事件循环的代码看select的容易理解点,结合你现在看到的信号代码;select事件循环的首先就是触发信号处理函数,后面才是处理读写time等事件,就是调用绑定的事件回调函数;所以当worker进程执行到pcntl_signal_dispatch后面的代码,即使有信号事件来也不会触发,当然这里说的除了SIGKILL信号,这就达到了worker还在处理业务的时候是不会退出的,但是如果不加-g参数父进程给worker发送的是SIGKILL信号,这个信号会立刻让进程退出,SIGKILL信号是不会暴露给用户的,就是这个信号不能绑定用户的回到函数

  • liziyu 2022-11-20

    看来再深入就要涉及到操作系统方面的东西了,厉害!~

evilk

我测试过
执行 restart -d不是reload -d
同样可以启起到平滑重启的作用
前提是设置stop_timeout = 30

  • 暂无评论
年代过于久远,无法发表回答
×
🔝