当前位置: 首页 > 后端技术 > PHP

Swoole-2.1.2进程池模块的使用

时间:2023-03-29 14:23:38 PHP

在Swoole-2.1.2版本中,我们将Server的进程管理模块封装成一个PHP类,现在可以在PHP代码中使用Swoole的进程管理器了。在实际项目中,经常需要编写一些长时间运行的脚本,比如基于redis、kafka、rabbitmq的多进程队列消费者,多进程爬虫等等。程序员需要使用pcntl和posix相关的扩展库来实现多进程编程,开发者需要有扎实的Linux系统编程功底,否则很容易出问题。Swoole提供的进程管理器来自Swoole\Server,经过大量生产项目验证,稳定性和健壮性非常高。可以大大简化多进程脚本的编程工作。1、创建进程池在PHP代码中使用newSwoole\Process\Pool创建进程池,构造方法第一个参数传入工作进程数。使用on方法设置WorkerStart在worker进程启动时执行指定的代码。你可以在这里执行一个while(true)循环来从redis队列中获取任务并处理它们。使用start方法启动所有进程,manager启动进入等待状态。$workerNum=10;$pool=newSwoole\Process\Pool($workerNum);$pool->on("WorkerStart",function($pool,$workerId){echo"Worker#{$workerId}已启动\n";$redis=newRedis();$redis->pconnect('127.0.0.1',6379);$key="key1";while(true){$msgs=$redis->brpop($key,2);如果($msgs==null)继续;var_dump($msgs);}});$pool->on("WorkerStop",function($pool,$workerId){echo"Worker#{$workerId}已停止\n";});$pool->start();使用进程管理器可以保证工作进程的稳定性。当一个工作进程遇到致命错误并主动退出时,管理器会对其进行回收,避免出现僵尸进程。工作进程退出后,manager会自动拉起创建新的工作进程。2.信号处理Swoole进程管理器自带信号处理后,发送给管理器进程:SIGTERM信号:停止服务,向所有工作进程发送SIGTERM关闭进程SIGUSR1信号:重启工作进程,管理器会重启工作过程一一工作过程中,可以使用pcntl_signal和pcntl_signal_dispatch来实现信号处理。$pool->on("WorkerStart",function($pool,$workerId){$running=true;pcntl_signal(SIGTERM,function()use(&$running){$running=false;});echo"Worker#{$workerId}已启动\n";$redis=newRedis();$redis->pconnect('127.0.0.1',6379);$key="key1";while($running){$msgs=$redis->brpop($key,2);pcntl_signal_dispatch();if($msgs==null)继续;var_dump($msgs);}});3、任务传递Swoole进程管理器自带消息队列和TCP-Socket消息传递的支持。您可以设置监控系统队列或TCP端口来接收任务数据。此功能是可选的。要使用任务下发功能,需要为进程池对象设置onMessage回调。消息队列$pool=newSwoole\Process\Pool(2,SWOOLE_IPC_MSGQUEUE,0x7000001);$pool->on("WorkerStart",function($pool,$workerId){echo"Worker#{$workerId}isstarted\n";});$pool->on("Message",function($pool),$message){echo"Message:{$message}\n";});$pool->start();需要构造方法的第二个参数传递给SWOOLE_IPC_MSGQUEUE,第三个参数设置要监听的消息队列的KEY。其他程序可以使用消息队列相关的API向worker进程下发任务。TCP端口$pool=newSwoole\Process\Pool(2,SWOOLE_IPC_SOCKET);$pool->on("WorkerStart",function($pool,$workerId){echo"Worker#{$workerId}已启动\n";});$pool->on("消息",function($pool,$message){echo"消息:{$message}\n";});$pool->listen('127.0.0.1',8089);$pool->start();使用TCP端口监听,需要将构造方法的第二个参数设置为SWOOLE_IPC_SOCKET,使用listen方法设置监听的主机和端口。底层使用4字节长度+包体的协议。当其他程序向该端口发送数据时,需要在数据包前增加一个长度字段。$fp=stream_socket_client("tcp://127.0.0.1:8089",$errno,$errstr)ordie("error:$errstr\n");$msg=json_encode(['data'=>'hello','uid'=>1991]);fwrite($fp,pack('N',strlen($msg)).$msg);fclose($fp);