资讯专栏INFORMATION COLUMN

swoole入门4-初识swoole

forsigner / 737人阅读

摘要:当某种网络事件发生时,会回调用户设置的指定回调函数。承担了底层网络事件的监听及各种底层事件处理,当收到请求时,会触发事件提醒,然后将控制权转交预先注册的事件回调函数,来进行后续的处理。请求到来时创建,请求结束后销毁。

运行流程图



当启动一个Swoole应用时,一共会创建2+n+m个进程,2为一个Master进程和一个Manager进程,其中n为Worker进程数,m为TaskWorker进程数。
名词解释 Master进程
主进程,该进程会创建Manager进程、Reactor线程,UDP收包线程,心跳检测线程等线程
Manger进程
管理进程,该进程的作用是创建、管理所有的Worker进程和TaskWorker进程。

子进程结束运行时,manager进程负责回收此子进程,避免成为僵尸进程。并创建新的子进程

服务器关闭时,manager进程将发送信号给所有子进程,通知子进程关闭服务

服务器reload时,manager进程会逐个关闭/重启子进程

Worker进程
工作进程,所有的业务逻辑代码均在此进程上运行。当Reactor线程接收到来自客户端的数据后,会将数据打包通过管道发送给某个Worker进程。

接受由Reactor线程投递的请求数据包,并执行PHP回调函数处理数据

生成响应数据并发给Reactor线程,由Reactor线程发送给TCP客户端

可以是异步非阻塞模式,也可以是同步阻塞模式

Worker以多进程的方式运行

TaskWorker进程
一种特殊的工作进程,该进程的作用是处理一些耗时较长的任务,以达到释放Worker进程的目的。

接受由Worker进程通过swoole_server->task/taskwait方法投递的任务

处理任务,并将结果数据返回(使用swoole_server->finish)给Worker进程

完全是同步阻塞模式

TaskWorker以多进程的方式运行

Reactor线程
实际运行Linux中是epoll实例,MacOS中为Kqueue实例,用于accept客户端连接以及接收客户端数据。

Swoole的主进程是一个多线程的程序。其中有一组很重要的线程,称之为Reactor线程。它就是真正处理TCP连接,收发数据的线程。

Swoole的主线程在Accept新的连接后,会将这个连接分配给一个固定的Reactor线程,并由这个线程负责监听此socket。

在socket可读时读取数据,并进行协议解析,将请求投递到Worker进程。在socket可写时将数据发送给TCP客户端。

负责维护客户端TCP连接、处理网络IO、处理协议、收发数据

完全是异步非阻塞的模式

全部为C代码,除Start/Shudown事件回调外,不执行任何PHP代码

将TCP客户端发来的数据缓冲、拼接、拆分成完整的一个请求数据包

Reactor以多线程的方式运行

运行机制
Swoole是php的扩展,一旦运行后就会接管PHP的控制权,进入事件循环。 

当某种IO(网络IO)事件发生时,Swoole 会回调用户设置的指定回调函数。
    
Swoole承担了底层网络事件的监听及各种底层事件处理,当收到请求时,会触发事件提醒,然后将控制权转交预先注册的事件回调函数,来进行后续的处理。

可以理解为Reactor就是nginx,Worker就是php-fpm。Reactor线程异步并行地处理网络请求,然后再转发给Worker进程中去处理。Reactor和Worker间通过UnixSocket进行通信。

Swoole提供的TaskWorker是一套更完整的方案,将任务的投递、队列、php任务处理进程管理合为一体。通过底层提供的API可以非常简单地实现异步任务的处理。

另外TaskWorker还可以在任务执行完成后,再返回一个结果反馈到Worker。

Swoole的Reactor、Worker、TaskWorker之间可以紧密的结合起来,提供更高级的使用方式。

一个更通俗的比喻,假设Server就是一个工厂,Master是董事长,Manager是CEO,那Reactor就是销售经理,接受客户订单。而Worker就是工人,当销售接到订单后,Worker去工作生产出客户要的东西。

而TaskWorker可以理解为行政人员,可以帮助Worker干些杂事,让Worker专心工作。
所谓的回调函数(CallBack) 就好比是张开了夹子的捕鼠器,我们设定当有老鼠踩到捕鼠器的时候,他会关闭夹子然后捉住老鼠,我们放置捕鼠器的时候,捕鼠器并没有真的抓老鼠。这个设定就是回调,他不立刻执行,会在遇到触发条件(事件)时执行,在上面的示例当中我们放置了3个捕鼠器(回调函数),我们只需要知道他会在特定老鼠(事件)踩到的时候(发生的时候)去执行我们期望的功能就好。

底层会为Worker进程、TaskWorker进程分配一个唯一的ID

不同的Worker和TaskWorker进程之间可以通过sendMessage接口进行通信

运行周期 程序全局期
 在swoole_server->start之前就创建好的对象,我们称之为程序全局生命周期。
 
 这些变量在程序启动后就会一直存在,直到整个程序结束运行才会销毁。
 
 有一些服务器程序可能会连续运行数月甚至数年才会关闭/重启,那么程序全局期的对象在这段时间持续驻留在内存中的。
 
 程序全局对象所占用的内存是Worker进程间共享的,不会额外占用内存。
 
 这部分内存会在写时分离(COW),在Worker进程内对这些对象进行写操作时,会自动从共享内存中分离,变为进程全局对象。
 
 程序全局期include/require的代码,必须在整个程序shutdown时才会释放,reload无效。
进程全局期
 swoole拥有进程生命周期控制的机制,一个Worker子进程处理的请求数超过max_request配置后,就会自动销毁。
 
 Worker进程启动后创建的对象(onWorkerStart中创建的对象),在这个子进程存活周期之内,是常驻内存的。
 
 onConnect/onReceive/onClose 中都可以去访问它。
 
 进程全局对象所占用的内存是在当前子进程内存堆的,并非共享内存。对此对象的修改仅在当前Worker进程中有效。
 
 进程期include/require的文件,在reload后就会重新加载。
 
会话期
 会话期是在onConnect后创建,或者在第一次onReceive时创建,onClose时销毁。一个客户端连接进入后,创建的对象会常驻内存,直到此客户端离开才会销毁。
 
 swoole中会话期的对象直接是常驻内存,不需要session_start之类操作。
 
 可以直接访问对象,并执行对象的方法。
 
请求期
 请求期就是指一个完整的请求发来,也就是onReceive收到请求开始处理,直到返回结果发送response。
 
 这个周期所创建的对象,会在请求完成后销毁。
 
 swoole中请求期对象与普通PHP程序中的对象就是一样的。
 
 请求到来时创建,请求结束后销毁。
4种PHP回调函数风格 匿名函数
$server->on("Request", function ($req, $resp) use ($a, $b, $c) {
       echo "hello world";
});
可使用use向匿名函数传递参数
类静态方法
class A
{
    static function test($req, $resp)
    {
        echo "hello world";
    }
}
$server->on("Request", "A::Test");
$server->on("Request", array("A", "Test"));
对象方法
class A
{
    function test($req, $resp)
    {
        echo "hello world";
    }
}

$object = new A();
$server->on("Request", array($object, "test"));
函数
function my_onRequest($req, $resp)
{
    echo "hello world";
}
$server->on("Request", "my_onRequest");
编程须知 注意事项

不要在代码中执行sleep以及其他睡眠函数,这样会导致整个进程阻塞

在swoole程序中禁止使用exit/die,如果PHP代码中有exit/die,当前工作的Worker进程、Task进程、User进程、以及swoole_process进程会立即退出。使用exit/die后Worker进程会因为异常退出, 被master进程再次拉起, 最终造成进程不断退出又不断启动和产生大量警报日志。

mt_rand随机数,在Swoole中如果在父进程内调用了mt_rand,不同的子进程内再调用mt_rand返回的结果会是相同的。所以必须在每个子进程内调用mt_srand重新播种。

while循环的影响,异步程序如果遇到死循环,事件将无法触发。异步IO程序使用Reactor模型,运行过程中必须在reactor->wait处轮询。如果遇到死循环,那么程序的控制权就在while中了,reactor无法得到控制权,无法检测事件,所以IO事件回调函数也将无法触发。

可通过register_shutdown_function来捕获致命错误,在进程异常退出时做一些清理工作

PHP代码中如果有异常抛出,必须在回调函数中进行try/catch捕获异常,否则会导致工作进程退出

不支持set_exception_handler,必须使用try/catch方式处理异常

Worker进程不得共用同一个Redis或MySQL等网络服务客户端,Redis/MySQL创建连接的相关代码可以放到onWorkerStart回调函数中。

异步编程

异步程序要求代码中不得包含任何同步阻塞操作

异步与同步代码不能混用,一旦应用程序使用了任何同步阻塞的代码,程序即退化为同步模式

类/函数重复定义
 新手非常容易犯这个错误,由于Swoole是常驻内存的,所以加载类/函数定义的文件后不会释放。因此引入类/函数的php文件时必须要使用include_once或require_once,否会发生cannot redeclare function/class 的致命错误。
进程隔离
 进程隔离也是很多新手经常遇到的问题。修改了全局变量的值,为什么不生效,原因就是全局变量在不同的进程,内存空间是隔离的,所以无效。所以使用Swoole开发Server程序需要了解进程隔离问题。

不同的进程中PHP变量不是共享,即使是全局变量,在A进程内修改了它的值,在B进程内是无效的

如果需要在不同的Worker进程内共享数据,可以用Redis、MySQL、文件、SwooleTable、APCu、shmget等工具实现

不同进程的文件句柄是隔离的,所以在A进程创建的Socket连接或打开的文件,在B进程内是无效,即使是将它的fd发送到B进程也是不可用的

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/29731.html

相关文章

  • 初识 swoole【上】

    摘要:前言都是为了生存有收获的话请加颗小星星,没有收获的话可以反对没有帮助举报三连代码仓库初始上一什么是面向生产环境的异步网络通信引擎使开发人员可以编写高性能的异步并发,服务。 前言:都是为了生存 有收获的话请加颗小星星,没有收获的话可以 反对 没有帮助 举报三连 代码仓库 初始swoole【上】 一、什么是swoole Swoole:面向生产环境的 PHP 异步网络通信引擎 使 PHP...

    scola666 评论0 收藏0
  • Swoole学习手记(一)初识Swoole

    摘要:目录初识创建服务器上创建服务器下异步任务持续更新中。。。参加工作有一段时间了,偶尔会听到,对我这种小白粗略看下文档都会觉得很牛逼。个人理解就是解决这样应用场景的。 目录 初识Swoole 创建服务器(上) 创建服务器(下) 异步任务task 持续更新中。。。 参加工作有一段时间了,偶尔会听到swoole,对我这种PHP小白粗略看下文档都会觉得很牛逼。由于学习成本比较高,自身对网络异...

    yeyan1996 评论0 收藏0
  • 初识 swoole【下】

    摘要:前言接初识上,这篇主要是异步问题有收获的话请加颗小星星,没有收获的话可以反对没有帮助举报三连代码仓库初识下异步任务设置异步任务的工作进程数量连接连接欢迎大山驴回调投递异步任务触发异步任务服务端回复说处理异步任务新的异步任务 前言:接初识swoole【上】,这篇主要是异步问题 有收获的话请加颗小星星,没有收获的话可以 反对 没有帮助 举报三连 代码仓库 初识swoole【下】 6、异...

    yeooo 评论0 收藏0
  • 实战 swoole【聊天室】

    摘要:是一个请求对象,包含了客户端发来的握手请求信息事件函数中可以调用向客户端发送数据或者调用关闭连接事件回调是可选的当服务器收到来自客户端的数据帧时会回调此函数。 前言:了解概念之后就应该练练手啦,不然就是巨婴 有收获的话请加颗小星星,没有收获的话可以 反对 没有帮助 举报三连 代码仓库 实战swoole【聊天室】 在线体验 准备工作 需要先看初识swoole【上】,了解基本的服务端...

    andycall 评论0 收藏0
  • swoole入门3-swoole开发环境搭建

    摘要:安装命令环境下必须关闭选项需要修改关闭在下开发可以使用来方便的开发应用,安装好后再里的选项里共享代码所在磁盘。为源码所在路径为容器内路径在里执行编译安装扩展是按照标准扩展构建的。 环境依赖 仅支持 Linux、FreeBSD、MacOS 三种操作系统 在Windows平台,可使用CygWin或WSL(Windows Subsystem for Linux) Linux 内核版本 2....

    jerryloveemily 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<