swoole 执行异步任务 案例 定时任务 大量数据请求执行异步

是这样的,风水轮流转确实不假,但你在轴心上这就很尴尬了

 

在很多时候,服务器需要进行定时执行某个脚本,而且数据量很大,耗时较长的情况下,这个时候我们就需要进行利用swoole的异步执行优势进行开发设计

直接上例子

<?php 
namespace app\command;

use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;

/**
 * dada测试
 */

class MySwoole extends Command{

    protected function configure() {
        // 指令配置
        $this->setName('my-test')
        ->setDescription('Say hello');
    }
    
       // 执行方法
    protected function execute(Input $input, Output $output) {

        $serv = new \swoole\server('127.0.0.1', 9501);

        $serv->set([
            'worker_num' => 4,// cpu核数1-4倍 work 进程数
            'task_worker_num' => 50,// task进程数
            'task_ipc_mode' => 1,// 模式
            'task_max_request' => 2000,
        ]);

        // 进程间无锁计数器
        $serv->atomic = new \Swoole\Atomic(0);

        // 直接启动
        $serv->on('WorkerStart', function ($serv, $workerId) {
            $this->onWorkerStart($serv, $workerId);
        });

        // 此函数在worker进程中执行 - 暂时没用到
        $serv->on('receive', function ($serv, $fd, $fromId, $data) {
            $this->onReceive($serv, $fd, $fromId, $data);
        });

        // 此回调函数在task进程中执行
        $serv->on('task', function ($serv, $taskId, $fromId, $data) {
            $this->onTask($serv, $taskId, $fromId, $data);

        });

        // 此回调函数在worker进程中执行
        $serv->on('finish', function ($serv, $taskId, $data) {
            $this->onFinish($serv, $taskId, $data);
        });

        // 执行入口
        $serv->start();
    }

    // 生成work进程和task进程
    public function onWorkerStart($server, $workerId) {

        // work 进行
        if( $workerId < $server->setting['worker_num'] ) {
            
            // 此workId  0, 1, 2, 3

            $mix = 100*$workerId;
            $max = 100*($workerId + 1);

            for($i=$mix;$i< $max;$i++) {
                // 进行计数计数增加
                $server->atomic->add();

                // 任务
                $server->task($i);
            }

        } else {
            // echo 'task id'.$workerId.PHP_EOL;
        }
    }

    protected function onTask($server, $taskId, $fromId, $data) {
        if( !empty($data) ) {

            // 相当执行你的逻辑程序
            sleep(1);

            // 直接调用
            $server->finish($data);
        }
    }

    protected function onReceive($server, $fd, $reactorId, $data) {

    }

    protected function onFinish($server, $taskId, $data) {

        // 计数器计数减少
        $server->atomic->sub();

        if( $server->atomic->get() == 1 ) {
            // 关闭资源
            $server->shutdown();
        }
    }


}

 

运行结果:

 

 

花了点时间,研究了一下,写的简单的案例模板,仅供参考

 

posted @ 2021-09-28 08:54  方达达  阅读(289)  评论(0编辑  收藏  举报