Workerman做HTTP服务器出现严重内存泄漏和busy

人民资本家

本人正在做的项目是一个网络游戏服务端,出现了严重的内存泄漏,大概在php app.php start -d后的几分钟开始出现内存占用暴涨,用php app.php status查看内存基本都由10M涨至400M乃至更多,同时会有几个子进程busy,导致CPU90-100%,仔细阅读手册和查找论坛案例始终没能从根本上解决问题,现在的解决方案是把Timer写进另一个启动文件(Timer没出现内存泄漏),然后业务写进另一个启动文件并设定一个定时脚本每五分钟reload。目前虽然能跑但是真难受。
关于全局变量或者静态变量的使用,未使用全局变量,有使用静态变量,游戏的数据在onWorkerStart时第一次从数据库加载到每一个子进程的类静态变量中,因为读取过于频繁,所以使用静态变量保存在内存中,但是这些数据只是在子进程启动时写入,后续都是读。
当前环境:服务器8核8G50M,PHP8.0.14
Timer可忽略,已写进另一个启动文件
如图已经有一个进程busy了,因为每五分钟reload,所以内存占用不多。
望各位高手不吝赐教。

704 1 0
1个回答

walkor

内存问题,数据库用的哪个组件?

cpu很高的问题,用 strace -s500 -ttp 进程pid 命令看下进程在做什么耗费cpu的业务。

  • 人民资本家 2022-01-16

    redis用的phpredis扩展,mysql用的pdo_mysql(mysqlnd)扩展,直接用Redis类和PDO类,没用其他的库或composer库,只是开了八个常驻内存的子进程,内部的代码本身还是同步阻塞的,所以redis和mysql连接也是用的类静态变量保存,在onWorkerStart的时候实例化。
    执行命令strace -s500 -ttp 37501显示strace: Process 37501 attached,然后就一直没有任何输出了。

  • 人民资本家 2022-01-16

    感谢walkor大大

  • 人民资本家 2022-01-16

    执行命令strace -s500 -ttp 37501时,37501进程是busy状态。

  • 人民资本家 2022-01-16

    我在一个窗口执行strace -s500 -ttp pid无响应,然后在另一个窗口执行kill -SIGALRM pid。
    结果如图
    https://i.bmp.ovh/imgs/2022/01/36ab4105b7817886.png

  • walkor 2022-01-16

    内存泄漏问题需要你自己压测下,看下具体哪个接口泄漏,然后然后才好找问题。

    busy问题,如果一直卡在 Process 37501 attached 不动,就再开一个终端,执行php start.php status,busy进程就会收到status信号,然后看下最后阻塞在哪里。根据 https://www.workerman.net/doc/workerman/debug/busy-process.html 定位问题。

    如果busy进程cpu100%,有很大概率是业务死循环了,一直消耗cpu。

🔝