死循环问题

Endy

早上发现Mac风扇狂转,看了一下活动监视器,竟然是PHP进程占用了接近100%的CPU,这是以前从未发生过的。
ps -ef|grep php看了一下,用于web应用的是php-fpm,php启动的进程只有workerman的几个businessworker
重启workerman,CPU使用降下去了,问题解决。
然后开始查看原因,打开日志,竟然loading了很久, ll看了一下,日志大小达到2GB。
日志从末尾往上,99%都是一句打印:

worker[Businessworker:xxxxx] exit with status 9

xxxxx为不停分配的进程号,但是每一个都刚分配好就kill掉了
继续往上查看日志,发现一个DB异常,error code: 1927 ('Connection was killed')
因为我在Events里需要bindUid,所以用到了DB查询,MariaDB主动断开连接造成了这个异常(具体原因还没有去详细查找,谷歌了一些结果说可能是因为并发造成死锁,但是这个地方只有简单的读,一个SELECT操作并没有加锁,回头再仔细看看,先解决死循环的主要矛盾),所以复现也很容易,在事件循环时故意关闭数据库服务即可。

1712 3 0
3个回答

小七他哥

看看这样可不可以解决:

$this->sql = $sql;
        $this->result = mysqli_query($this->conn, $this->sql);

        //参考:https://wenda.workerman.net/question/1793
        if ($this->getErrorNo() == 2006) {
            $this->initConnection();
            $this->result = mysqli_query($this->conn, $this->sql);
            //注意这里不能再做有关于数据库的操作,否则会发生死循环
            wlog('数据库链接失效重连');
        }

主要就是在 mysqli_query 或者 mysql_query 这一步下面加个检测当前有没有错误号为 2006 的,如果有错误就重连一遍数据库。

  • 暂无评论
抽不完的寂寞

连数据库放在onWorkerStart里试下,不要在onWorkerStart运行前连数据库

  • 暂无评论
Endy

连接数据库是放在Gateway的onMessage里,worker早就启动了。
worker进程和数据库产生了连接,连接过程中,数据库突然发生异常断掉连接。

1、没有弄明白这个数据库断开的异常为什么会kill掉worker
2、为什么新fork的worker立即获得了SIGKILL的信号导致不停fork不停kill

  • 小七他哥 2021-07-20

    看源代码吧,很多地方都写的 exit(250); 这句,这里就是被kill 了

  • Endy 2021-07-20

    不是在exit(250)被kill的,这句之前都会有log,但日志里面就只有exit with status 9,我试了直接从命令行kill -9worker进程,也不会产生反复fork反复kill的死循环。

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