"/>
·设为首页收藏本站📧邮箱修改🎁免费下载专区💎积分✅卡密📒收藏夹👽聊天室
DZ插件网 门户 站长圈 查看内容

Swoole的底层架构和实现原理

2022-3-7 05:40| 发布者: admin| 查看: 243| 评论: 0|原作者: 架构师学习路线

摘要: SUMMERSwoole的底层架构首先我们来看下Swoole的底层架构:通过上图我们可以看到,Swoole主要包含以下组件:Master:整个...

点击蓝字 ╱ 关注我们

SUMMER

Swoole 的底层架构

首先我们来看下 Swoole 的底层架构:
通过上图我们可以看到,Swoole 主要包含以下组件:
Master:整个应用的 root 进程
当我们运行启动 Swoole 的 PHP 脚本时,首先会创建该进程,然后由该进程 fork 出 Reactor 线程和 Manager 进程。

Reactor:包含在 Master 进程中的多线程程序
Reactor 是用来处理 TCP 连接和数据收发(异步非阻塞方式)的程序 。Reactor 主线程在 Accept 新的连接后,会将这个连接分配给一个固定的 Reactor 线程,并由这个线程负责监听此 socket。在 socket 可读时读取数据,并进行协议解析,将请求投递到 Worker 进程;在 socket 可写时将数据发送给 TCP 客户端。

Manager:负责 fork 并维护多个 Worker 子进程
当有 Worker 子进程中止时,Manager 负责回收并创建新的 Worker 子进程,以便保持 Worker 进程总数不变;当服务器关闭时,Manager 将发送信号给所有 Worker 子进程,通知其关闭服务。

Worker:编写业务代码时真正要关心的部分
以多进程方式运行,每个子进程负责接受由 Reactor 线程投递的请求数据包,并执行 PHP 回调函数处理数据,然后生成响应数据并发给 Reactor 线程,由 Reactor 线程发送给 TCP 客户端。所有请求的处理逻辑都是在 Worker 子进程中完成。

Task Worker:
功能和 Worker 进程类似,同样以多进程方式运行,但仅用于任务分发,当 Worker 进程将任务异步分发到任务队列时,Task Worker 负责从队列中消费这些任务(同步阻塞方式处理),处理完成后将结果返回给 Worker 进程。
Swoole 官方对 Reactor、Worker、Task Worker有一个形象的比喻,如果把基于 Swoole 的 Web 服务器比作一个工厂,那么 Reactor 就是这个工厂的销售员,Worker 是负责生产的工人,销售员负责接订单,然后交给工人生产,而 Task Worker 可以理解为行政人员,负责提工人处理生产以外的杂事,比如订盒饭、收快递,让工人可以安心生产。

底层实现原理

我们以 MySQL 连接查询为例,对 Swoole 协程底层实现做一个简单的介绍:
$server = new Swoole\Http\Server('127.0.0.1', 9501, SWOOLE_BASE);
#1$server->on('Request', function($request, $response) { $mysql = new Swoole\Coroutine\MySQL(); #2 $res = $mysql->connect([ 'host' => '127.0.0.1', 'user' => 'root', 'password' => 'root', 'database' => 'test', ]); #3 if ($res == false) { $response->end("MySQL connect fail!"); return; } $ret = $mysql->query('show tables', 2); $response->end("swoole response is ok, result=".var_export($ret, true));});
$server->start();
在这段代码中,我们启动一个基于 Swoole 实现的 HTTP 服务器监听客户端请求,如果有 onRequest 事件发生,则通过基于 Swoole 协程实现的异步 MySQL 客户端组件对 MySQL 服务器发起连接请求,并执行查询操作,然后将结果以响应方式返回给 HTTP 客户端,下面我们来看一下协程在这段代码中的应用:
  • 调用 Swoole\Http\Server 的 onRequest 事件回调函数时,底层会调用 C 函数 coro_create创建一个协程(#1位置),同时保存这个时间点的 CPU 寄存器状态和 ZendVM 堆栈信息;

  • 调用 mysql->connect 时会发生 IO 操作,底层会调用 C 函数 coro_save 保存当前协程的状态,包括 ZendVM 上下文以及协程描述信息,并调用 coro_yield 让出程序控制权,当前的请求会挂起(#2位置);

  • 协程让出程序控制权后,会继续进入 HTTP 服务器的事件循环处理其他事件,这时 Swoole 可以继续去处理其他客户端发来的请求;

  • 当数据库 IO 事件完成后,MySQL 连接成功或失败,底层调用 C 函数 coro_resume 恢复对应的协程,恢复 ZendVM 上下文,继续向下执行 PHP 代码(#3位置);

  • mysql->query 的执行过程与 mysql->connect 一样,也会触发 IO 事件并进行一次协程切换调度;

  • 所有操作完成后,调用 end 方法返回结果,并销毁此协程。

上面这段代码我们借助了 Swoole 实现的协程 MySQL 客户端(Swoole 还提供了很多其他协程客户端,如 Redis、HTTP等,后面我们会详细介绍),所有的编码和之前编写同步代码时并没有任何不同,但是 Swoole 底层会在 IO 事件发生时,保存当前状态,将程序控制权交出,以便 CPU 处理其它事件,当 IO 事件完成时恢复并继续执行后续逻辑,从而实现异步 IO 的功能,这正是协程的强大之处,它可以让服务器同时可以处理更多请求,而不会阻塞在这里等待 IO 事件处理完成,从而极大提高系统的并发性。
*声明:本文于网络整理,版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜


上一篇:致用户,微擎8年,我们初心未变
下一篇:原创|java安全-java类加载器

鲜花

握手

雷人

路过

鸡蛋

评论

您需要登录后才可以发表言论 登录立即注册
创宇盾启航版免费网站防御网站加速服务
投诉/建议联系

discuzaddons@vip.qq.com

未经授权禁止转载,复制和建立镜像,
如有违反,按照公告处理!!!
  • 联系QQ客服
  • 添加微信客服

联系DZ插件网微信客服|最近更新|Archiver|手机版|小黑屋|DZ插件网! ( 鄂ICP备20010621号-1 )|网站地图 知道创宇云防御

您的IP:18.119.248.214,GMT+8, 2024-11-23 17:00 , Processed in 0.257492 second(s), 57 queries , Gzip On, Redis On.

Powered by Discuz! X5.0 Licensed

© 2001-2024 Discuz! Team.

关灯
扫一扫添加微信客服
QQ客服返回顶部
返回顶部