二十六、Swoole 基础学习笔记 - Swoole Process\Pool 进程池

作者: 温新

分类: 【Swoole 系列】

阅读: 922

时间: 2023-03-13 11:59:18

hi,我是温新,一名PHPer

文章基于 Swoole 5.0.1 版本编写。

学习目标:学习 Process\Pool 多进程的使用

说明:本篇文章结合官方文档编写及参考网络资料编写,虽非全部原创,但也是结合了自己的理解,若转载请附带本文 URL,编写不易,持续编写更不易,谢谢!

Process\Pool

Swoole 提供的进程池为 Process\Pool,进程池是基于 Swoole\Server 的 Manager 管理进程模块实现。可以管理多个工作进程。该模块的核心功能为进程管理,相比于 Process 实现的多进程,Process\Pool 更加简单,封装层次更高,开发者无需编写过多代码即可实现进程管理功能,配合 Co\Server 可以创建纯协程风格的,能利用多核 CPU 的服务端程序。

在实现开发中,一些需要长期运行的脚本,如基于 redis、kafka、rabbitmq 实现的多进程队列消费者,多进程爬虫等等。

创建进程池

通过一个案例快速了解进程池

<span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important"><?</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">php</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">// 26-swoole-process-pool-1.php</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">// 实例进程池对象</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$pool</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span> <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">new</span> <span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">Swoole\Process\Pool</span>(<span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">3</span>);</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">// 监听子进程启动</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$pool</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">on</span>(<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'WorkerStart'</span>, <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">function</span> (<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$pool</span>, <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$workerId</span>) {</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">while</span> (<span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">true</span>) {</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    }</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">});</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">// 监听子进程终止</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$pool</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">on</span>(<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'WorkerStop'</span>, <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">function</span> (<span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">\Swoole\Process\Pool</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$pool</span>, <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$workerId</span>) {</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">echo</span>(<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">"[Worker #</span>{<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$workerId</span>}<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">] WorkerStop\n"</span>);</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">});</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">// 启动工作进程</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$pool</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">start</span>();</span>

测试

<span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$pstree</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">aup</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span> <span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">grep</span> <span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">php</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">  <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">`</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">php</span>,<span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">641057</span> <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">25</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">swoole</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">process</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">pool</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-</span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">1.</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">php</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">  <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>       <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|-</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">php</span>,<span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">641058</span> <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">25</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">swoole</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">process</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">pool</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-</span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">1.</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">php</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">  <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>       <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|-</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">php</span>,<span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">641059</span> <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">25</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">swoole</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">process</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">pool</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-</span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">1.</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">php</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">  <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>       <span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">`</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">php</span>,<span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">641060</span> <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">25</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">swoole</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">process</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">pool</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-</span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">1.</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">php</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">  <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|</span>   <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">|-</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">grep</span>,<span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">641063</span> <span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">php</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$kill</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">SIGTERM</span> <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">641060</span></span>

本篇文章到这里就可以结束了。下面的内容都是对官方文档内容的抄录,纯属于人个学习。若要了解相关属性和方法,还是请前往官方文档学习。

好记性不如烂笔头,学习还是得脚踏实地。

构造函数

<span style="color: rgb(0, 176, 240);">Swoole\Process\Pool::__construct(int $worker_num, int $ipc_type = SWOOLE_IPC_NONE, int $msgqueue_key = 0, bool $enable_coroutine = false);</span><br></br>

参数:

  • worker_num:指定工作进程的数量;

  • ipc_type:进程间通信模式【默认为 0 ,表示不使用任务进程通信】;

  • SWOOLE_IPC_MSGQUEUE 表示使用系统消息队列通信,可设置 $msgqueue_key 指定消息队列的 KEY,未设置消息队列的 KEY 将申请私有队列;

  • SWOOLE_IPC_SOCKET 表示使用 Socket 进行通信,需要使用 listen 方法指定监听的地址和端口;

  • SWOOLE_IPC_UNIXSOCK 表示使用 unixSocket 进行通信,协程模式下使用,官方强烈推荐使用此方式进行进程间通信;

  • 设置为 0 时必须设置 onWorkerStart 回调,且必须在该回调中实现循环逻辑,当该函数退出工作时工作进程会立即退出,之后由 Manager 进程重新拉起进程;

    使用非 0 设置时,必须设置 onMessage 回调,onWorkerStart 则为可选项。

  • msgqueue:消息队列的 key;

  • enable_coroutine:是否开启协程支持。

set

含义:设置参数。

<span style="color: rgb(0, 176, 240);">Swoole\Process\Pool->set(array $settings)</span><br></br>

on

含义:设置进程池回调函数。

<span style="color: rgb(0, 176, 240);">Swoole\Process\Pool->on(string $event, callable $function);</span><br></br>

参数:

  • event:指定事件;

  • onWorkeStart (Swoole\Process\Pool $pool, int $workerId) - 子进程启动;

  • onWorkerStop(Swoole\Process\Pool $pool, int $workerId) - 子进程结束;

  • onMessage(Swoole\Process\Pool $pool, string $data) - 接收消息。

  • function:回调函数。

listen

含义:监听 socket,必须在 ipc_type 为 SWOOLE_IPC_SOCKET 时可用。

<span style="color: rgb(0, 176, 240);">Swoole\Process\Pool->listen(string $host, int $port = 0, int $backlog = 2048): bool</span><br></br>

参数:

  • host:监听的地址;
  • port:监听的端口;
  • backlog:监听的队列长度。

通信协议:向监听端口发送数据时,客户端必须在请求前增加 4 字节、网络字节序的长度值。协议格式为 packet = htonl(strlen(data)) + data;

write

含义:向对端写入数据,必须在 $ipc_modeSWOOLE_IPC_SOCKET 时才能使用。

<span style="color: rgb(0, 176, 240);">Swoole\Process\Pool->write(string $data): bool</span><br></br>

start

含义:启动工作进程。

<span style="color: rgb(0, 176, 240);">Swoole\Process\Pool->start(): bool</span><br></br>

shutdown

含义:终止工作进程。

<span style="color: rgb(0, 176, 240);">Swoole\Process\Pool->shutdown(): bool</span><br></br>

getProcess

含义:获取当前工作进程对象,返回 Swoole\Process 对象。

<span style="color: rgb(0, 176, 240);">Swoole\Process\Pool->getProcess(int $worker_id): Swoole\Process</span><br></br>

detach

含义:将进程池当前 Worker 进程脱离管理,底层会立即创建新的进程,老的进程不再处理数据,由应用层代码自行管理生命周期。

<span style="color: rgb(0, 176, 240);">Swoole\Process\Pool->detach(): bool</span><br></br>

本篇次学习耽搁的时间有 3 周,再次续写时发现有很多已经忘记,于是把官方文档中的属性方法照抄一遍,当一个记录学习。

通过前后的学习,应该有所明白,Process 是创建单进程,Process Pool 是创建多进程。什么时候使用多进程?比有大批量的数据要处理时,多个进程比单进程就快多了。

本篇文章到此结束,下篇文章继续学习 Swoole。

请登录后再评论