关于http协议下,restart -g时造成的进程每处理一条请求就退出的问题

www

workerman版本4.0.6
现象:使用restart -g重启服务,进程每处理一个请求后就退出.客户端使用php curl,使用浏览器访问,当浏览器关闭时也会出现这个现象.而服务正常start时无此问题.
经实验发现,curl每次请求完后会关闭连接,此时TcpConnection类会destroy当前连接,进入__destruct,由于-g参数为true会走到Worker::stopAll,造成进程退出.
截图
代码是TcpConnection.php的截图,998行由于-g参数的存在,条件为真,当连接数为0时,进程退出.
请问998行到1010行的代码的作用是什么?如果删除掉会有什么影响?

1869 2 1
2个回答

six

restart为啥要加-g ?,-g是平滑退出进程用的。

  • 暂无评论
phpcreeper

我还是从个人的理解严谨下相关的概念:
1、workerman的平滑指的的是reload指令干的事情,并不是 -g 参数所起的作用,而且也不是一回事,关于什么是平滑重启,手册说的很清楚:
http://doc.workerman.net/faq/reload-principle.html
2、-g 参数正如单词gracefully含义一样,代表“优雅”行为,所以restart -g 即代表优雅重启进程,当然还有 stop -g 即代表优雅的退出进程;这里也能看出很大的区别了;

概念明确了,那我们还得从“优雅”行为背后的业务概念理解说起:
1、首先删了肯定是不行的有影响的,删了题示的那几行代码则workerman所体现的“优雅”功能荡然无存了;
2、restart -g 体现在: 如果重启之前仍有存活的TCP连接,甚至连接上还有数据的来往交互,如果没有-g, 那就相当于强硬重启进程,即原子进程立即退出,新的子进程立即补上来,原连接强制被中断,数据因此可能丢失;相反,原子进程则不会立即退出,直至该进程内的所有连接都已妥善断开才会补充一个新的子进程上来继续服务,所谓的“优雅”重启说的这个。

  • www 2020-07-22

    感谢解答!我能否理解为-g参数只能跟reload一起用,restart不能使用-g参数?

  • phpcreeper 2020-07-22

    不是你理解的这样的, stop、restart、reload指令均可以配合 -g 参数。

  • www 2020-07-22

    那我有点不明白了,restart -g会产生上面说的问题,还是可以用?

  • phpcreeper 2020-07-22

    首先你客户端的行为无非就是什么时刻切断tcp连接的问题;其次服务端这边执行了restart 不论有没有-g参数都会导致原进程退出并重新补充一个新的上来,只不过这个行为受到-g参数的影响【这个时候和客户端的TCP连接是有关系的】,具体的影响上面那大段话说的很明白了,自己再捋一捋吧;

  • www 2020-07-23

    @614:非常感谢你能抽出时间来解答我的问题,但是说实话,我还是有点不明白,可能是我基础比较弱.我补充下提出问题的原因.我需要的是业务可以热重启,就是说重启时不能丢失当前的业务数据.reload -g可以做到,但是,当服务器配置更改,比如增加了进程数,或者修改了启动脚本,reload就不行了(这种情况很少见,但是我必须要考虑当它发生时可能带来的后果).restart重启时,如果有业务执行时间较长,会被强制kill掉,业务数据会丢失.stop -g后再start在低访问量时是可以的,但是访问量高时会有闪断.我原以为restart -g可以实现我的需求(也可能有闪断问题,暂且不论),但是却有进程退出的问题.基于上面的原因我提出了前面的问题,其实我不是想纠结什么时候用-g什么时候不用,我只是想解决问题.目前我的解决方案是用shell先启动一个新的服务,启动完成后再关闭老的服务,暂时没有更好的办法了.感谢回复!

  • phpcreeper 2020-07-23

    @5923:
    1、增加了进程或者修改启动脚本,这两个没辙,势必会牵扯到进程的重启,也没有什么热启一说,热启就是针对reload指令以及常见的更新业务代码常见而言的;另外多说一句restart是父子进程全部退出重来,reload仅仅只是子进程退出重来,但也支持设置不退出,看你场景。
    2、根据workerman自身的信号实现的工作机制,无论是restart亦或是stop或者是reload,都会涉及到进程的退出的问题,但是进程退出前会有两种情况发生:一个是业务代码会正常执行完毕后进程正常退出;另外一个是设定在指定的时间内【参考常量Worker::KILL_WORKER_TIMER_TIME】业务必须执行完毕,否则到期后进程强制退出【当然针对是非优雅手段操作进程】。

    所以不难发现,不管哪种情况都有可能造成业务数据的丢失,所以官方手册里也有提到不要在进程里保存业务数据;至于提及的新旧服务,这个我理解的就是如何不影响用户持续不间断的提供服务,一般就是上集群了。

年代过于久远,无法发表回答
×
🔝