首页 后端开发 php教程 php如何使用SwooleTaskWorker实现异步操作Mysql(代码)

php如何使用SwooleTaskWorker实现异步操作Mysql(代码)

Oct 17, 2018 pm 04:02 PM
linux mysql php

本篇文章给大家带来的内容是关于php如何使用SwooleTaskWorker实现异步操作Mysql(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

在一般的 Server 程序中都会有一些耗时的任务,比如:发送邮件、聊天服务器发送广播等。如果我们采用同步阻塞的防水去执行这些任务,那么这肯定会非常的慢。

Swoole 的 TaskWorker 进程池可以用来执行一些异步的任务,而且不会影响接下来的任务,很适合处理以上场景。

那么什么是异步任务呢?

可以从下面的图示中来简单了解一下。(来源于网络,侵删)

4082169211-5bc5c9e6327d8_articlex.png

我们上一个 Swoole 的文章介绍了如何创建一个简单的服务器,并且知道了几个核心的回调函数的使用方法。

要实现上述的异步处理,只需要增加两个事件回调即可:onTask 和 onFinish, 这两个回调函数分别用于执行 Task 任务和处理 Task 任务的返回结果。另外还需要在 set 方法中设置 task 进程数量。

使用示例:

class Server
{
    private $serv;
    public function __construct() {
        $this->serv = new swoole_server("0.0.0.0", 9501);
        $this->serv->set(array(
            'worker_num' => 4,
            'daemonize' => false,
            'task_worker_num' => 8
        ));
        $this->serv->on('Start', array($this, 'onStart'));
        $this->serv->on('Connect', array($this, 'onConnect'));
        $this->serv->on('Receive', array($this, 'onReceive'));
        $this->serv->on('Close', array($this, 'onClose'));
        $this->serv->on('Task', array($this, 'onTask'));
        $this->serv->on('Finish', array($this, 'onFinish'));
        $this->serv->start();
    }

    public function onReceive( swoole_server $serv, $fd, $from_id, $data ) {
        echo "Get Message From Client {$fd}:{$data}\n";
        // 发送任务到Task进程
        $param = array(
            'fd' => $fd
        );
        $serv->task( json_encode( $param ) );
        echo "继续处理之后的逻辑\n";
    }

    public function onTask($serv, $task_id, $from_id, $data) {
        echo "This Task {$task_id} from Worker {$from_id}\n";
        echo "Data: {$data}\n";
        for($i = 0 ; $i < 5 ; $i ++ ) {
            sleep(1);
            echo "Task {$task_id} Handle {$i} times...\n";
        }
        $fd = json_decode( $data , true )[&#39;fd&#39;];
        $serv->send( $fd , "Data in Task {$task_id}");
        return "Task {$task_id}'s result";
    }
    public function onFinish($serv,$task_id, $data) {
        echo "Task {$task_id} finish\n";
        echo "Result: {$data}\n";
    }
    public function onStart( $serv ) {
        echo "Server Start\n";
    }
    public function onConnect( $serv, $fd, $from_id ) {
        echo "Client {$fd} connect\n";
    }
    public function onClose( $serv, $fd, $from_id ) {
        echo "Client {$fd} close connection\n";
    }
}
$server = new Server();
登录后复制

通过上述示例可以看到,发起一个异步任务只需要调用 swoole_server 的 task 方法就可以。发送之后会触发 onTask 回调,可以通过 $task_id 和 $from_id 处理不同进程的不同任务。最后可以通过 return 一个字符串来将执行结果返回给 Worker 进程,Worker 进程通过 onFinish 回调来处理结果。

那么基于上述代码就可以实现异步操作 mysql。异步操作 mysql 较适合以下场景:

  • 并发的读写操作

  • 没有时序上的严格关系

  • 不影响主线程逻辑

好处:

  • 提高并发

  • 降低 IO 消耗

数据库的压力主要在于 mysql 维持的连接数,如果存在 1000 个并发,那么 mysql 就需要建立对应数量的连接。而采用长连接的方式,mysql 的连接一直维持在进程中,减少了创建连接的损耗。可以通过 swoole 开启多个 task 进程,每一个进程内维持一个mysql 长连接,那么这样子也可以引申出来 mysql 连接池技术。还需要注意的是,mysql 服务器如果检测到长时间没有没有查询,则会断开连接回收资源,所以要有断线重连的机制。

以下是一个简单的异步操作 mysql 的示例:

还是以上的代码,我们只需要修改 onReceive、onTask、onFinish 三个函数。

class Server
{
    private $serv;
    public function __construct() {
        $this->serv = new swoole_server("0.0.0.0", 9501);
        $this->serv->set(array(
            'worker_num' => 4,
            'daemonize' => false,
            'task_worker_num' => 8 // task进程数量 即为维持的MySQL连接的数量
        ));
        $this->serv->on('Start', array($this, 'onStart'));
        $this->serv->on('Connect', array($this, 'onConnect'));
        $this->serv->on('Receive', array($this, 'onReceive'));
        $this->serv->on('Close', array($this, 'onClose'));
        $this->serv->on('Task', array($this, 'onTask'));
        $this->serv->on('Finish', array($this, 'onFinish'));
        $this->serv->start();
    }

    public function onReceive( swoole_server $serv, $fd, $from_id, $data ) {
        echo "收到数据". $data . PHP_EOL;
        // 发送任务到Task进程
        $param = array(
            'sql' => $data, // 接收客户端发送的 sql 
            'fd'  => $fd
        );
        $serv->task( json_encode( $param ) );  // 向 task 投递任务
        echo "继续处理之后的逻辑\n";
    }

    public function onTask($serv, $task_id, $from_id, $data) {
        echo "This Task {$task_id} from Worker {$from_id}\n";
        echo "recv SQL: {$data['sql']}\n";
        static $link = null;
        $sql = $data['sql'];
        $fd  = $data['fd'];
        HELL:
        if ($link == null) {
            $link = @mysqli_connect("127.0.0.1", "root", "root", "test");
        }
        $result = $link->query($sql);
        if (!$result) { //如果查询失败
            if(in_array(mysqli_errno($link), [2013, 2006])){
                //错误码为2013,或者2006,则重连数据库,重新执行sql
                    $link = null;
                    goto HELL;
            }
        }
        if(preg_match("/^select/i", $sql)){//如果是select操作,就返回关联数组
             $data = array();
                while ($fetchResult = mysqli_fetch_assoc($result) ){
                     $data['data'][] = $fetchResult;
                }                
        }else{//否则直接返回结果
            $data['data'] = $result;
        }
        $data['status'] = "OK";
        $data['fd'] = $fd;
        $serv->finish(json_encode($data));
    }
    public function onFinish($serv, $task_id, $data) {
        echo "Task {$task_id} finish\n";
        $result = json_decode($result, true);
        if ($result['status'] == 'OK') {
            $this->serv->send($result['fd'], json_encode($result['data']) . "\n");
        } else {
            $this->serv->send($result['fd'], $result);
        }
    }
    public function onStart( $serv ) {
        echo "Server Start\n";
    }
    public function onConnect( $serv, $fd, $from_id ) {
        echo "Client {$fd} connect\n";
    }
    public function onClose( $serv, $fd, $from_id ) {
        echo "Client {$fd} close connection\n";
    }
}
$server = new Server();
登录后复制

以上代码在 onReceive 时直接接收一条 sql,之后直接发送到 Task 任务中。这个时候下一步的流程紧接着输出,这里也就体现出了异步。然后 onTask 和 onFinish 分别用来向数据库发送 sql,处理 task 执行结果。

以上是php如何使用SwooleTaskWorker实现异步操作Mysql(代码)的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1662
14
CakePHP 教程
1419
52
Laravel 教程
1311
25
PHP教程
1261
29
C# 教程
1234
24
MySQL和PhpMyAdmin:核心功能和功能 MySQL和PhpMyAdmin:核心功能和功能 Apr 22, 2025 am 12:12 AM

MySQL和phpMyAdmin是强大的数据库管理工具。1)MySQL用于创建数据库和表、执行DML和SQL查询。2)phpMyAdmin提供直观界面进行数据库管理、表结构管理、数据操作和用户权限管理。

Linux上的Docker:Linux系统的容器化 Linux上的Docker:Linux系统的容器化 Apr 22, 2025 am 12:03 AM

Docker在Linux上重要,因为Linux是其原生平台,提供了丰富的工具和社区支持。1.安装Docker:使用sudoapt-getupdate和sudoapt-getinstalldocker-cedocker-ce-clicontainerd.io。2.创建和管理容器:使用dockerrun命令,如dockerrun-d--namemynginx-p80:80nginx。3.编写Dockerfile:优化镜像大小,使用多阶段构建。4.优化和调试:使用dockerlogs和dockerex

在MySQL中解释外键的目的。 在MySQL中解释外键的目的。 Apr 25, 2025 am 12:17 AM

在MySQL中,外键的作用是建立表与表之间的关系,确保数据的一致性和完整性。外键通过引用完整性检查和级联操作维护数据的有效性,使用时需注意性能优化和避免常见错误。

比较和对比Mysql和Mariadb。 比较和对比Mysql和Mariadb。 Apr 26, 2025 am 12:08 AM

MySQL和MariaDB的主要区别在于性能、功能和许可证:1.MySQL由Oracle开发,MariaDB是其分支。2.MariaDB在高负载环境中性能可能更好。3.MariaDB提供了更多的存储引擎和功能。4.MySQL采用双重许可证,MariaDB完全开源。选择时应考虑现有基础设施、性能需求、功能需求和许可证成本。

SQL与MySQL:澄清两者之间的关系 SQL与MySQL:澄清两者之间的关系 Apr 24, 2025 am 12:02 AM

SQL是一种用于管理关系数据库的标准语言,而MySQL是一个使用SQL的数据库管理系统。SQL定义了与数据库交互的方式,包括CRUD操作,而MySQL实现了SQL标准并提供了额外的功能,如存储过程和触发器。

Linux操作:管理文件,目录和权限 Linux操作:管理文件,目录和权限 Apr 23, 2025 am 12:19 AM

在Linux中,文件和目录管理使用ls、cd、mkdir、rm、cp、mv命令,权限管理使用chmod、chown、chgrp命令。1.文件和目录管理命令如ls-l列出详细信息,mkdir-p递归创建目录。2.权限管理命令如chmod755file设置文件权限,chownuserfile改变文件所有者,chgrpgroupfile改变文件所属组。这些命令基于文件系统结构和用户、组系统,通过系统调用和元数据实现操作和控制。

MySQL与Oracle有何不同? MySQL与Oracle有何不同? Apr 22, 2025 pm 05:57 PM

MySQL适合快速开发和中小型应用,Oracle适合大型企业和高可用性需求。1)MySQL开源、易用,适用于Web应用和中小型企业。2)Oracle功能强大,适合大型企业和政府机构。3)MySQL支持多种存储引擎,Oracle提供丰富的企业级功能。

Linux中的维护模式是什么?解释了 Linux中的维护模式是什么?解释了 Apr 22, 2025 am 12:06 AM

MaintenancemodeInuxisAspecialBootenvironmentforforcalsystemmaintenancetasks.itallowsadMinistratorStoperFormTaskSlikerSettingPassingPassingPasswords,RepairingFilesystems,andRecoveringFrombootFailuresFailuresFailuresInamInimAlenimalenimalenrenmentrent.ToEnterMainterMainterMaintErmaintErmaintEncemememodeBoode,Interlecttheboo

See all articles