swoole| swoole 协程知识点小结

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: 本文要点:- swoole 协程现状一览: 学不动? 其实是更简单了- 使用 swoole 协程很简单: 开个协程, 协程里写非阻塞代码- 展望 swoole 协程未来

本文要点:

  • swoole 协程现状一览: 学不动? 其实是更简单了
  • 使用 swoole 协程很简单: 开个协程, 协程里写非阻塞代码
  • 展望 swoole 协程未来

swoole 协程现状一览

swoole 一直保持着 颇为快速 的迭代速度, 快到什么程度呢 -- 「快别更新了, 学不动了」

  • 半年前还是 v4.0 支持完整的协程编程(CSP, go+chan), 现在已经迭代到 v4.3.3
  • v4.3 版本做了一次大更新, 项目拆分成了 swooleswoole_async
  • 官方 wiki 修改了很多, 协程的部分的文档增加了不少, 而且提前到更加显眼的地方
来一句灵魂叩问: 改动这么大, 那是不是真的 「学不动了」?

并不是! swoole 是一直在为 世界上最好的语言 添砖加瓦:

  • 更为完整的协程编程支持, 直观的效果是更加 无缝无感 的编程切换体验(后面细说), 意味着需要了解和注意的语法细节更少, 编程更轻松
  • v4.3 版本做的一次大更新, 实际是优化 swoole 项目的架构, 主项目 focus 协程模式的网络编程, 更多网络编程相关的功能, 使用 扩展(ext) 的方式提供(具体可以参考 swoole 的 github 主页: https://github.com/swoole, 扫一眼下面有的项目, 就能有所启发)
  • 官方 wiki 一直以信息量著称(同时也意味着 可以学到很多东西), 但是如果具备了 网络编程 + 协程 的基础知识, 然后 focus 到swoole 协程部分文档 上, 就会发现其实都是一些 编程语法, so easy~

使用 swole 协程

如何使用协程:

  • 使用 go()(\Swoole\Coroutine::create() 的简写) 创建一个协程
  • 在 go() 的回调函数中, 加入协程需要执行的代码, 注意是 非阻塞代码
use Swoole\Coroutine as Co; // 常用的缩写方式

go(function () { // 创建协程, 回调函数中写需要在协程中执行的代码
    echo "daydaygo";
    Co::sleep(1); // 不能是阻塞代码
});
swoole 中协程就是这么简单: 开个协程, 协程里写非阻塞代码. 官方协程部分文档看起来很多, 牢记这两点, 其实很简单!

开协程

  • 上文提到的, 使用 go() 创建一个协程
  • swoole server 中, 底层自动在 onRequet, onReceive, onConnect 等事件回调之前自动创建一个协程

  • 使用 task_enable_coroutine 开启的协程版 Task 进程, 会在 onTask 回调之前自动创建一个协程
  • 进程和进程池支持开启协程, 开启后创建的子进程会自动创建协程
// tcp/udp server, 可以在此基础可封装 rpc
$s = new \Swoole\Server();

// http server, 替代传统的 fpm
$s = new \Swoole\Http\Server();

// 开启 http2 支持: https://wiki.swoole.com/wiki/page/326.html
$s = new \Swoole\Http\Server();
$s->set([
    'open_http2_protocol' => true,
]);
// 进而可以实现基于 http2 的服务, 比如 grpc

// websocket server
$s = new \Swoole\WebSocket\Server();

非阻塞代码

协程中必须编写 非阻塞代码, 看到上面 Co::sleep(1) 的小伙伴会有疑问了:

连个 sleep 都要 swoole 提供一个协程版, 我得掌握多少 swoole 协程版 API 才够呀?

所以问题的关键点来了:

  • 协程中一定要使用 非阻塞代码(一定要牢记, 多次重复了, 可以心里再默念三遍)
  • 怎么区分哪些是阻塞的, 哪些是非阻塞的: 可以参考 官方wiki - runtime
  • 随着 swoole 的迭代, 对协程的支持越来越完整, 区分哪些阻塞, 哪些非阻塞, 越来越无感

swoole 更新后, 添加了开启协程 runtime 功能:

// 没有开启协程 runtime, 需要协程版 API
use Swoole\Coroutine as Co;

go(function () {
    echo "daydaygo";
    Co::sleep(1); // 需要使用 swoole 提供的协程版 API
});

// 开启协程 runtime
\Swoole\Runtime::enableCoroutine();
go(function () {
    echo "daydaygo";
    sleep(1); // 和原来编程一样了
});

协程 runtime 开启后, 支持的列表:

  • redis扩展
  • 使用mysqlnd模式的pdo、mysqli扩展,如果未启用mysqlnd将不支持协程化
  • soap扩展
  • file_get_contents、fopen
  • stream_socket_client (predis)
  • stream_socket_server
  • stream_select(需要4.3.2以上版本)
  • fsockopen
  • 文件操作底层使用 AIO 线程池模拟实现

    • fopen / fclose
    • fread / fwrite
    • fgets / fputs
    • file_get_contents / file_put_contents
    • unlink / mkdir / rmdir
  • sleep系列函数

    • sleep / usleep
    • time_nanosleep / time_sleep_until

不支持的列表:

  • mysql:底层使用libmysqlclient
  • curl:底层使用libcurl (即不能使用CURL驱动的Guzzle)
  • mongo:底层使用mongo-c-client
  • pdo_pgsql / pdo_ori / pdo_odbc / pdo_firebird

协程 runtime 还不支持怎么办

需要的功能协程 runtime 下还没支持怎么办? 你有三种方法:

  • 协程 runtime 之前, 官方和社区已经贡献了很多协程版 API 可供使用, 比如上面 Co::sleep(1), PostgreSQL Client Swoole\Coroutine\PostgreSQL
  • 官方和社区没有, 可以使用 swoole 提供的协程版 client 进行封装, 可以参考 官方 amqp client 封装, 将 socket() 函数实现的 tcp client, 使用 swoole 协程版 tcp client 实现即可
public function connect()
{
    // 使用 Swoole\Coroutine\Client 
    $sock = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP);
    if (!$sock->connect($this->host, $this->port, $this->connection_timeout))
    {
        throw new AMQPRuntimeException(
            sprintf(
                'Error Connecting to server(%s): %s ',
                $sock->errCode,
                swoole_strerror($sock->errCode)
            ),
            $sock->errCode
        );
    }
    $this->sock = $sock;
}

PS: 这里只是抛砖引玉, 原库中使用 stream_socket_client(), 现在 swoole 协程 runtime 已经支持了

  • 传统的阻塞解决方案(当然是在现有的协程方式都不行, 才会继续使用传统的方式): 抛给 swoole 的 task 进程, 使用 MQ 异步掉, 等等

展望 swoole 协程的未来

到目前为止, 希望小伙伴们已经 get 到了 swoole 中协程编程的要点(我喜欢用 姿势, 人最紧要的是姿势好看~), 让我们展望一下未来:

  • 解锁更多协程使用: chan, defer, select, waitgroup, 这些官方都提供了 demo( 韩天峰 - PHP 协程:Go + Chan + Defer), 看完后自己也能封装一份
  • 并不是 完整(100%, one hundred percent) 的支持, 要是一不小心踩到不支持的怎么办? swoole 的后续版本将支持检测协程环境下是否有阻塞调用
  • 随着 swoole 官方在协程编程上的持续发力, 基于 swoole 实现的全协程式 PHP 开发框架也将更为简单, 从基础/底层的网络编程到整个微服务架构的道路也将更为平坦, 比如马上将要迎来大版本升级的 swoft2

写在最后

官方协程部分的文档看起来多, 其实多是对协程 API 的介绍, 并没有在知识结构理解的复杂度上有所增加. swoole 中协程的编程语法, 都在 \Swoole\Coroutine 命名空间下可以找到.

最后回到一个经典问题, 学习 swoole 的协程好, 还是学习 go 的协程好? 我谈谈我个人的观点:

  • 所需要的基础知识: 网络编程 + 协程, 不会因为你是用 swoole 还是 go 而有所减少, 基础不大好, 表现出来了就是学着学着就容易卡住, 效率上不来
  • 以为你写的是 swoole, 不不不, 写的是一个又一个功能的 API, go 也同样(要用到 redis/mysql/mq, 相应的 API 你还是得学得会), 区别在于, swoole 趋势是在底层实现支持(比如 协程runtime), 这样 PHPer 可以无缝切换过来, 而 Gopher 则需要学习一个又一个基于 go 协程封装好的 API. 当初在 PHP 中学习的这些 API, 到 go 里面, 一样需要再熟悉一遍
  • 最后来谈谈性能, 请允许我用一个傲娇一点的说, 你用 swoole 达不到的性能, 换个语言, 呵呵呵. 难易程度排行: 加机器 < 加程序员 < 加语言.
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
目录
相关文章
|
存储 消息中间件 监控
Pulsar 介绍与部署
Pulsar 介绍与部署
4636 0
Pulsar 介绍与部署
|
9月前
|
程序员 API 调度
iOS|解决 setBrightness 调节屏幕亮度不生效的问题
在包含视频播放功能的 App 中,一种常见的交互是在播放器界面的左侧上下滑动调节屏幕亮度,右侧上下滑动调节音量。我们的 iOS App 里也是这样设计的,但最近在测试过程中,发现亮度调节不生效了。
371 76
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
4991 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
开发框架 前端开发 小程序
跨平台开发框架的选择应该考虑哪些因素?
【10月更文挑战第25天】综合考虑以上因素,能够帮助您更准确地选择适合项目需求的跨平台开发框架,从而提高项目的成功率和开发效率,为用户提供更好的应用体验。
|
存储 编解码 网络协议
阿里云目前活动中各实例规格性能、指标数据、适用场景及选择参考
很多新手用户初次通过阿里云各种活动购买云服务器的时候,面对各种不同的实例规格,往往不知道应该怎么选,目前在阿里云的活动中,除了轻量应用服务器之外,活动内的云服务器实例规格主要以经济型e、通用算力型u1、计算型c7/c8y、通用型g7/g8y、内存型r7/r8y这几个实例规格为主,不同的云服务器实例规格在性能特点、适用场景等方面均有所差异。本文将详细介绍阿里云目前活动中常见的实例规格及其性能特点、适用场景,帮助用户更好地选择适合自己的云服务器配置。
阿里云目前活动中各实例规格性能、指标数据、适用场景及选择参考
|
XML 资源调度 网络协议
大数据-02-Hadoop集群 XML配置 超详细 core-site.xml hdfs-site.xml 3节点云服务器 2C4G HDFS Yarn MapRedece(二)
大数据-02-Hadoop集群 XML配置 超详细 core-site.xml hdfs-site.xml 3节点云服务器 2C4G HDFS Yarn MapRedece(二)
546 4
|
机器学习/深度学习 人工智能 分布式计算
构建基于AI的游戏AI系统:技术详解与实现
【6月更文挑战第4天】本文探讨了构建基于AI的游戏AI系统的详细过程,包括技术选型(如机器学习、深度学习、强化学习)、系统设计(感知层、决策层和执行层)、实现步骤(数据收集、模型训练、评估与优化)和优化策略(实时更新、多代理协同、迁移学习、持续学习)。通过合理选择技术和策略,可以创建高性能、适应性强的游戏AI系统,提升游戏体验并推动创新。
1059 3
|
机器学习/深度学习 Python
音频去噪:使用Python和FFT增强音质
声音去噪目标是改善聆听体验以及音频分析和处理的准确性。过滤掉噪音对于高保真音频来说非常重要,不仅是为了聆听,也是为了创建某些机器学习任务的数据集。
478 0
音频去噪:使用Python和FFT增强音质
|
存储 消息中间件 分布式计算
大数据-137 - ClickHouse 集群 表引擎详解2 - MergeTree 存储结构 一级索引 跳数索引
大数据-137 - ClickHouse 集群 表引擎详解2 - MergeTree 存储结构 一级索引 跳数索引
199 0
|
监控 小程序
利用PowerShell写的一个CPU监控小程序
业务部门需要,所以写的一个CPU监控小程序,有窗口显示,同时会在当前目录生成日志,有需要的自取,复制代码,TXT另存为xx.ps1即可。 仅供学习交流。
373 0