thinkphp5 think-worker 使用定时器,4个进程同时执行一个晚上,内存暴涨!

边玩边玩

运行10个小时,内存占用390M,并且4个报错也是内存溢出,如何能优化呢? 

[attach]1686[/attach]

[attach]1685[/attach]

[attach]1684[/attach]
 
 

5828 9 0
9个回答

six

定时器里的业务代码有内存泄漏,这个东西我觉得得自己找,把怀疑有内存泄漏的业务先注释掉跑着试下,慢慢就定位到了

  • 边玩边玩 2019-01-24

    意思是这个内存增长的原因还是因为 跑业务的内存泄漏导致的么...我看看

  • six 2019-01-24

    对啊

  • 边玩边玩 2019-01-24

    @1393:我先排查下业务,然后做个测试

边玩边玩

☀️

  • 暂无评论
边玩边玩

我排查了下,业务逻辑没问题,就内容采集和入库,没其他多余的逻辑啊
 
这里查了下内存最多的10个进程

[attach]1688[/attach]
 

  • six 2019-01-24

    把业务去掉就知道是不是业务问题啦

  • 边玩边玩 2019-01-24

    @1393:好,我也业务逻辑注释掉,定时器执行时间改5秒,4个进程同事进行,看内存是否会保障

  • 边玩边玩 2019-01-24

    @1393:纯定时器5秒,4个进程同时执行,没有业务逻辑,内存照样会增长,只是不会增长那么快

  • six 2019-01-24

    空定时器,我这测试不会有增长啊,你是怎么看出来内存涨了的

six
<?php
require_once __DIR__ . '/../Workerman/Autoloader.php';
use Workerman\Worker;
use Workerman\Lib\Timer;
$w = new \Workerman\Worker();
$w->onWorkerStart=function(){
    $timer_id=Timer::add(0.001,function(){
       
    });
};
\Workerman\Worker::runAll();

每秒1000次运行,跑了几分钟,定时器运行了几十万次,进程内存占用情况一直是3116K,没有丝毫变化USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
wanghai 46204 6.2 0.0 4365440 3116 s004 S+ 12:11下午 0:10.35 php timer.php start

  • 暂无评论
边玩边玩

[attach]1689[/attach]
运行2小时  32M

  • 暂无评论
a7662199

我这边也遇到这样的问题, 写一个socket服务端对接一个考勤机硬件,因为加了一个定时器,导致内存涨的很快,我目前的做法是每小时定时的reload, 还没有想到比较好的办法来解决这个问题, 
 

six

奇怪,为啥我的没问题。
你们自己运行下下面的代码,看下进程占用内存有涨没。

<?php
require_once __DIR__ . '/../Workerman/Autoloader.php';
use Workerman\Worker;
use Workerman\Lib\Timer;
$w = new \Workerman\Worker();
$w->onWorkerStart=function(){
    $timer_id=Timer::add(0.001,function(){
       
    });
};
\Workerman\Worker::runAll();
  • 静默 2019-01-24

    获取数据肯定是要占用内存的。只要内存不是无限涨到几十M就没问题。

  • 静默 2019-01-24

    一般是往全局数组里存数据,然后又不删除,慢慢数组变得越来越大,然后GG了

  • a7662199 2019-01-24

    @3236:我这边目前内存是无限涨的,一般到3个小时的时候会把线上8G的服务器爆掉

  • 静默 2019-01-24

    那可能真的是业务代码有内存泄漏了

  • a7662199 2019-01-24

    @5367:我的业务代码就存了一个客户端连接的全局数据还会定时清除掉

  • a7662199 2019-01-24

    @3236:我的业务代码里面都是一些sql操作,每次读取的数据也不多,下面上传了我的业务代码截图

  • 静默 2019-01-24

    那可能有2个地方导致的,一个是你说的那个存客户端连接的全局数据,一个是定时器部分。
    那个存客户端连接的全局数据定时打印下里面的连接数看下是不是无限增长,如果是可能就是这里导致的。定时器部分有可能是数据库类有问题,每次新建一个mysql连接去获取,用完连接也没关闭,导致开了很多mysql连接占用了很多内存。

  • a7662199 2019-01-24

    @3236:好的 感谢指导 我去测试看看

a7662199

[attach]1690[/attach]
 

  • 暂无评论
longhaishan
static $timer_count;
if(++$timer_count > 100) {
    Worker::stopAll();
}

把这个代码放到定时任务的尾部,即可解决的你的问题。

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