# Swoole进程结构

Swoole的高效不仅仅于底层使用c编写，他的进程结构模型也使其可以高效的处理业务，我们想要深入学习，并且在实际的场景当中使用必须了解，下面我们先看一下结构图:

![](https://3149448975-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfnT31GMG1d9KiXwANW%2F-LfnT7UNILQRAFnaeTSW%2F-LfnTFMt0Ss8ZfTNZvqm%2F1.png?generation=1558862957100242\&alt=media)

首先先介绍下swoole的这几种进程分别是干什么的

从这些层级的名字，我们先大概说一下，下面这些层级分别是干什么的，做一个详细的说明。

* 1、Master进程：主进程
* 2、Manger进程：管理进程
* 3、Worker进程：工作进程
* 4、Task进程：异步任务工作进程

> Swoole的Reactor、Worker、TaskWorker之间可以紧密的结合起来，提供更高级的使用方式。
>
> 一个更通俗的比喻，假设Server就是一个工厂，那Reactor就是销售，接受客户订单。而Worker就是工人，当销售接到订单后，Worker去工作生产出客户要的东西。而TaskWorker可以理解为行政人员，可以帮助Worker干些杂事，让Worker专心工作。

## Master进程

第一层，Master进程，这个是swoole的主进程,这个进程是用于处理swoole的核心事件驱动的，那么在这个进程当中可以看到它拥有一个MainReactor\[线程]以及若干个Reactor\[线程]，swoole所有对于事件的监听都会在这些线程中实现，比如来自客户端的连接，信号处理等。

![](https://3149448975-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfnT31GMG1d9KiXwANW%2F-LfnT7UNILQRAFnaeTSW%2F-LfnTFMvfvPM2QwKvknE%2F2.png?generation=1558862957040308\&alt=media)

每一个线程都有自己的用途，下面多每个线程有一个了解

**1、MainReactor（主线程）**

主线程会负责监听server socket，如果有新的连接accept，主线程会评估每个Reactor线程的连接数量。将此连接分配给连接数最少的reactor线程，做一个负载均衡。

**2 、Reactor线程组**

Reactor线程负责维护客户端机器的TCP连接、处理网络IO、收发数据完全是异步非阻塞的模式。

swoole的主线程在Accept新的连接后，会将这个连接分配给一个固定的Reactor线程，在socket可读时读取数据，并进行协议解析，将请求投递到Worker进程。在socket可写时将数据发送给TCP客户端。

**3、心跳包检测线程（HeartbeatCheck）**

Swoole配置了心跳检测之后，心跳包线程会在固定时间内对所有之前在线的连接发送检测数据包

**4、UDP收包线程（UdpRecv）**

接收并且处理客户端udp数据包

## 管理进程Manager

Swoole想要实现最好的性能必须创建出多个工作进程帮助处理任务，但Worker进程就必须fork操作，但是fork操作是不安全的，如果没有管理会出现很多的僵尸进程，进而影响服务器性能，同时worker进程被误杀或者由于程序的原因会异常退出，为了保证服务的稳定性，需要重新创建worker进程。

Swoole在运行中会创建一个单独的管理进程，所有的worker进程和task进程都是从管理进程Fork出来的。管理进程会监视所有子进程的退出事件，当worker进程发生致命错误或者运行生命周期结束时，管理进程会回收此进程，并创建新的进程。换句话也就是说，对于worker、task进程的创建、回收等操作全权有“保姆”Manager进程进行管理。

再来一张图梳理下Manager进程和Worker/Task进程的关系。

## ![](https://3149448975-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfnT31GMG1d9KiXwANW%2F-LfnT7UNILQRAFnaeTSW%2F-LfnTFMxJ32qDqC-0Asi%2F3.png?generation=1558862969328160\&alt=media)

## Worker进程

worker 进程属于swoole的主逻辑进程，用户处理客户端的一系列请求，接受由Reactor线程投递的请求数据包，并执行PHP回调函数处理数据生成响应数据并发给Reactor线程，由Reactor线程发送给TCP客户端可以是异步非阻塞模式，也可以是同步阻塞模式

## Task进程

taskWorker进程这一进程是swoole提供的异步工作进程，这些进程主要用于处理一些耗时较长的同步任务，在worker进程当中投递过来。

## 进程查看

当启动一个Swoole应用时，一共会创建2 + n + m个进程，2为一个Master进程和一个Manager进程，其中n为Worker进程数。m为TaskWorker进程数。

默认如果不设置，swoole底层会根据当前机器有多少CPU核数，启动对应数量的Reactor线程和Worker进程。我机器为1核的。Worker为1。

所以现在默认我启动了1个Master进程，1个Manager进程，和1个worker进程，TaskWorker没有设置也就是为0，当前server会产生3个进程。

在启动了server之后，在命令行查看当前产生的进程

![](https://3149448975-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfnT31GMG1d9KiXwANW%2F-LfnT7UNILQRAFnaeTSW%2F-LfnTFMzEtLZbPDV_Bv2%2F4.png?generation=1558862960555820\&alt=media)

这三个进程中，所有进程的根进程，也就是例子中的2123进程，就是所谓的Master进程；而2212进程，则是Manager进程；最后的2321进程，是Worker进程。

## 流程梳理:

当请求到达时,swoole是这样处理的：

* 1、 client请求到达 Main Reactor,Client实际上是与Master进程中的某个Reactor线程发生了连接。
* 2、Main Reactor根据Reactor的情况，将请求注册给对应的Reactor (每个Reactor都有epoll。用来监听客户端的变化)&#x20;
* 3、客户端有变化时Reactor将数据交给worker来处理&#x20;
* 4、worker处理完毕，通过进程间通信(比如管道、共享内存、消息队列)发给对应的reactor。&#x20;
* 5、reactor将响应结果发给相应的连接请求处理完成

**流程示意图：**

## ![](https://3149448975-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfnT31GMG1d9KiXwANW%2F-LfnT7UNILQRAFnaeTSW%2F-LfnTFN0hvEl3YIogOnI%2F5.png?generation=1558862971588959\&alt=media) 进程的绑定事件

以下是一些进程的回调函数

**Master进程内的回调函数**

* onStart   Server启动在主进程的主线程回调此函数
* onShutdown  此事件在Server正常结束时发生

**Manager进程内的回调函数**

* onManagerStart 当管理进程启动时调用它
* onManagerStop  当管理进程结束时调用它
* onWorkerError  当worker/task\_worker进程发生异常后会在Manager进程内回调此函数

**Worker进程内的回调函数**

* onWorkerStart  此事件在Worker进程/Task进程启动时发生
* onWorkerStop    此事件在worker进程终止时发生。
* onConnect   有新的连接进入时，在worker进程中回调
* onClose   TCP客户端连接关闭后，在worker进程中回调此函数
* onReceive 接收到数据时回调此函数，发生在worker进程中
* onPacket 接收到UDP数据包时回调此函数，发生在worker进程中
* onFinish  当worker进程投递的任务在task\_worker中完成时，task进程会通过finish()方法将任务处理的结果发送给worker进程。
* onWorkerExit  仅在开启reload\_async特性后有效。异步重启特性
* onPipeMessage  当工作进程收到由 sendMessage 发送的管道消息时会触发事件

**Task进程内的回调函数**

* onTask   在task\_worker进程内被调用。worker进程可以使用swoole\_server\_task函数向task\_worker进程投递新的任务
* onWorkerStart  此事件在Worker进程/Task进程启动时发生
* onPipeMessage  当工作进程收到由 sendMessage 发送的管道消息时会触发事件

## 简单说明：

* 1、服务器关闭程序终止时最后一次事件是onShutdown。
* 2、服务器启动成功后，onStart/onManagerStart/onWorkerStart会在不同的进程内并发执
* 行，并不是顺序的。
* 3、所有事件回调均在$server->start后发生，start之后写的代码是无效代码。
* 4、onStart/onManagerStart/onWorkerStart 3个事件的执行顺序是不确定的


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://xiaoxiami.gitbook.io/swoole/gai-nian/swoolejin-cheng-jie-gou.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
