swoole 1.9.17 一个bug的处理过程
2017-08-02
背景
在用最新版swoole 1.9.17 跑websocket服务时,在重启服务时worker进程会产生异常。
除了swoole版本不一样之外,在swoole1.9.13和2.0.7版本的环境中均未发现此问题。
而1.9.17版本刚刚重构了底层WorkerStop的机制:https://wiki.swoole.com/wiki/page/775.html
复现
issue详情:https://github.com/swoole/swoole-src/issues/1309
环境
websocket server端代码为官网的例子,设置worker_num为5。
运行server代码,查看进程
一个master进程,一个manager进程,5个worker进程,一切正常。
但是在多次重启时,kill -USR1 pid,会出现如下问题
然后查看进程数,发现进程数会增加。
排查过程
首先看多出的进程都是什么进程
多次对比,多出的都是worker进程,而且当发生上述错误的时候,就会多出进程,在之后重启时,该进程一直没有被kill掉。
咨询韩老师,回答:
worker进程数量不一致是有可能的,新版本实现了异步安全reload,底层会先创建新的worker进程,因此统一时间可能会出现 worker_num * 2 数量的进程,老的 worker 进程会自然消亡并退出。
但实际上多出的进程一直都没有被kill掉。
然后strace一下这些进程,首先是master进程,master进程一直只是event_loop和接收信号,没有异常。
看manager进程
发现在接收到USR1信号量的时候,对某些worker进程并没有全部发送信号量。
看有问题的worker进程
发现在master发送信号量的时候,该进程没有收到信号,而且在过一段时间接收到SIGTSTP信号的时候,该进程也没有退出。
解决
底层有BUG,异步安全reload 特性带来的,有一个特殊情况会出现,同时并发了2个信号。
解决代码如下:https://github.com/swoole/swoole-src/commit/9a79829cd0d16d1ce8af76a8e68fa444957d2992
完成
韩老师在1.9.18分支中fix了该问题,安装了该分支后重新测试上述场景:
已经没有上述问题。