1.swoole是什么
swoole是php扩展,为php提供异步多线程服务器,异步tcp/UDP网络客户端,异步mysql,异步Redis,数据库连接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异步DNS查询,Swoole内置了HTTP/WEBSocket服务器端/客户端,HTTP2.0服务器端
2.swoole模型
swoole目前有三种运行模式 分别为 Base模式 线程模式,进程模式
Base模式是传统的异步非阻塞Server,reactor和worker是同一个角色。tcp连接是在worker进程中维持。如果客户度连接之间不需要交货,可以使用base模式。如Memcache、http服务器等
线程模式是多现实worker模式,Reactor线程来处理网络事件的轮训,读取数据,得到的请求交给worker线程去处理。但是他的缺点是当一个线程发生内存错误,整个进程会全部结束
进程模式与多线程worker模式不同的是,线程换成进程,Reactor线程来处理网络事件轮训,读取数据,得到的请求交给worker进程处理
3.进程模式的讲解
Master进程是一个多线程进程,其中有一组非常重要的线程,叫做Reactor、线程组,每当一个客户端连接上服务器的时候,都会由Master进程从已有的Reactor线程中,根据一定的规则挑选一个,专门负责向这个客户端提供维持链接,网络IO与收发数据等服务,分包拆包等功能也是在这里完成
Manager进程,某种意义上可以看做一个代理层,它本身并不直接处理业务,其主要工作室将Master进程中收到的数据转交给Worker进程,或者将Worker进程中希望发给客户端的数据转交给Master进程进行发送
Manager进程还复制监控worker进程,如果worker进程因为某些意外挂了,Manager进程会重新拉起新的worker进程,有点像Supervisor的工作。这个特性也是最终实现热重载的核心机制
worker进程其实就是处理各种业务工作的进程,Manager将数据包转交给Work进程,然后worker进程惊喜具体的处理,并根据实际情况将结果反馈给客户端
我们可以总结出来上面简单的Server,当客户端连接的时候这个过程中,三种进程之间是怎么协作的:
Client主动Connect的时候,Client实际上是与Master进程中的某个Reactor线程发生了连接。 当TCP的三次握手成功了以后,由这个Reactor线程将连接成功的消息告诉Manager进程,再由Manager进程转交给Worker进程。 在这个Worker进程中触发了OnConnect的方法。 当Client向Server发送了一个数据包的时候,首先收到数据包的是Reactor线程,同时Reactor线程会完成组包,再将组好的包交给Manager进程,由Manager进程转交给Worker。 此时Worker进程触发OnReceive事件。 如果在Worker进程中做了什么处理,然后再用Send方法将数据发回给客户端时,数据则会沿着这个路径逆流而上。
回调函数
Swoole作为Server时,回调函数有很多。但可以简单分个类:
1) 进程启动时执行的:onStart、onManagerStart、onWorkerStart;onWorkerStop、onManagerStop、onShutdown;onWorkerError
2) 客户端交互时触发的:onReceive/onRequest/onPacket/onMessage、onOpen/onConnect、onClose
3) Task:onTask、onFinish
4) Timer:onTimer
事件执行顺序: 所有事件回调均在$server->start后发生
服务器关闭程序终止时最后一次事件是onShutdown
服务器启动成功后,onStart/onManagerStart/onWorkerStart会在不同的进程内并发执行。 onReceive/onConnect/onClose/onTimer在worker进程(包括task进程)中各自触发 worker/task进程启动/结束时会分别调用onWorkerStart/onWorkerStop
onTask事件仅在task进程中发生 onFinish事件仅在worker进程中发生
onStart/onManagerStart/onWorkerStart 3个事件的执行顺序是不确定的
UDP协议下只有onReceive事件,没有onConnect/onClose事件 如果未设置onPacket回调函数,收到UDP数据包默认会回调onReceive函数 onOpen事件回调是可选的:当WebSocket客户端与服务器建立连接并完成握手后会回调此函数
swoole只能在cli模式下执行
我们可以通过shell_exec()函数去启动启动和热加载swoole