前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >workerman5.0 和 swoole5.0 实现一键协程

workerman5.0 和 swoole5.0 实现一键协程

作者头像
Tinywan
发布2024-04-28 11:07:42
1130
发布2024-04-28 11:07:42
举报
文章被收录于专栏:开源技术小栈开源技术小栈

概述

在现代的互联网应用开发中,性能和实时性是衡量一个应用成功的关键指标。Workerman 和 Swoole 作为 PHP 社区中流行的高性能通信库,它们的结合使用为开发者提供了强大的异步网络通信能力。本文将深入探索如何利用 Workerman 5.0 结合 Swoole 5.0 来实现一键协程。

? 问: workerman5.0为什么要使用swoole5.0,原因很简单:workerman5.0 全面支持Swoole驱动。更多了解:https://github.com/walkor/workerman/releases/tag/v5.0.0-beta.1

使用

强烈建议看看这个作为入门:webman如何使用swoole事件驱动和协程?

为了方便开发和部署,这里直接使用docker容器。

代码语言:javascript
复制
docker pull tinywan/docker-php-webman:8.2.17-swoole5.1

更多使用方法可以参考这里 https://github.com/Tinywan/docker-php-webman。该容器支持swoole扩展5.1.1

代码语言:javascript
复制
# pecl info swoole
About pecl.php.net/swoole-5.1.1
===============================
Release Type          PECL-style PHP extension (source code)
Name                  swoole
Channel               pecl.php.net
Summary               Event-driven asynchronous and concurrent
                      networking engine with high performance for PHP.
Description           Event-driven asynchronous and concurrent
                      networking engine with high performance for PHP.
                       - event-driven
                       - coroutine
                       - asynchronous non-blocking
                       - multi-thread reactor
                       - multi-process worker
                       - multi-protocol
                       - millisecond timer
                       - built-in tcp/http/websocket/http2 server
                       - coroutine tcp/http/websocket client
                       - coroutine mysql client
                       - coroutine redis client
                       - coroutine read/write file system
                       - coroutine dns lookup
                       - support IPv4/IPv6/UnixSocket/TCP/UDP
                       - support SSL/TLS encrypted transmission
Maintainers           Tianfeng Han <rango@swoole.com> (lead)
                      Twosee <twosee@php.net> (developer)
                      Shen Zhe <shenzhe163@gmail.com> (developer,
                      inactive)
                      Lu Fei <lufei@php.net> (developer)
                      Bruce Dou <doubaokun@php.net> (developer)
Release Date          2023-11-26 14:25:25
Release Version       5.1.1 (stable)
API Version           5.0 (stable)
License               Apache2.0
                      (http://www.apache.org/licenses/LICENSE-2.0.html)
Release Notes         - Fixed memory leak issue in HTTP coroutine
                      client
                      - Fixed the issue of can not hook pdo_odbc
                      - Fixed the error in executing
                      socket_import_stream()
                      - Fixed the issue with
                      Context::parse_multipart_data() unable to handle
                      empty request body
                      - Fixed the issue with PostgreSQL coroutine
                      client where the parameters are not working
                      - Fixed the bug where curl crashes during
                      destruction
                      - Fixed the compatibility issue between Swoole
                      5.x and the latest version of xdebug
                      - Fixed the problem of class not found error
                      caused by coroutine switching during the process
                      of class autoloading
                      - Fixed the issue of not being able to compile
                      Swoole on OpenBSD
Required Dependencies PHP version 8.0.0
                      PEAR installer version 1.4.0 or newer
package.xml version   2.0
Last Modified         2024-04-21 10:05
Previous Installed    - None -
Version

开启swoole事件驱动

webman框架中开启swoole事件驱动特别简单,只有配置一下就可以了。修改配置文件config/server.php服务配置文件

代码语言:javascript
复制
'event_loop' => Workerman\Events\Swoole::class

Docker 启动webman

代码语言:javascript
复制
$ docker run --rm -it -p 8887:8787 -v d:/dnmp/www/webman2024:/app tinywan/docker-php-webman:8.2.17-swoole5.1
2024-04-21 14:13:53,255 INFO Set uid to user 0 succeeded
2024-04-21 14:13:53,266 INFO supervisord started with pid 1
2024-04-21 14:13:54,272 INFO spawned: 'webman' with pid 7
Workerman[/app/start.php] start in DEBUG mode
-------------------------------------------------- WORKERMAN --------------------------------------------------
Workerman version:5.0.0    PHP version:8.2.17     Event-loop:Workerman\Events\Swoole
--------------------------------------------------- WORKERS ---------------------------------------------------
proto   user            worker                       listen                      processes    state
tcp     root            webman                       http://0.0.0.0:8787         8             [OK]
tcp     root            monitor                      none                        1             [OK]
tcp     root            push_chart                   none                        1             [OK]
tcp     root            plugin.webman.push.server    websocket://0.0.0.0:8788    1             [OK]
---------------------------------------------------------------------------------------------------------------
Press Ctrl+C to stop. Start success.

swoole实现协程

协程伪代码

代码语言:javascript
复制
<?php
/**
 * @desc Swoole 协程入门
 * @author Tinywan(ShaoBo Wan)
 * @date 2024/4/22 19:27
 */
declare(strict_types=1);

function task1(){
    for ($i=0;$i<=5;$i++){
        //写入文件,大概要3000微秒
        usleep(3000);
        echo '[x] [写入文件] ['.$i.'] ' . date('Y-m-d H:i:s') . PHP_EOL;
        \Co::sleep(0.001);//挂起当前协程,0.001秒后恢复//相当于切换协程
    }
}
function task2(){
    for ($i=0;$i<=10;$i++){
        //发送邮件给500名会员,大概3000微秒
        usleep(3000);
        echo '[x] [发送邮件] ['.$i.'] ' . date('Y-m-d H:i:s') . PHP_EOL;
        Co::sleep(0.001);//挂起当前协程,0.001秒后恢复//相当于切换协程
    }
}
function task3(){
    for ($i=0;$i<=15;$i++){
        //模拟插入100条数据,大概3000微秒
        usleep(3000);
        echo '[x] [插入数据] ['.$i.'] ' . date('Y-m-d H:i:s') . PHP_EOL;
        Co::sleep(0.001);//挂起当前协程,0.001秒后恢复//相当于切换协程
    }
}
$pid1 = go('task1'); //go函数是swoole的开启协程函数,用于开启一个协程
$pid2 = go('task2');
$pid3 = go('task3');

执行结果

代码语言:javascript
复制
[x] [写入文件] [0] 2024-04-21 13:31:37
[x] [发送邮件] [0] 2024-04-21 13:31:37
[x] [插入数据] [0] 2024-04-21 13:31:37
[x] [写入文件] [1] 2024-04-21 13:31:37
[x] [发送邮件] [1] 2024-04-21 13:31:37
[x] [插入数据] [1] 2024-04-21 13:31:37
[x] [写入文件] [2] 2024-04-21 13:31:37
[x] [发送邮件] [2] 2024-04-21 13:31:37
[x] [插入数据] [2] 2024-04-21 13:31:37
[x] [写入文件] [3] 2024-04-21 13:31:37
[x] [发送邮件] [3] 2024-04-21 13:31:37
[x] [插入数据] [3] 2024-04-21 13:31:37
[x] [写入文件] [4] 2024-04-21 13:31:37
[x] [发送邮件] [4] 2024-04-21 13:31:37
[x] [插入数据] [4] 2024-04-21 13:31:37
[x] [写入文件] [5] 2024-04-21 13:31:37
[x] [发送邮件] [5] 2024-04-21 13:31:37
[x] [插入数据] [5] 2024-04-21 13:31:37
[x] [发送邮件] [6] 2024-04-21 13:31:37
[x] [插入数据] [6] 2024-04-21 13:31:37
[x] [发送邮件] [7] 2024-04-21 13:31:37
[x] [插入数据] [7] 2024-04-21 13:31:37
[x] [发送邮件] [8] 2024-04-21 13:31:37
[x] [插入数据] [8] 2024-04-21 13:31:37
[x] [发送邮件] [9] 2024-04-21 13:31:37
[x] [插入数据] [9] 2024-04-21 13:31:37
[x] [发送邮件] [10] 2024-04-21 13:31:37
[x] [插入数据] [10] 2024-04-21 13:31:37
[x] [插入数据] [11] 2024-04-21 13:31:37
[x] [插入数据] [12] 2024-04-21 13:31:37
[x] [插入数据] [13] 2024-04-21 13:31:37
[x] [插入数据] [14] 2024-04-21 13:31:37
[x] [插入数据] [15] 2024-04-21 13:31:37

为什么要用sleep挂起协程实现切换呢?因为swoole的协程是自动的,当协程内遇上I/O操作(mysql,redis)等时,swoole的协程会自动切换,运行到下一个协程任务中(切换后,I/O继续执行),直到下一个协程任务完成或者被切换(遇上I/O),如此反复,直到所有协程任务完成,则任务完成。

MySQL 一键协程化

代码语言:javascript
复制
<?php

use function Swoole\Coroutine\run;
use function Swoole\Coroutine\go;

run(function () {
    go(function () {
        $pdo = new \PDO('mysql:host=192.168.3.29;port=3308;dbname=nacos;charset=utf8', 'root', '123456');
        $statement = $pdo->prepare('SELECT * FROM `users`');
        $statement->execute();
        var_dump($statement->fetchAll());
    });
    go(function () {
        $mysqli = new mysqli('192.168.3.29', 'root', '123456', 'webman-admin', 3308);
        $mysqli->set_charset('utf8mb4');
        var_dump($mysqli);
    });
});

执行结果

代码语言:javascript
复制
array(1) {
  [0]=>
  array(6) {
    ["username"]=>
    string(5) "nacos"
    [0]=>
    string(5) "nacos"
    ["password"]=>
    string(60) "$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu"
    [1]=>
    string(60) "$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu"
    ["enabled"]=>
    int(1)
    [2]=>
    int(1)
  }
}
object(mysqli)#6 (18) {
  ["affected_rows"]=>
  int(0)
  ["client_info"]=>
  string(14) "mysqlnd 8.2.17"
  ["client_version"]=>
  int(80217)
  ["connect_errno"]=>
  int(0)
  ["connect_error"]=>
  NULL
  ["errno"]=>
  int(0)
  ["error"]=>
  string(0) ""
  ["error_list"]=>
  array(0) {
  }
  ["field_count"]=>
  int(0)
  ["host_info"]=>
  string(23) "192.168.3.29 via TCP/IP"
  ["info"]=>
  NULL
  ["insert_id"]=>
  int(0)
  ["server_info"]=>
  string(6) "5.7.36"
  ["server_version"]=>
  int(50736)
  ["sqlstate"]=>
  string(5) "00000"
  ["protocol_version"]=>
  int(10)
  ["thread_id"]=>
  int(104)
  ["warning_count"]=>
  int(0)
}

致谢: 感谢 Workerman 和 Swoole 开发团队为 PHP 社区带来的创新和卓越贡献,让我们共同期待 PHP 在实时应用领域的更多突破。

参考

  • https://www.easyswoole.com/NoobCourse/coroutine.html
  • https://wiki.swoole.com/#/runtime
本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-04-22,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 开源技术小栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 使用
    • 开启swoole事件驱动
      • Docker 启动webman
        • swoole实现协程
        • 参考
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
        http://www.vxiaotou.com