当前位置:   article > 正文

Laravel+workman+redis实现多进程异步任务处理

Laravel+workman+redis实现多进程异步任务处理

前言


PHP本身并不直接支持多线程编程,因为PHP的设计初衷是作为一个脚本语言,主要面向的是Web开发。不过我们可以使用一些扩展和库来实现多进程的功能,提高系统性能,比如workerman和swoole。通过多进程异步执行任务。

安装workman


Laravel中使用workman创建多进程任务


  • 1.创建 artisan命令

    目录下建立命令行文件WorkermanCommand

    php artisan make:command WorkermanCommand
    
    • 1

    文件内容如下

    protected $signature = 'workman {action} {--d}';
    
        protected $description = 'Start a Workerman server.';
    
        public function handle()
        {
            global $argv;
            $action = $this->argument('action');
    
            $argv[0] = 'wk';
            $argv[1] = $action;
            $argv[2] = $this->option('d') ? '-d' : '';
    
            $this->start();
        }
    
        private function start()
        {
            $this->startGateWay();
            $this->startBusinessWorker();
            $this->startRegister();
            Worker::runAll();
        }
    
        private function startBusinessWorker()
        {
            $worker                  = new BusinessWorker();
            $worker->name            = 'BusinessWorker';
            $worker->count           = 1;
            $worker->registerAddress = '127.0.0.1:1236';
            $worker->eventHandler    = \App\Workerman\Events::class; //指定workman监听事件文件
        }
    
        private function startGateWay()
        {
            $gateway = new Gateway("websocket://0.0.0.0:2346");
            $gateway->name                 = 'Gateway';
            $gateway->count                = 1;
            $gateway->lanIp                = '127.0.0.1';
            $gateway->startPort            = 2300;
            $gateway->pingInterval         = 30;
            $gateway->pingNotResponseLimit = 0;
            $gateway->pingData             = '{"type":"@heart@"}';
            $gateway->registerAddress      = '127.0.0.1:1236';
        }
    
        private function startRegister()
        {
            new Register('text://0.0.0.0:1236');
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
  • 2.创建监听事件

    创建app/Workerman/Events.php文件来监听处理Workman的各种事件

    <?php
    
    namespace App\Workerman;
    
    class Events
    {
    
        public static function onWorkerStart($worker)
        {
            echo 'workman进程启动,进程id ' . $worker->id . PHP_EOL;
    
            //监听redis队列
            $redis = app('redis.connection');
            while (true) {
                //读取redis队列
                $data = $redis->lPop('test-queue');
                if ($data) {
                    //处理业务
                    echo '进程id ' . $worker->id . ' 开始处理业务数据' . $data . PHP_EOL;
                    //模拟耗时任务
                    sleep(5);
                    echo '进程id ' . $worker->id . ' 处理业务数据' . $data . ' 完成' . PHP_EOL;
                } else {
                    echo '进程id ' . $worker->id . ' 空闲中,休息5秒' . PHP_EOL;
                    sleep(5);
                }
            }
        }
    
        public static function onConnect($client_id)
        {
        }
    
        public static function onWebSocketConnect($client_id, $data)
        {
        }
    
        public static function onMessage($client_id, $message)
        {
        }
    
        public static function onClose($client_id)
        {
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
  • 3.启动workman

    php artisan workman start -d
    
    • 1

    看到下面的信息说明启动成功

    root@2e870aece68b:/var/www/hello# php artisan workman start
    Workerman[wk] start in DEBUG mode
    -------------------------------------------- WORKERMAN ---------------------------------------------
    Workerman version:4.1.15          PHP version:7.4.33           Event-Loop:\Workerman\Events\Select
    --------------------------------------------- WORKERS ----------------------------------------------
    proto   user            worker            listen                      processes    status
    tcp     root            Gateway           websocket://0.0.0.0:2346    4             [OK]
    tcp     root            BusinessWorker    none                        4             [OK]
    tcp     root            Register          text://0.0.0.0:1236         1             [OK]
    ----------------------------------------------------------------------------------------------------
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  • 4.在laravel框架中新增api接口将任务加入redis队列,例如我这里写一个添加redis列表元素的方法

    <?php
    
    namespace App\Http\Controllers;
    
    
    class IndexController extends Controller
    {
        //新增队列数据
        public function addQueue()
        {
            $redis = app('redis.connection');
            $redis->rPush('test-queue', '1');
            $redis->rPush('test-queue', '2');
            $redis->rPush('test-queue', '3');
            $redis->rPush('test-queue', '4');
            $redis->rPush('test-queue', '5');
            $redis->rPush('test-queue', '6');
            $redis->rPush('test-queue', '7');
            echo 'success';
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    加完方法后记得新增路由

  • 5.访问上面的将任务加入redis队列接口,直接用浏览器或者命令行curl访问http://网站域名/api/index/addQueue即可,然后你就可以看到所有的redis队列将被workman进程分配并执行,以下是我启动workman->添加redis队列->workman处理->队列处理结束打印的结果:

    root@2e870aece68b:/var/www/hello# php artisan workman start
    Workerman[wk] start in DEBUG mode
    -------------------------------------------- WORKERMAN ---------------------------------------------
    Workerman version:4.1.15          PHP version:7.4.33           Event-Loop:\Workerman\Events\Select
    --------------------------------------------- WORKERS ----------------------------------------------
    proto   user            worker            listen                      processes    status
    tcp     root            Gateway           websocket://0.0.0.0:2346    4             [OK]
    tcp     root            BusinessWorker    none                        4             [OK]
    tcp     root            Register          text://0.0.0.0:1236         1             [OK]
    ----------------------------------------------------------------------------------------------------
    Press Ctrl+C to stop. Start success.
    workman进程启动,进程id 2
    workman进程启动,进程id 0
    workman进程启动,进程id 1
    进程id 0 空闲中,休息5秒
    workman进程启动,进程id 3
    进程id 2 空闲中,休息5秒
    进程id 1 空闲中,休息5秒
    进程id 3 空闲中,休息5秒
    进程id 0 开始处理业务数据1
    进程id 2 开始处理业务数据3
    进程id 3 开始处理业务数据4
    进程id 1 开始处理业务数据2
    进程id 0 处理业务数据1 完成
    进程id 0 开始处理业务数据5
    进程id 3 处理业务数据4 完成
    进程id 2 处理业务数据3 完成
    进程id 1 处理业务数据2 完成
    进程id 3 开始处理业务数据6
    进程id 2 开始处理业务数据7
    进程id 1 空闲中,休息5秒
    进程id 0 处理业务数据5 完成
    进程id 0 空闲中,休息5秒
    进程id 3 处理业务数据6 完成
    进程id 2 处理业务数据7 完成
    进程id 2 空闲中,休息5秒
    进程id 3 空闲中,休息5秒
    进程id 1 空闲中,休息5秒
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/309449
推荐阅读
相关标签
  

闽ICP备14008679号