借助Laravel定时任务Schedule来实现(php-fpm)伪多进程

前提:在网上到出找资料都是需要安装多线程扩展,还有自己调用自己的接口CUrl请求自己1秒终端等,感觉麻烦本人比较懒,不想找运维安装扩展调试加班搞,在思考大半天后想起Laravel可以并发执行命定时脚本也能传参数,说干就干,首先咱们需要配置好Crontab脚本,本文方法是利用Linux的crontab定时任务来协助实现Laravel调度(Mac也一样)。 

咱们在部署之前最好在shell跑一下:

我的会报错要去php.ini文件去除禁用函数

一切可用之后用命令crontab -e 添加如下内容:

* * * * * /usr/local/bin/php /usr/local/var/www/projectName/artisan schedule:run >> /dev/null 2>&1

服务器的准备好之后开始代码:

咱们先在app/Console/Kernel.php文件 schedule方法内:

for ($i = 1; $i <= 10;$i++ ){
            $schedule->command("command:getInventoryByASN --num=$i")->everyMinute()->runInBackground();//商品授权每五分钟跑一次
}

10代表开的进程数,你可以安装自己的实际配置来选择。 $i 为传入线程识别号用它来做分批处理;runInBackground() 后台执行代表多条命令并发运行,命令必须在linux环境跑,windows在会报错要去运行。

注意要加文件锁一个进程对应一个锁,否则会出现重复处理的问题,我用的Laravel5.4版本withoutOverlapping()方法实测不管用。

<?php

namespace App\Console\Commands;

use App\CustomerInfo;
use App\GcReceiving;
use App\Lib\Helps\Common;
use App\LogHelper;
use Illuminate\Console\Command;


class getInventoryByASN extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'command:getInventoryByASN {--num=}';
    /**
     * @var string 多进程任务文件锁名称
     */
    private $fileLock = 'getInventoryByASN';
    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '根据入库单获取库存';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }
    //执行前
    public function before($num = 1)
    {
        $dir = storage_path();
        $flagFile = $dir . DIRECTORY_SEPARATOR . $this->fileLock . $num. '.lock';
        if (file_exists($flagFile)) {
            //如果锁文件存在时间过长删除锁文件
            if (time() - filemtime($flagFile) > 7200) {
                @unlink($flagFile);
            }
        }
        //如果锁文件存在,程序已经运行.
        if (file_exists($flagFile)) {
            echo "Is already running,please unlock! \n";
            exit(0);
        }
        //加锁,创建锁文件
        touch($flagFile);
        if (preg_match('/linux/i', PHP_OS) || preg_match('/Unix/i', PHP_OS)) {
            chmod($flagFile, 0777);
        }
    }

    public function end($num = 1)
    {
        $dir = storage_path();
        $flagFile = $dir . DIRECTORY_SEPARATOR . $this->fileLock . $num. '.lock';
        //解锁,删除锁文件
        unlink($flagFile);
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $num = $this->option('num') ?? 1;
        try {
            $this->before($num);
            ignore_user_abort(true);
            set_time_limit (0);
            date_default_timezone_set('PRC');//设置时间为中国时区
            ini_set('memory_limit', '1024M');
//            exec("chcp 65001");//设置命令行窗口为中文编码
            $logInfo = [
                'task_time'=>'任务时间:'.date('Y-m-d H:i:s',time()),
                'task_name'=>'批次入库单商品库存信息同步定时任务',
                'remark'=>'任务开始',
            ];
            $start = date('Y-m-d H:i:s');
            //codeing
            LogHelper::setExceptionLog($logInfo,'inventory_asn');
            GcReceiving::getPendingReceiveinfoChunk ($num);
            $mem = round(memory_get_peak_usage() / 1024 / 1024, 2);
            file_put_contents('task.log',"进程:".$num."----- 开始时间: $start------- 结束时间:". date('Y-m-d H:i:s')." ----- 同步完成;内存峰值:  $mem MB;"."\n", FILE_APPEND);
        } catch (\Exception $e) {

        } finally{
            $logInfo = [
                'task_time'=>'任务时间:'.date('Y-m-d H:i:s',time()),
                'task_name'=>'批次入库单商品库存信息同步定时任务',
                'remark'=>'任务结束',
            ];
            LogHelper::setExceptionLog($logInfo,'inventory_asn');
            $this->end($num);
        }
    }





}

在shell产生10个进程在运行,多进程运行代码成功:

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_34701838

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值