多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
`Master`进程是一个多线程进程,其中有一组非常重要的线程,叫做`Reactor`线程(组),每当一个客户端连接上服务器的时候,都会由Master进程从已有的Reactor线程中,根据一定规则挑选一个,专门负责向这个客户端提供维持链接、处理网络IO与收发数据等服务。分包拆包等功能也是在这里完成。 `Manager`进程,某种意义上可以看做一个代理层,它本身并不直接处理业务,其主要工作是将Master进程中收到的数据转交给Worker进程,或者将Worker进程中希望发给客户端的数据转交给Master进程进行发送。 `Manager`进程还负责监控Worker进程,如果Worker进程因为某些意外挂了,Manager进程会重新拉起新的Worker进程,有点像Supervisor的工作。而这个特性,也是最终实现热重载的核心机制。 `Worker`进程其实就是处理各种业务工作的进程,Manager将数据包转交给Worker进程,然后Worker进程进行具体的处理,并根据实际情况将结果反馈给客户端。 我们可以总结出来上面简单的Server,当客户端连接的时候这个过程中,三种进程之间是怎么协作的: 1. Client主动Connect的时候,Client实际上是与Master进程中的某个Reactor线程发生了连接。 2. 当TCP的三次握手成功了以后,由这个Reactor线程将连接成功的消息告诉Manager进程,再由Manager进程转交给Worker进程。 3. 在这个Worker进程中触发了OnConnect的方法。 4. 当Client向Server发送了一个数据包的时候,首先收到数据包的是Reactor线程,同时Reactor线程会完成组包,再将组好的包交给Manager进程,由Manager进程转交给Worker。 5. 此时Worker进程触发OnReceive事件。 6. 如果在Worker进程中做了什么处理,然后再用Send方法将数据发回给客户端时,数据则会沿着这个路径逆流而上。 Swoole进程/线程结构图: ![](https://wiki.swoole.com/static/image/process.jpg) 现在,我们基于上面的例子修改代码,来看看一个简单的多进程Swoole Server的几个基本配置: ``` php <?php $server->set(array( 'demonize' => false,//是否后台运行 'reactor_num' => 2, 'worker_num' => 4 )); $server -> start(); ``` `reactor_num`:表示Master进程中,Reactor线程总共开多少个,注意,这个可不是越多越好,因为计算机的CPU是有限的,所以一般设置为与CPU核心数量相同,或者两倍即可。 `worker_num`:表示启动多少个Worker进程,同样,Worker进程数量不是越多越好,仍然设置为与CPU核心数量相同,或者两倍即可。 我们可以在Shell里运行,使用pstree查看进程模型结构: ``` php swoole_tcp_server.php pstree -ap|grep swoole_tcp | | `-php,2505 swoole_tcp_server.php | | |-php,2507 swoole_tcp_server.php | | | |-php,2510 swoole_tcp_server.php | | | |-php,2511 swoole_tcp_server.php | | | |-php,2512 swoole_tcp_server.php | | | `-php,2513 swoole_tcp_server.php ```