Swoole 的底层架构及原理特性

Swoole底层架构

Swoole 的底层架构及原理特性

Swoole 主要包含以下组件:

  • Master:当我们运行启动 Swoole 的 PHP 脚本时,首先会创建该进程(它是整个应用的 root 进程),然后由该进程 fork 出 Reactor 线程和 Manager 进程
  • Reactor:Reactor 是包含在 Master 进程中的多线程程序,用来处理 TCP 连接和数据收发(异步非阻塞方式)。Reactor 主线程在 Accept 新的连接后,会将这个连接分配给一个固定的 Reactor 线程,并由这个线程负责监听此 socket。在 socket 可读时读取数据,并进行协议解析,将请求投递到 Worker 进程;在 socket 可写时将数据发送给 TCP 客户端。
  • ManagerManager 进程负责 fork 并维护多个 Worker 子进程。当有 Worker 子进程中止时,Manager 负责回收并创建新的 Worker 子进程,以便保持 Worker 进程总数不变;当服务器关闭时,Manager 将发送信号给所有 Worker 子进程,通知其关闭服务。
  • Worker以多进程方式运行,每个子进程负责接受由 Reactor 线程投递的请求数据包,并执行 PHP 回调函数处理数据,然后生成响应数据并发给 Reactor 线程,由 Reactor 线程发送给 TCP 客户端。所有请求的处理逻辑都是在 Worker 子进程中完成,这是我们编写业务代码时真正要关心的部分。
  • Task Worker:功能和 Worker 进程类似,同样以多进程方式运行,但仅用于任务分发,当 Worker 进程将任务异步分发到任务队列时,Task Worker 负责从队列中消费这些任务(同步阻塞方式处理),处理完成后将结果返回给 Worker 进程。

php-fpm 和 Swoole 的主要区别

php在php-fpm中的生命周期

在传统的 php-fpm 中,php是没有web服务器的,需要借助 Nginx (Apache)来做为web服务器,然后 php-fpm 通过 Fastcgi 协议,接收 Nginx 传过来的请求,而 php-fpm 是 Master/Worker 运行模式,php-fpm 启动时,会常驻运行一个 Master 进程,来监听来自 Nginx的请求。当Master主进程收到来自 Nginx 的请求时候,就会fork多个Worker进程,来处理请求(每个Worker进程只能处理一个请求),一个Worker进程生命周期如下:

  1. 初始化模块
  2. 初始化请求(指初始php代码请求,不是http)
  3. 执行php脚本
  4. 结束请求
  5. 关闭模块

这也是PHP不适合高并发的根本原因,每处理一个http请求,PHP-FPM就会建立一个worker进程来处理,处理完请求在关闭,无论是建立或者销毁还是初始化,都会导致内存和cpu的消耗巨大(PHP是多进程的)

php在Swoole中的生命周期

在swoole中,接收一个http请求,是不需要借助Nignx这类第三方的web服务器,swoole会自已建立一个或者多个端口负责监听来处理请求,相当于swoole自已一个就做了Nginx+php-fpm的工作。

swoole采用的也是Master/Worker进程模式,不同的是Master进程下有多个Reactor线程,Master进程只负责监听Socket句柄的事件变化(类似监听对外开发的接口),而请求由Reactor线程接收和处理(处理TCP请求),并转发给Worker进程执行回调函数(PHP编写的代码),所以swoole启动的时候,需要常驻运行Master进程,启动过程如下:

  1. 初始化模块
  2. 初始化请求(与php-fpm不一样,php-fpm是每次请求都会初始化,而swoole只是启动的时候才初始化
  3. 执行PHP脚本(没有结束和关闭,Master进程会进入监听状态)
    swoole(或者是基于swoole开发的hyperf框架)都是由cli(命令行方式)运行的

对比总结

从上面比较不难看出,swoole和php-fpm的生命周期不一样。php-fpm每次接受请求都会执行一遍php代码,而swoole只会在启动的时候执行一次php代码的编译,所以在实际开发的时候,会发现传统的php-fpm在改php代码的时候,刷新网页http请求就能看到php代码的变化,但是swoole不会,swoole需要重新运行和编译才能看到代码的变化。

Swoole如何实现高并发

因为reactor基于epoll,所以每个reactor可以处理很多个连接请求。 如此,swoole就轻松的处理了高并发。

Swoole如何实现异步I/O

swoole的worker进程有2种类型:一种是普通的worker进程,一种是task worker进程。

  • worker进程是用来处理普通的耗时不是太长的请求;
  • task worker进程用来处理耗时较长的请求,比如数据库的I/O操作。

如此,通过worker、task worker结合的方式,我们就实现了异步I/O。

Swoole技术特点

  • 常驻内存,避免重复加载带来的性能损耗,提升海量性能;
  • 基于epoll,轻松支持高并发;
  • 协程异步I/O,提高对I/O密集型场景并发处理能力;
  • 支持多种通信协议,方便地开发 Http、WebSocket、TCP、UDP 等应用