Laravel守护进程队列内存泄漏



我使用laravel 5.1并使用supervisor来监视队列作业。队列驱动是Database.

[program:queue]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/artisan queue:work database --sleep=3 --tries=1 --daemon
autostart=true
autorestart=true
user=root
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/html/storage/logs/supervisord.log

队列侦听器在处理每个作业后使用的RAM增加,最高可达150- 200mb。所有全局变量赋值为null。

namespace AppJobs;
use AppJobsJob;
use AppCompatibility;
use AppLike;
use AppMessage;
use IlluminateQueueSerializesModels;
use IlluminateQueueInteractsWithQueue;
use IlluminateContractsBusSelfHandling;
use IlluminateContractsQueueShouldQueue;
class CalculateInteractionLike extends Job implements SelfHandling, ShouldQueue
{
    use InteractsWithQueue, SerializesModels;
    protected $userAId;
    protected $userBId;
    protected $gender;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($userAId, $userBId, $gender)
    {
        $this->userAId = $userAId;
        $this->userBId = $userBId;
        $this->gender = $gender;
    }
    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        echo 'start CalculateInteractionLike '. memory_get_usage() . "n";
        $userArray = array();
        Compatibility::where('userAId', $this->userBId)->where('userBId', $this->userAId)->update(['interactionAB'=>0.0001]);
        $profiles = Compatibility::where('userAId', $this->userBId)->where('interactionAB', '>',0)->orderBy('compatibilityAB', 'desc')->take(4)->get(['compatibilityAB']);
        $compatible = array();
        for($i=0; $i<sizeof($profiles);$i++){
            $compatible[] = $profiles[$i]->compatibilityAB;
        }
        $std = sizeof($compatible)>1 ? $this->_calculateStd($compatible) : 0;
        $messagedProfile = Message::where('userBId', $this->userBId)->where('type', '1')->get(['userAId']);
        for($i=0;$i<sizeof($messagedProfile);$i++){
            Compatibility::where('userAId',$this->userBId)->where('userBId', $messagedProfile[$i]->userAId)->update(array('interactionAB' => $std));
        }
        $this->userAId = null;
        $this->userBId = null;
        $this->gender = null;
        $userArray = null;
        $profiles = null;
        $compatible = null;
        $std = null;
        $messagedProfile = null;
    }
    private function _calculateStd($compatible){
        return sqrt(array_sum(array_map([$this,"_stdSquare"], $compatible, array_fill(0,count($compatible), (array_sum($compatible) / count($compatible))))) / (count($compatible)-1));
    }
    private static function _stdSquare($x, $mean){
        return pow($x - $mean, 2);
    }
    public function __destruct(){
        $this->cleanup();
        echo 'end CalculateInteractionLike '. memory_get_usage() . "n";
    }
    public function cleanup() {
        //cleanup everything from attributes
        foreach (get_class_vars(__CLASS__) as $clsVar => $_) {
            unset($this->$clsVar);
        }
    }
}

如果上面的作业被处理,每次都会增加一些RAM。

作为一种解决方案-如果您找不到内存泄漏的来源-您可以切换到没有任何守护进程标志的queue:listen

这将在每个作业后"重新启动"框架,PHP释放所有内存。

这与Supervisor兼容,这将确保queue:listen总是重新启动。

唯一没有清理内存的地方是for()

        for($i=0;$i<sizeof($messagedProfile);$i++){
            Compatibility::where('userAId',$this->userBId)->where('userBId', $messagedProfile[$i]->userAId)->update(array('interactionAB' => $std));
        }

第一个是静态的(::used),但是是内部创建的对象,并且您开始使用->来调用函数。您是否尝试检查是否有析构函数并手动调用垃圾收集器?

 for($i=0;$i<sizeof($messagedProfile);$i++){
            Compatibility::where('userAId',$this->userBId)->where('userBId', $messagedProfile[$i]->userAId)->update(array('interactionAB' => $std));
            gc_collect_cycles();
        }

where(), update()等可以返回对对象的引用,所以如果你想尝试:

            for($i=0;$i<sizeof($messagedProfile);$i++){
                $tmp = Compatibility::where('userAId',$this->userBId)->where('userBId', $messagedProfile[$i]->userAId)->update(array('interactionAB' => $std));
$tmp = null;
            }

请注意php <7.0不会自动销毁在上层类中创建的类的对象。检查一下:https://codereview.stackexchange.com/questions/57847/case-of-the-hidden-memory-leak

最新更新